#include <bits/stdc++.h>
using namespace std;
int n, m;
char opt[500010], s[5];
int x[500010], y[500010];
class mergeble {
 public:
  vector<int> v[500010];
  int bel[500010], sett[500010], actualt[500010], updt[500010];
  void init(int N) {
    for (int i = 1; i <= N; i++)
      bel[i] = i, v[i].push_back(i), actualt[i] = updt[i] = sett[i] = 0;
  }
  void merge(int x, int y) {
    x = bel[x];
    y = bel[y];
    if (x == y) return;
    if (v[x].size() < v[y].size()) swap(x, y);
    v[x].insert(v[x].end(), v[y].begin(), v[y].end());
    for (auto &p : v[y]) {
      if (sett[y] != actualt[p]) updt[p] = sett[y];
      actualt[p] = sett[x];
      bel[p] = x;
    }
    v[y].clear();
  }
  inline int query(int p) {
    if (sett[bel[p]] == actualt[p]) return updt[p];
    return sett[bel[p]];
  }
} M;
class mergeble2 {
 public:
  int bel[500010];
  long long sum[500010], tag[500010];
  vector<int> v[500010];
  void init(int N) {
    for (int i = 1; i <= N; i++) bel[i] = i, v[i].push_back(i);
  }
  void merge(int x, int y) {
    x = bel[x];
    y = bel[y];
    if (x == y) return;
    if (v[x].size() < v[y].size()) swap(x, y);
    v[x].insert(v[x].end(), v[y].begin(), v[y].end());
    for (auto &p : v[y]) {
      sum[p] = sum[p] + tag[y] - tag[x];
      bel[p] = x;
    }
    v[y].clear();
  }
  inline long long query(int p) { return sum[p] + tag[bel[p]]; }
} M2;
int early[500010];
long long pre[500010];
vector<int> tq[500010];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%s", s);
    opt[i] = s[0];
    switch (opt[i]) {
      case 'U':
        scanf("%d%d", &x[i], &y[i]);
        break;
      case 'M':
        scanf("%d%d", &x[i], &y[i]);
        break;
      default:
        scanf("%d", &x[i]);
    }
  }
  M.init(n);
  for (int i = 1; i <= m; i++) {
    if (opt[i] == 'M')
      M.merge(x[i], y[i]);
    else if (opt[i] == 'Z')
      M.sett[M.bel[x[i]]] = i;
    else if (opt[i] == 'Q')
      early[i] = M.query(x[i]), tq[early[i]].push_back(i);
  }
  M2.init(n);
  for (int i = 1; i <= m; i++) {
    if (opt[i] == 'U')
      M2.merge(x[i], y[i]);
    else if (opt[i] == 'Z') {
      for (auto &p : tq[i]) {
        pre[p] = M2.query(x[p]);
      }
    } else if (opt[i] == 'A') {
      M2.tag[M2.bel[x[i]]] += M2.v[M2.bel[x[i]]].size();
    } else if (opt[i] == 'Q') {
      printf("%lld\n", M2.query(x[i]) - pre[i]);
    }
  }
  return 0;
}
