#include<bits/stdc++.h>
#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define swap(a,b) (a^=b^=a^=b)
using namespace std;
const int N=1e4+5;
int n,Q;
struct LCT
{
int ch[2],fa;
bool rev;
}t[N];
bool isRoot(int x){
int g=t[x].fa;
return (t[g].ch[0]^x)&&(t[g].ch[1]^x);
}
/*void update(int x){
}*/
void reverse(int x){
if(!x) return;
swap(lc,rc);
t[x].rev^=1;
}
void push_down(int x){
if(!t[x].rev) return;
reverse(lc),reverse(rc);
t[x].rev=0;
}
void push(int x){
if(!isRoot(x)) push(t[x].fa);
push_down(x);
}
void rotate(int x){
int y=t[x].fa;
int z=t[y].fa;
int k=t[y].ch[1]==x;
if(!isRoot(y)) t[z].ch[t[z].ch[1]==y]=x;
t[x].fa=z;
t[y].ch[k]=t[x].ch[k^1];
if(t[x].ch[k^1]) t[t[x].ch[k^1]].fa=y;
t[y].fa=x;
t[x].ch[k^1]=y;
//update(y);
}
void splay(int x){
push(x);
while(!isRoot(x)){
int y=t[x].fa,z=t[y].fa;
if(!isRoot(y))
(t[x].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
rotate(x);
}
//update(x);
}
void access(int x){
for(int cld=0;x;cld=x,x=t[x].fa){
splay(x);
rc=cld;
//update(x);
}
}
void makeroot(int x){
access(x),splay(x),reverse(x);
}
void split(int x,int y){
makeroot(x),access(y),splay(y);
}
void link(int x,int y){
makeroot(x),t[x].fa=y;
}
void cut(int x,int y){
split(x,y);
if((t[y].ch[0]^x)||rc) return;
t[x].fa=t[y].ch[0]=0;
//update(x);
}
int findroot(int x){
access(x),splay(x);
while(lc) push_down(x),x=lc;
return x;
}
int main(){
scanf("%d%d",&n,&Q);
while(Q--){
char opt[10],x,y;
scanf("%s%d%d",opt,&x,&y);
if(opt[0]=='Q')
printf("%s\n",findroot(x)^findroot(y)?"No":"Yes");
else if(opt[0]=='C')
link(x,y);
else
cut(x,y);
}
return 0;
}
萌新不懂,为啥 LCT 死循环了