Code:
#include<bits/stdc++.h>
#define maxn 200000
#define inf 1000000000
using namespace std;
void setIO(string s)
{
string in=s+".in",out=s+".out";
freopen(in.c_str(),"r",stdin);
}
multiset<int>sonmax[maxn];
int n,Q,X=0;
int siz[maxn],son[maxn],p[maxn];
char str[20];
void init() { for(int i=0;i<maxn;++i) p[i]=i; }
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
namespace tr
{
#define isrt(x) (!(ch[f[x]][0]==x||ch[f[x]][1]==x))
#define get(x) (ch[f[x]][1]==x)
#define lson ch[x][0]
#define rson ch[x][1]
int ch[maxn][2],f[maxn],rev[maxn],sta[maxn];
void mark(int x)
{
if(!x)return;
swap(lson,rson), rev[x]^=1;
}
void pushup(int x)
{
if(!x)return;
siz[x]=siz[lson]+siz[rson]+son[x]+1;
}
void rotate(int x)
{
int old=f[x],fold=f[old],which=get(x);
if(!isrt(old)) ch[fold][ch[fold][1]==old]=x;
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
ch[x][which^1]=old,f[old]=x,f[x]=fold;
pushup(old),pushup(x);
}
void pushdown(int x)
{
if(!rev[x]||!x)return;
mark(lson), mark(rson),rev[x]^=1;
}
void splay(int x)
{
int v=0,u=x,fa;
sta[++v]=u;
while(!isrt(u)) sta[++v]=f[u],u=f[u];
while(v) pushdown(sta[v--]);
for(u=f[u];(fa=f[x])!=u;rotate(x))
if(f[fa]!=u)
rotate(get(x)==get(fa)?fa:x);
}
void Access(int x)
{
int t=0;
while(x)
{
splay(x);
son[x]=son[x]+siz[rson]-siz[t];
if(t) sonmax[x].erase(sonmax[x].lower_bound(-siz[t]));
if(rson) sonmax[x].insert(-siz[rson]);
rson=t;
pushup(x);
t=x,x=f[x];
}
}
void MakeRoot(int x)
{
Access(x), splay(x), mark(x);
}
void split(int x,int y)
{
MakeRoot(x),Access(y),splay(y);
}
void link(int x,int y)
{
MakeRoot(x), MakeRoot(y);
f[x]=y, son[y]+=siz[x];
sonmax[y].insert(-siz[x]);
pushup(y);
x=find(x),y=find(y);
split(x,y); // y is on top of x
int size=siz[y]>>1;
int now=y,ls=0,rs=0,newg=n+233;
while(now)
{
pushdown(now);
int lsum=ls+siz[ch[now][0]],rsum=rs+siz[ch[now][1]];
if(lsum<=size&&rsum<=size&&(-*sonmax[now].begin())<=size) newg=min(newg,now);
if(lsum>rsum) rs+=siz[ch[now][1]]+son[now]+1,now=ch[now][0];
else ls+=siz[ch[now][0]]+son[now]+1, now=ch[now][1];
}
splay(newg);
p[x]=p[y]=p[newg]=newg;
X^=x,X^=y,X^=newg;
}
};
int main()
{
// setIO("input");
init();
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;++i) X^=i,sonmax[i].insert(3);
int x,y,a,b,c,d;
while(Q--)
{
scanf("%s",str);
switch(str[0])
{
case 'A' :
{
scanf("%d%d",&x,&y);
tr::link(x,y);
break;
}
case 'Q' :
{
scanf("%d",&x);
printf("%d\n",find(x));
break;
}
case 'X' :
{
printf("%d\n",X);
break;
}
}
}
return 0;
}