#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));
    }
  }
}
