### 代码

#include <bits/stdc++.h>
#define maxn 100010
#define maxm 40000000//注意主席树一定要开大
#define mid ((l+r)>>1)
using namespace std;
struct Edge{
int to,next;
Edge(int a=0,int b=0){
to=a,next=b;
}
}l[maxn*2];
int n,m,q,id,siz[maxn],L[maxm],R[maxm],tree[maxm],rt[maxn];
int find(int x){
return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
}
}
void Merge(int a,int b){
int fx=find(a),fy=find(b);
fa[fx]=fy;siz[fy]+=siz[fx];
}
void insert(int x,int &y,int l,int r,int val){
if (!y) y=++id;
tree[y]=tree[x]+1;
if (l==r) return;
if (val<=mid) R[y]=R[x],insert(L[x],L[y],l,mid,val);
else L[y]=L[x],insert(R[x],R[y],mid+1,r,val);
}
int query(int x,int y,int w,int e,int l,int r,int k){
if (l==r) return l;
int tem=tree[L[x]]+tree[L[y]]-tree[L[w]]-tree[L[e]];
if (tem>=k) return query(L[x],L[y],L[w],L[e],l,mid,k);
else return query(R[x],R[y],R[w],R[e],mid+1,r,k-tem);
}
void Build(int u){
d[u]=d[p[u][0]]+1;
for (int i=1;(1<<i)<=d[u];i++)
p[u][i]=p[p[u][i-1]][i-1];
rt[u]=0;
insert(rt[p[u][0]],rt[u],0,INF,a[u]);
int v=l[i].to;if (v==p[u][0]) continue;
p[v][0]=u;Build(v);
}
}
int lca(int a,int b){
if (d[a]<d[b]) swap(a,b);
for (int i=24;i>=0;i--)
if (d[p[a][i]]>=d[b]) a=p[a][i];
if (a==b) return a;
for (int i=24;i>=0;i--)
if (p[a][i]!=p[b][i]) a=p[a][i],b=p[b][i];
return p[a][0];
}
int main(){
ios::sync_with_stdio(false);
int t;cin>>t;
cin>>n>>m>>q;
for (int i=1;i<=n;i++)
fa[i]=i,cin>>a[i],INF=max(INF,a[i]),siz[i]=1;
for (int i=1,t1,t2;i<=m;i++){
}
for (int i=1;i<=n;i++)
if (!p[i][0]) Build(i);
int ans=0,x,y,k;char op;
for (int i=1;i<=q;i++){
cin>>op;if (op=='Q'){
cin>>x>>y>>k;
x^=ans,y^=ans,k^=ans;int lc=lca(x,y);
ans=query(rt[x],rt[y],rt[lc],rt[p[lc][0]],0,INF,k);
cout<<ans<<endl;
}else{
cin>>x>>y;x^=ans,y^=ans;
int fx=find(x),fy=find(y);
if (siz[fx]>siz[fy]) swap(x,y);