const int maxn = 60010;
const int maxm = maxn*40;
int n,q,m,tot;
int a[maxn],b[maxn];
int T[maxn],lson[maxm],rson[maxm],c[maxm];
int S[maxn],use[maxn];
int Build( int l , int r )
{
int root = tot++;
c[root] = 0;
if ( l!=r )
{
int mid = ( l+r )>>1;
lson[root] = Build( l , mid );
rson[root] = Build( mid+1 , r );
}
return root;
}
int Update( int root , int pos , int val )
{
int newroot = tot++,tmp = newroot;
int l = 0,r = m-1;
c[newroot] = c[root]+val;
while ( l<r )
{
int mid = (l+r)>>1;
if ( pos<=mid )
{
lson[newroot] = tot++; rson[newroot] = rson[root];
newroot = lson[newroot]; root = lson[root]; r = mid;
}
else
{
rson[newroot] = tot++; lson[newroot] = lson[root];
newroot = rson[newroot]; root = rson[root]; l = mid+1;
}
c[newroot] = c[root]+val;
}
return tmp;
}
int lowbit( int x )
{
return x&(-x);
}
void add( int x , int pos , int val )
{
for ( ; x<=n ; x+=lowbit(x) )
S[x] = Update( S[x] , pos , val );
}
int sum( int x )
{
int res = 0;
for ( ; x>=1 ; x-=lowbit(x) )
res += c[lson[use[x]]];
return res;
}
int Query( int left , int right , int k )
{
int left_root = T[left-1];
int right_root = T[right];
int l = 0,r = m-1;
for ( int i=left-1 ; i>=1 ; i-=lowbit(i) ) use[i] = S[i];
for ( int i=right ; i>=1 ; i-=lowbit(i) ) use[i] = S[i];
while ( l<r )
{
int mid = (l+r)>>1;
int tmp = sum(right)-sum(left-1)+c[lson[right_root]]-c[lson[left_root]];
if ( k<=tmp )
{
r = mid;
for ( int i=left-1 ; i>=1 ; i-=lowbit(i) ) use[i] = lson[use[i]];
for ( int i=right ; i>=1 ; i-=lowbit(i) ) use[i] = lson[use[i]];
left_root = lson[left_root];
right_root = lson[right_root];
}
else
{
l = mid+1;
k -= tmp;
for ( int i=left-1 ; i>=1 ; i-=lowbit(i) ) use[i] = rson[use[i]];
for ( int i=right ; i>=1 ; i-=lowbit(i) ) use[i] = rson[use[i]];
left_root = rson[left_root];
right_root = rson[right_root];
}
}
return l;
}
void Modify( int x , int p , int d )
{
for ( ; x<=n ; x+=lowbit(x) )
S[x] = Update( S[x] , p , d );
}
struct node
{
char op[5];
int l,r,k;
}data[10010];
int main()
{
for ( int t ; scanf ( "%d" , &t )==1 ; )
{
for ( int cas=1 ; cas<=t ; cas++ )
{
scanf ( "%d%d" , &n , &q );
tot = 0,m = 0;
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &a[i] ),b[m++] = a[i];
for ( int i=1 ; i<=q ; i++ )
{
scanf ( "%s" , data[i].op );
if ( data[i].op[0]=='Q' )
scanf ( "%d%d%d" , &data[i].l , &data[i].r , &data[i].k );
else
scanf ( "%d%d" , &data[i].l , &data[i].r ),b[m++] = data[i].r;
}
sort ( b , b+m );
m = unique( b , b+m )-b;
T[0] = Build( 0 , m-1 );
for ( int i=1 ; i<=n ; i++ )
{
int pos = lower_bound( b , b+m , a[i] )-b;
T[i] = Update( T[i-1] , pos , 1 );
}
for ( int i=1 ; i<=n ; i++ )
S[i] = T[0];
for ( int i=1 ; i<=q ; i++ )
{
if ( data[i].op[0]=='Q' )
printf( "%d\n" , b[Query( data[i].l , data[i].r , data[i].k )] );
else
{
int pos = lower_bound( b , b+m , a[data[i].l] )-b;
Modify( data[i].l , pos , -1 );
pos = lower_bound( b , b+m , data[i].r )-b;
Modify( data[i].l , pos , 1 );
a[data[i].l] = data[i].r;
}
}
}
}
return 0;
}