#include <bits/stdc++.h>   using namespace std;   const int N = 5e5 + 10;   int n, m;   struct bian {     int from, to;   };   struct tree {     bian eg[N << 2];     int num, front[N << 1];     int zong;     int fa[N << 1], siz[N << 1];     void add(int x, int y) {       eg[++num].to = y;       eg[num].from = front[x];       front[x] = num;     }     void init() {       zong = n;       for (int i = 1; i <= zong; ++i) fa[i] = i, siz[i] = 1;     }     int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }     int tot, now;     int son[N << 4][2];     long long tag[N << 4];     int root[N];     void merge(int x, int y) {       int d1 = find(x), d2 = find(y);       fa[++zong] = zong;       add(zong, d1);       add(zong, d2);       siz[zong] = siz[find(x)] + siz[find(y)];       fa[d1] = zong;       fa[d2] = zong;     }     int ll[N << 1], rr[N << 1], ids[N], p;     void dfs(int o) {       if (o <= n) {         ids[o] = ++p;         ll[o] = rr[o] = ids[o];         return;       }       ll[o] = 1e9;       for (int i = front[o]; i; i = eg[i].from) {         int to = eg[i].to;         dfs(to);         ll[o] = min(ll[o], ll[to]);         rr[o] = max(rr[o], rr[to]);       }     }     void opt1(int be, int &o, int l, int r, int L, int R, int w) {       if (o == 0) o = ++tot;       tag[o] = tag[be];       if (L <= l && r <= R) {         tag[o] += w;         son[o][0] = son[be][0];         son[o][1] = son[be][1];         return;       }       int mid = (l + r) >> 1;       if (mid >= L)         opt1(son[be][0], son[o][0], l, mid, L, R, w);       else         son[o][0] = son[be][0];       if (mid < R)         opt1(son[be][1], son[o][1], mid + 1, r, L, R, w);       else         son[o][1] = son[be][1];     }     long long opt2(int o, int l, int r, int i, long long now) {       if (o == 0) return now;       if (l == r) return now + tag[o];       int mid = (l + r) >> 1;       if (mid >= i)         return opt2(son[o][0], l, mid, i, now + tag[o]);       else         return opt2(son[o][1], mid + 1, r, i, now + tag[o]);     }   } T1;   struct tree_ {     bian eg[N << 2];     int num, front[N << 1];     int zong;     int fa[N << 1];     void add(int x, int y) {       eg[++num].to = y;       eg[num].from = front[x];       front[x] = num;     }     void init() {       zong = n;       for (int i = 1; i <= zong; ++i) fa[i] = i;     }     int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }     void merge(int x, int y) {       int d1 = find(x), d2 = find(y);       fa[++zong] = zong;       add(zong, d1);       add(zong, d2);       fa[d1] = zong;       fa[d2] = zong;     }     int ll[N << 1], rr[N << 1], ids[N], p;     void dfs(int o) {       if (o <= n) {         ids[o] = ++p;         ll[o] = rr[o] = ids[o];         return;       }       ll[o] = 1e9;       for (int i = front[o]; i; i = eg[i].from) {         int to = eg[i].to;         dfs(to);         ll[o] = min(ll[o], ll[to]);         rr[o] = max(rr[o], rr[to]);       }     }     int col[N << 2];     void opt3(int o, int l, int r, int L, int R, int w) {       if (L <= l && r <= R) {         col[o] = w;         return;       }       int mid = (l + r) >> 1;       if (col[o]) {         col[o << 1] = col[o << 1 | 1] = col[o];         col[o] = 0;       }       if (mid >= L) opt3(o << 1, l, mid, L, R, w);       if (mid < R) opt3(o << 1 | 1, mid + 1, r, L, R, w);     }     int opt4(int o, int l, int r, int i) {       if (l == r) return col[o];       int mid = (l + r) >> 1;       if (col[o]) {         col[o << 1] = col[o << 1 | 1] = col[o];         col[o] = 0;       }       if (mid >= i)         return opt4(o << 1, l, mid, i);       else         return opt4(o << 1 | 1, mid + 1, r, i);     }   } T2;   int que[N][3];   struct b {     int fa[N << 1], zong;     void init() {       zong = n;       for (int i = 1; i <= n; ++i) fa[i] = i;     }     int find(int o) { return fa[o] == o ? o : fa[o] = find(fa[o]); }     void merge(int x, int y) {       int d1 = find(x), d2 = find(y);       fa[++zong] = zong;       fa[d1] = zong;       fa[d2] = zong;     }   } B1, B2;   int main() {     scanf( %d%d , &n, &m);     T1.init();     T2.init();     for (int i = 1; i <= m; ++i) {       char s[10];       scanf( %s , s);       if (s[0] ==  U ) {         int x, y;         scanf( %d%d , &x, &y);         que[i][0] = 1;         que[i][1] = x;         que[i][2] = y;         T1.merge(x, y);       }       if (s[0] ==  M ) {         int x, y;         scanf( %d%d , &x, &y);         que[i][0] = 2;         que[i][1] = x;         que[i][2] = y;         T2.merge(x, y);       }       if (s[0] ==  A ) {         int x;         scanf( %d , &x);         que[i][0] = 3;         que[i][1] = x;       }       if (s[0] ==  Z ) {         int x;         scanf( %d , &x);         que[i][0] = 4;         que[i][1] = x;       }       if (s[0] ==  Q ) {         int x;         scanf( %d , &x);         que[i][0] = 5;         que[i][1] = x;       }     }     for (int i = 1; i <= T1.zong; ++i)       if (T1.find(i) == i) T1.dfs(i);     for (int i = 1; i <= T2.zong; ++i)       if (T2.find(i) == i) T2.dfs(i);     B1.init();     B2.init();     for (int i = 1; i <= m; ++i) {       if (que[i][0] == 1) {         B1.merge(que[i][1], que[i][2]);       }       if (que[i][0] == 2) {         B2.merge(que[i][1], que[i][2]);       }       if (que[i][0] == 3) {         ++T1.now;         T1.opt1(T1.root[T1.now - 1], T1.root[T1.now], 1, n,                 T1.ll[B1.find(que[i][1])], T1.rr[B1.find(que[i][1])],                 T1.siz[B1.find(que[i][1])]);       }       if (que[i][0] == 4) {         T2.opt3(1, 1, n, T2.ll[B2.find(que[i][1])], T2.rr[B2.find(que[i][1])],                 T1.now);       }       if (que[i][0] == 5) {         printf( %lld n , T1.opt2(T1.root[T1.now], 1, n, T1.ids[que[i][1]], 0) -                              T1.opt2(T1.root[T2.opt4(1, 1, n, T2.ids[que[i][1]])],                                      1, n, T1.ids[que[i][1]], 0));       }     }   }   