#include <bits/stdc++.h>
using namespace std;
struct query {
  char c;
  int x, y;
  long long ans;
  query *child;
  void read() {
    scanf(" %c %d", &c, &x);
    if (c == 'U' || c == 'M') {
      scanf("%d", &y);
    }
  }
};
int N, M;
query Q[2 * (1 << 19)];
struct virus {
  int ch[2 * (1 << 19)][2];
  int lt[2 * (1 << 19)], rt[2 * (1 << 19)];
  int chpar[2 * (1 << 19)];
  int cnode;
  int curn[(1 << 19)];
  int ord[(1 << 19)], idx[(1 << 19)];
  int ufpar[(1 << 19)];
  void setchild(int cur, int dir, int x) {
    ch[cur][dir] = x;
    chpar[x] = cur;
  }
  int find(int x) { return x == ufpar[x] ? x : ufpar[x] = find(ufpar[x]); }
  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      puts("BAD MERGE");
      exit(0);
    }
    ufpar[x] = y;
    curn[y] = chpar[curn[y]];
  }
  void reset() {
    for (int i = 1; i <= N; i++) {
      curn[i] = ufpar[i] = i;
    }
  }
} john, tukey;
void inorder(virus &tr, int x, int &ptr) {
  if (x > N) {
    for (int i = 0; i < 2; i++) {
      inorder(tr, tr.ch[x][i], ptr);
    }
    tr.lt[x] = tr.lt[tr.ch[x][0]];
    tr.rt[x] = tr.rt[tr.ch[x][1]];
  } else {
    ptr++;
    tr.ord[ptr] = x;
    tr.idx[x] = ptr;
  }
}
void filter(char c, virus &tr) {
  tr.reset();
  for (int i = 1; i <= N; i++) {
    tr.lt[i] = tr.rt[i] = i;
  }
  int &ctr = tr.cnode;
  ctr = N;
  for (int i = 1; i <= M; i++) {
    if (Q[i].c != c) {
      continue;
    }
    int x = tr.find(Q[i].x), y = tr.find(Q[i].y);
    ctr++;
    tr.setchild(ctr, 0, tr.curn[x]);
    tr.setchild(ctr, 1, tr.curn[y]);
    tr.merge(x, y);
  }
  int ptr = 0;
  for (int i = 1; i <= ctr; i++) {
    if (tr.chpar[i]) {
      continue;
    }
    inorder(tr, i, ptr);
  }
  if (ptr != N) {
    printf("UHOH %d\n", ptr);
    exit(0);
  }
  tr.reset();
}
int tree[2 * (1 << 19)], lazy[2 * (1 << 19)];
long long bit[(1 << 19)];
vector<query> qbef[(1 << 19)];
void add(int cur, int v) {
  tree[cur] = v;
  lazy[cur] = v;
}
void down(int cur) {
  if (lazy[cur]) {
    add(2 * cur, lazy[cur]);
    add(2 * cur + 1, lazy[cur]);
    lazy[cur] = 0;
  }
}
void update(int a, int b, int v, int cur = 1, int l = 0, int r = (1 << 19)) {
  if (r <= a || b <= l) {
    return;
  }
  if (a <= l && r <= b) {
    add(cur, v);
    return;
  }
  down(cur);
  int mid = (l + r) / 2;
  update(a, b, v, 2 * cur, l, mid);
  update(a, b, v, 2 * cur + 1, mid, r);
}
int qtree(int a, int cur = 1, int l = 0, int r = (1 << 19)) {
  if (r == l + 1) {
    return tree[cur];
  }
  down(cur);
  int mid = (l + r) / 2;
  return a < mid ? qtree(a, 2 * cur, l, mid) : qtree(a, 2 * cur + 1, mid, r);
}
void upbit(int x, int v) {
  for (; x < (1 << 19); x += (x & -x)) {
    bit[x] += v;
  }
}
long long qubit(int x) {
  long long s = 0;
  for (; x; x &= x - 1) {
    s += bit[x];
  }
  return s;
}
void go(bool second) {
  for (int i = 1; i <= M; i++) {
    if (second) {
      for (query qu : qbef[i]) {
        qu.child->ans -= qubit(john.idx[qu.x]);
      }
    }
    char c = Q[i].c;
    int x = Q[i].x, y = Q[i].y;
    if (c == 'M') {
      tukey.merge(x, y);
    } else if (c == 'U') {
      john.merge(x, y);
    } else if (c == 'A') {
      int cn = john.curn[john.find(x)];
      int ltidx = john.idx[john.lt[cn]], rtidx = john.idx[john.rt[cn]];
      int sz = rtidx - ltidx + 1;
      upbit(ltidx, sz);
      upbit(rtidx + 1, -sz);
    } else if (c == 'Z') {
      if (second) {
        continue;
      }
      int cn = tukey.curn[tukey.find(x)];
      int ltidx = tukey.idx[tukey.lt[cn]], rtidx = tukey.idx[tukey.rt[cn]];
      update(ltidx, rtidx + 1, i);
    } else {
      if (second) {
        cout << Q[i].ans << '\n';
      } else {
        Q[i].ans = qubit(john.idx[x]);
        int raid = qtree(tukey.idx[x]);
        query qu;
        qu.x = x;
        qu.child = Q + i;
        qbef[raid].push_back(qu);
      }
    }
  }
}
int main() {
  if (fopen("input.txt", "r")) {
    freopen("input.txt", "r", stdin);
  }
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= M; i++) {
    Q[i].read();
  }
  filter('U', john);
  filter('M', tukey);
  go(false);
  tukey.reset();
  john.reset();
  memset((tree), (0), sizeof(tree));
  memset((lazy), (0), sizeof(lazy));
  memset((bit), (0), sizeof(bit));
  go(true);
}
