struct UFS {
stack<pair<int*, int> > stk;
int fa[maxn], rnk[maxn];
inline void init(int n) {
for (int i = 0; i <= n; ++i) fa[i] = i, rnk[i] = 0;
}
inline int find(int x) {
while(x^fa[x]) x = fa[x];
return x;
}
inline void unite(int x, int y) {
x = find(x), y = find(y);
if(x == y) return ;
if(rnk[x] <= rnk[y]) {//先连边,再修改rank,撤销的时候就会最后撤销边
stk.push({fa+x, fa[x]});
fa[x] = y;
if(rnk[x] == rnk[y]) {
stk.push({rnk+y, rnk[y]});
rnk[y]++;
}
}
else {
stk.push({fa+y, fa[y]});
fa[y] = x;
}
}
inline void undo() {
*stk.top().first = stk.top().second;
stk.pop();
}
}ufs;