#include <bits/stdc++.h>
using i64 = long long;
const int N = 1000007;
int fa[N], vis[N], size[N];
i64 tag[N], ans[N];
struct node {
  int o, t, x, y, id;
};
std::vector<node> vec;
int read() {
  int x = 0, c = getchar();
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) (x *= 10) += c & 15, c = getchar();
  return x;
}
char get() {
  char c = getchar();
  while (!isupper(c)) c = getchar();
  return c;
}
int find(int x, int f) {
  if (fa[fa[x]] == fa[x]) return fa[x];
  int y = find(fa[x], f);
  return tag[x] = f ? std::max(tag[x], tag[fa[x]]) : tag[x] + tag[fa[x]],
         fa[x] = y;
}
int main() {
  int n = read(), m = read(), cnt = n;
  std::iota(fa + 1, fa + n + n + 1, 1);
  for (int i = 1, x, y; i <= m; ++i) switch (get()) {
      case 'U':
        x = read(), y = read(), vec.push_back({0, i, x, y, 0});
        break;
      case 'M':
        x = read(), y = read(), ++cnt, fa[find(x, 1)] = fa[find(y, 1)] = cnt;
        break;
      case 'A':
        vec.push_back({-1, i, read(), 0, 0});
        break;
      case 'Z':
        tag[find(read(), 1)] = i;
        break;
      case 'Q':
        x = read(), vis[i] = 1, vec.push_back({1, i, x, 1, i}), y = find(x, 1);
        if (tag[x] || tag[y])
          vec.push_back({1, (int)std::max(tag[x], tag[y]), x, -1, i});
        ;
        break;
    }
  std::sort(vec.begin(), vec.end(),
            [](const node& a, const node& b) { return a.t < b.t; }),
      std::iota(fa + 1, fa + n + n + 1, 1),
      std::fill(size + 1, size + n + n + 1, 1), memset(tag + 1, 0, n << 4),
      cnt = n;
  for (auto t : vec) switch (t.o) {
      case -1:
        tag[find(t.x, 0)] += size[find(t.x, 0)];
        break;
      case 0:
        t.x = find(t.x, 0), t.y = find(t.y, 0), ++cnt,
        size[cnt] = size[t.x] + size[t.y], fa[t.x] = fa[t.y] = cnt;
        break;
      case 1:
        find(t.x, 0),
            ans[t.id] += t.y * (tag[t.x] + (fa[t.x] == t.x ? 0 : tag[fa[t.x]]));
    }
  for (int i = 1; i <= m; ++i)
    if (vis[i]) printf("%lld\n", ans[i]);
}
