#include <bits/stdc++.h>
using namespace std;
inline int gi() {
  char c = getchar();
  int x = 0;
  for (; c < '0' || c > '9'; c = getchar())
    ;
  for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
  return x;
}
const int N = 1e6 + 5;
int st[N << 2], tg[N << 2], n, m, mn[N];
int ed[N], res;
bool gans;
char op[N][2];
vector<pair<int, int>> qa[N];
vector<int> qq[N], qz[N];
long long ans[N], t[N];
void upd(int i, int w) {
  for (; i <= n + m; i += (i & -i)) t[i] += w;
}
long long qry(int i) {
  long long r = 0;
  for (; i; i -= (i & -i)) r += t[i];
  return r;
}
void update(int x, int l, int r, int s, int w) {
  if (l == r) {
    st[x] += w;
    return;
  }
  int mid = l + r >> 1;
  s <= mid ? update((x << 1), l, mid, s, w)
           : update((x << 1 | 1), mid + 1, r, s, w);
  st[x] = st[(x << 1)] + st[(x << 1 | 1)];
}
void search(int x, int l, int r) {
  if (l == r) {
    res = l;
    return;
  }
  int mid = l + r >> 1;
  st[(x << 1 | 1)] ? search((x << 1 | 1), mid + 1, r)
                   : search((x << 1), l, mid);
}
void query(int x, int l, int r, int sr) {
  if (gans) return;
  if (r <= sr) {
    if (st[x]) gans = true, search(x, l, r);
    return;
  }
  int mid = l + r >> 1;
  if (sr > mid) query((x << 1 | 1), mid + 1, r, sr);
  query((x << 1), l, mid, sr);
}
struct Tree {
  vector<int> e[N];
  int f[N], sze[N], id;
  void init() {
    id = n;
    for (int i = 1; i <= n + m; ++i) f[i] = i, sze[i] = 1;
  }
  int fset(int x) {
    if (f[x] == x) return x;
    return f[x] = fset(f[x]);
  }
  void addp(int x, int y) {
    ++id;
    x = fset(x), y = fset(y);
    e[id].push_back(x), e[id].push_back(y);
    f[x] = f[y] = id, sze[id] = sze[x] + sze[y];
  }
} t1, t2;
void dfs2(int u) {
  for (auto x : qz[u]) update(1, 1, m, x, 1);
  for (auto x : qq[u]) gans = false, res = 0, query(1, 1, m, x), ed[x] = res;
  for (auto v : t2.e[u]) dfs2(v);
  for (auto x : qz[u]) update(1, 1, m, x, -1);
}
void dfs1(int u) {
  for (auto x : qa[u]) upd(x.second, x.first);
  for (auto x : qq[u]) ans[x] += qry(x) - qry(ed[x]);
  for (auto v : t1.e[u]) dfs1(v);
  for (auto x : qa[u]) upd(x.second, -x.first);
}
int main() {
  n = gi(), m = gi();
  t1.init(), t2.init();
  for (int i = 1; i <= m; ++i) {
    scanf("%s", op[i]);
    char c = op[i][0];
    if (c == 'U') t1.addp(gi(), gi());
    if (c == 'M') t2.addp(gi(), gi());
    if (c == 'A') {
      int x = gi(), fx = t1.fset(x);
      qa[fx].push_back(make_pair(t1.sze[fx], i));
    }
    if (c == 'Z') {
      int x = gi(), fx = t2.fset(x);
      qz[fx].push_back(i);
    }
    if (c == 'Q') {
      int x = gi();
      qq[x].push_back(i);
    }
  }
  for (int i = 1; i <= t2.id; ++i)
    if (t2.f[i] == i) dfs2(i);
  for (int i = 1; i <= t1.id; ++i)
    if (t1.f[i] == i) dfs1(i);
  for (int i = 1; i <= m; ++i)
    if (op[i][0] == 'Q') printf("%lld\n", ans[i]);
}
