#include <bits/stdc++.h>
using namespace std;
const int RLEN = 1 << 20 | 1;
inline char gc() {
  static char ibuf[RLEN], *ib, *ob;
  (ib == ob) && (ob = (ib = ibuf) + fread(ibuf, 1, RLEN, stdin));
  return (ib == ob) ? EOF : *ib++;
}
inline int read() {
  char ch = gc();
  int res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline long long readll() {
  char ch = gc();
  long long res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline int readstring(char *s) {
  int top = 0;
  char ch = gc();
  while (isspace(ch)) ch = gc();
  while (!isspace(ch) && ch != EOF) s[++top] = ch, ch = gc();
  return top;
}
template <typename tp>
inline void chemx(tp &a, tp b) {
  a < b ? a = b : 0;
}
template <typename tp>
inline void chemn(tp &a, tp b) {
  a > b ? a = b : 0;
}
const int N = 1000005;
namespace Seg {
int tag[N << 2];
inline void pushdown(int u) {
  if (!tag[u]) return;
  tag[(u << 1)] = tag[u], tag[((u << 1) | 1)] = tag[u];
  tag[u] = 0;
}
void update(int u, int l, int r, int st, int des, int k) {
  if (st <= l && r <= des) {
    tag[u] = k;
    return;
  }
  pushdown(u);
  if (st <= ((l + r) >> 1)) update((u << 1), l, ((l + r) >> 1), st, des, k);
  if (((l + r) >> 1) < des)
    update(((u << 1) | 1), ((l + r) >> 1) + 1, r, st, des, k);
}
int query(int u, int l, int r, int p) {
  if (l == r) return tag[u];
  pushdown(u);
  if (p <= ((l + r) >> 1))
    return query((u << 1), l, ((l + r) >> 1), p);
  else
    return query(((u << 1) | 1), ((l + r) >> 1) + 1, r, p);
}
}  // namespace Seg
int n, q, m, qn;
namespace Bit {
long long tr[N];
void update(int p, long long k) {
  for (; p <= m; p += (p & (-p))) tr[p] += k;
}
inline long long qry(int p, long long res = 0) {
  for (; p > 0; p -= (p & (-p))) res += tr[p];
  return res;
}
long long query(int l, int r) { return qry(r) - qry(l - 1); }
}  // namespace Bit
long long ans[N];
vector<int> upd[N];
vector<pair<pair<int, int>, int>> qr[N];
struct tree {
  int lc[N], rc[N];
  int in[N], out[N], siz[N], dfn, ff[N], tot;
  int kd;
  inline int find(int x) { return ff[x] == x ? x : ff[x] = find(ff[x]); }
  inline void merge(int u, int v) {
    int f1 = find(u), f2 = find(v);
    if (f1 == f2) return;
    ++tot, ff[f1] = ff[f2] = ff[tot] = tot;
    lc[tot] = f1, rc[tot] = f2;
  }
  inline void init() {
    tot = n;
    for (int i = 1; i <= n; i++) ff[i] = i;
  }
  void dfs(int u) {
    in[u] = ++dfn;
    siz[u] = (u <= n);
    if (lc[u]) dfs(lc[u]), siz[u] += siz[lc[u]];
    if (rc[u]) dfs(rc[u]), siz[u] += siz[rc[u]];
    out[u] = dfn;
  }
  void build() {
    for (int i = 1; i <= tot; i++)
      if (ff[i] == i) dfs(i);
  }
  void update(int u, int i) { Seg::update(1, 1, tot, in[u], out[u], i); }
  int query(int u) { return Seg::query(1, 1, tot, in[u]); }
  void dfs2(int u) {
    for (int &x : upd[u]) Bit::update(x, siz[u]);
    for (pair<pair<int, int>, int> &x : qr[u])
      ans[x.second] = Bit::query(x.first.first, x.first.second);
    if (lc[u]) dfs2(lc[u]);
    if (rc[u]) dfs2(rc[u]);
    for (int &x : upd[u]) Bit::update(x, -siz[u]);
  }
  void solve() {
    for (int i = 1; i <= tot; i++)
      if (ff[i] == i) dfs2(i);
  }
} t1, t2;
struct opt {
  int op, x;
  opt(int a = 0, int b = 0) : op(a), x(b) {}
} p[N];
char str[3];
int main() {
  n = read(), q = read();
  t1.init(), t2.init();
  for (int i = 1, x, y; i <= q; i++) {
    readstring(str);
    switch (str[1]) {
      case 'U':
        x = read(), y = read(), t1.merge(x, y);
        break;
      case 'M':
        x = read(), y = read(), t2.merge(x, y);
        break;
      case 'A':
        x = read(), p[++m] = opt(1, t1.find(x));
        break;
      case 'Z':
        x = read(), p[++m] = opt(2, t2.find(x));
        break;
      case 'Q':
        x = read(), p[++m] = opt(3, x);
        break;
    }
  }
  t1.build(), t2.build();
  for (int i = 1; i <= m; i++) {
    switch (p[i].op) {
      case 1:
        upd[p[i].x].push_back(i);
        ;
        break;
      case 2:
        t2.update(p[i].x, i);
        break;
      case 3:
        qr[p[i].x].push_back(
            make_pair(pair<int, int>(t2.query(p[i].x), i), ++qn));
        break;
    }
  }
  t1.solve();
  for (int i = 1; i <= qn; i++) cout << ans[i] << '\n';
  return 0;
}
