- d[x]维护x到根节点的距离,初始值为0,size[x]维护以x为根节点的树的节点数,初始值为1。
- 合并x,y时,找到x,y的根节点fx,fy,d[fx]+=size[fy],size[fy]+=size[fx]。
- 查找时,d[x]+=d[f[x]],d[f[x]]在取到前会先更新到与根节点同步的信息。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define INIT(a,b) memset(a,b,sizeof(a))
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define repd(i,a,b) for(int i=a;i>=b;--i)
#define S(d) scanf("%d",&d)
#define SLL(d) scanf("%lld",&d)
#define P(d) printf("%d\n",d)
#define PLL(d) printf("%lld\n",d)
using namespace std;
const int inf=0x3f3f3f3f;
const int N=3e4+7;
const int M=2e6+7;
const int mod=1e9+7;
int f[N],d[N],num[N];
int find(int n){
if(n==f[n]) return n;
int root=find(f[n]);//先更新前面节点的信息
d[n]+=d[f[n]];
return f[n]=root;
}
void merge(int a,int b){
a=find(a),b=find(b);
f[a]=b,d[a]=num[b];
num[b]+=num[a];
}
int main(){
rep(i,1,N-5) f[i]=i,num[i]=1;
int t,x,y;char op;
scanf("%d",&t);
while(t--){
getchar();
scanf("%c%d%d",&op,&x,&y);
if(op=='M') merge(x,y);
if(op=='C') {
if(find(x)==find(y))
printf("%d\n",abs(d[x]-d[y])-1);
else
puts("-1");
}
}
return 0;
}