using namespace std;
int use[maxn*10],n,m,size,tot=0,all=0,h[maxn*10],v[maxn*10],t[maxn*10];
struct chairtree
{
int l,r,size;
}a[maxn*300];
struct question
{
int l,r,k;
}q[maxn];
//树状数组
int lowbit(int x)
{
return x&(-x);
}
//对数组h排序,并求出有多少个不同的值
void Hash1()
{
sort(h+1,h+1+all);
size=unique(h+1,h+1+all)-h-1;
}
//求出x在去重后的数据中的序号
int Hash(int x)
{
return lower_bound(h+1,h+1+size,x)-h;
}
//建线段树
int Build(int l,int r)
{
int now=++tot;
a[now].size=0;
if (l==r) return now;
int m=(l+r)>>1;
a[now].l=Build(l,m);
a[now].r=Build(m+1,r);
return now;
}
//更新。每更新一个节点相当于建立新的线段树
//非递归更新
//val为1或-1.表示删除数据或新增数据
//修改数据:要先删除然后再增加
int Update(int root,int p,int val)
{
int now=++tot,tmp=now;
int l=1,r=size;
a[now].size=a[root].size+val;
while (l<r)
{
int m=(l+r)>>1;
if (p<=m)
{
a[now].l=++tot; a[now].r=a[root].r;
root=a[root].l; now=a[now].l;
r=m;
}
else
{
a[now].l=a[root].l; a[now].r=++tot;
root=a[root].r; now=a[now].r;
l=m+1;
}
a[now].size=a[root].size+val;
}
return tmp;
}
//把第x个数改成p(p已经离散化为去重后的序号)
//val为1或-1
void Add(int x,int p,int val)
{
for (int i=x;i<=n;i+=lowbit(i)) //树状数组只需修改logn个
t[i]=Update(t[i],p,val);
}
int Getsum(int x)
{
int ans=0;
for (int i=x;i;i-=lowbit(i))
ans+=a[a[use[i]].l].size;
return ans;
}
int Query(int lx,int rx,int k)
{
int l=1,r=size;
for (int i=lx-1;i;i-=lowbit(i)) use[i]=t[i];
for (int i=rx;i;i-=lowbit(i)) use[i]=t[i];
while (l<r)
{
int m=(l+r)>>1;
int tmp=Getsum(rx)-Getsum(lx-1);
if (tmp>=k)
{
for (int i=lx-1;i;i-=lowbit(i))
use[i]=a[use[i]].l;
for (int i=rx;i;i-=lowbit(i))
use[i]=a[use[i]].l;
r=m;
}
else
{
for (int i=lx-1;i;i-=lowbit(i))
use[i]=a[use[i]].r;
for (int i=rx;i;i-=lowbit(i))
use[i]=a[use[i]].r;
k-=tmp;
l=m+1;
}
}
return l;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&v[i]),h[i]=v[i];
all=n;
for (int i=1;i<=m;i++)
{
char str[10];
int l,r,k;
scanf("%s",str);
if (str[0]=='Q')
{
scanf("%d%d%d",&l,&r,&k);
q[i].l=l,q[i].r=r,q[i].k=k;
}
else
{
scanf("%d%d",&r,&k); //把第r个数改为k
q[i].l=0,q[i].r=r,q[i].k=k;
h[++all]=k;
}
}
Hash1();
t[0]=Build(1,size);
for (int i=1;i<=n;i++)
t[i]=t[0];
for (int i=1;i<=n;i++)
Add(i,Hash(v[i]),1);
for (int i=1;i<=m;i++)
{
if (q[i].l)
{
printf("%d\n",h[Query(q[i].l,q[i].r,q[i].k)]);
}
else
{
Add(q[i].r,Hash(v[q[i].r]),-1); //先把原数去掉
Add(q[i].r,Hash(q[i].k),1); //增加新数
v[q[i].r]=q[i].k; //v数组保存最新的数据
}
}
return 0;
}