#include <iostream>
#include <stdio.h>
#define MAXN 30001
using namespace std;
int pre[MAXN], son[MAXN], vis[MAXN];
int find(int x){
if(pre[x]==x){
return x;
}
int temp=pre[x]; //***递归思想,temp为存储x改变根节点后的根节点的临时变量
pre[x]=find(pre[x]);
vis[x]+=vis[temp]; //***x到改变前根节点的距离即x到temp的距离加上temp到根节点的距离
return pre[x];
}
void jion(int x, int y){
int px=find(x);
int py=find(y);
if(px!=py){
pre[py]=px;
vis[py]=son[px]; //***将x所在列放到y所在列上面后,find(y)到新合并后的根节点的距离即为合并前find(x)的子树的大小
son[px]+=son[py]; //***合并后find(x)的子树大小即为合并前find(x)与find(y)的子树大小的和
}
}
int main(void){
int p;
scanf("%d", &p);
for(int i=1; i<=MAXN; i++){
pre[i]=i;
son[i]=1;
}
for(int i=1; i<=p; i++){
char s[2];
int x, y;
scanf("%s", s);
if(s[0]=='M'){
scanf("%d%d", &x, &y);
jion(x, y);
}else{
scanf("%d", &x);
printf("%d\n", son[find(x)]-vis[x]-1);//***注意这里并不是输出son(x),因为我们并没有求出每个节点的子树的大小
}
}
return 0;
}
#include <stdio.h>
#define MAXN 30001
using namespace std;
int pre[MAXN], son[MAXN], vis[MAXN];
int find(int x){
if(pre[x]==x){
return x;
}
int temp=pre[x]; //***递归思想,temp为存储x改变根节点后的根节点的临时变量
pre[x]=find(pre[x]);
vis[x]+=vis[temp]; //***x到改变前根节点的距离即x到temp的距离加上temp到根节点的距离
return pre[x];
}
void jion(int x, int y){
int px=find(x);
int py=find(y);
if(px!=py){
pre[py]=px;
vis[py]=son[px]; //***将x所在列放到y所在列上面后,find(y)到新合并后的根节点的距离即为合并前find(x)的子树的大小
son[px]+=son[py]; //***合并后find(x)的子树大小即为合并前find(x)与find(y)的子树大小的和
}
}
int main(void){
int p;
scanf("%d", &p);
for(int i=1; i<=MAXN; i++){
pre[i]=i;
son[i]=1;
}
for(int i=1; i<=p; i++){
char s[2];
int x, y;
scanf("%s", s);
if(s[0]=='M'){
scanf("%d%d", &x, &y);
jion(x, y);
}else{
scanf("%d", &x);
printf("%d\n", son[find(x)]-vis[x]-1);//***注意这里并不是输出son(x),因为我们并没有求出每个节点的子树的大小
}
}
return 0;
}