using namespace std;
const int MAX=1e5;
int fa[MAX];
int rk[MAX];
//连通块个数
int cc;
//初始化
void build(int n){
for(int i=0;i<n;i++){
fa[i]=i;
rk[i]=0;
}
cc=n;
}
//查询根节点
int find(int x){
if(x!=fa[x]){
//路径压缩
fa[x]=find(fa[x]);
}
return fa[x];
}
//判断是否为同一个集合
bool same(int x,int y){
return find(x)==find(y);
}
//合并集合
void unite(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
//按秩合并 小挂大
if(rk[x]<rk[y]){
fa[x]=y;
}else{
fa[y]=x;
if(rk[x]==rk[y]) rk[x]++;
}
//合并成功减1
cc--;
}