#include <bits/stdc++.h>
using namespace std;
int gcdex(int a, int b, int &x, int &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  int x1, y1;
  int g = gcdex(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return g;
}
inline int ADD_MOD(int a, int b) { return (a + b) % 1000000007; }
inline int MUL_MOD(int a, int b) { return (int64_t(a) * b) % 1000000007; }
inline int SUB_MOD(int a, int b) { return a >= b ? a - b : a + 1000000007 - b; }
int DIV_MOD(int a, int b) {
  int x, y;
  gcdex(b, 1000000007, x, y);
  int b1 = (x % 1000000007 + 1000000007) % 1000000007;
  return MUL_MOD(a, b1);
}
inline bool EPS_EQUAL(double a, double b) { return abs(a - b) <= 0.0000001; }
inline bool EPS_LESS(double a, double b) { return b - a > 0.0000001; }
inline bool EPS_GREATER(double a, double b) { return a - b > 0.0000001; }
const int INF = numeric_limits<int>::max();
struct Node {
  int parent;
  int addTime = -1;
  int size = 1;
  int clearTime = -1;
  vector<int64_t> increments;
  vector<int> incrementTimes;
};
int join(Node &a, Node &b, int time) {
  if (a.parent == b.parent) {
    return a.parent;
  }
  if (b.size > a.size) {
    a.parent = b.parent;
    a.addTime = time;
    b.size += a.size;
  } else {
    b.parent = a.parent;
    b.addTime = time;
    a.size += b.size;
  }
  return a.parent;
}
int clear_time(vector<Node> &a, int node) {
  int t = a[node].clearTime;
  int prevNode = node;
  node = a[node].parent;
  while (prevNode != node) {
    if (a[node].clearTime > a[prevNode].addTime) {
      t = a[node].clearTime;
    }
    prevNode = node;
    node = a[node].parent;
  }
  return t;
}
int64_t calc(Node &a, int from) {
  if (a.increments.empty()) {
    return 0;
  }
  int fromI =
      lower_bound(a.incrementTimes.begin(), a.incrementTimes.end(), from) -
      a.incrementTimes.begin();
  if (fromI > 0) {
    return a.increments.back() - a.increments[fromI - 1];
  }
  return a.increments.back();
}
int64_t solve(vector<Node> &a, int node, int fromTime) {
  int64_t res = calc(a[node], fromTime);
  int prevNode = node;
  node = a[node].parent;
  while (prevNode != node) {
    fromTime = max(fromTime, a[prevNode].addTime);
    res += calc(a[node], fromTime);
    prevNode = node;
    node = a[node].parent;
  }
  return res;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.precision(15);
  int n, m;
  cin >> n >> m;
  vector<Node> a(n);
  vector<Node> b(n);
  vector<int> parentsA(n);
  vector<int> parentsB(n);
  for (int i = 0; i < n; ++i) {
    a[i].parent = i;
    b[i].parent = i;
    parentsA[i] = i;
    parentsB[i] = i;
  }
  for (int i = 0; i < m; ++i) {
    char cmd;
    int x1;
    cin >> cmd >> x1;
    --x1;
    switch (cmd) {
      case 'U': {
        int x2;
        cin >> x2;
        --x2;
        parentsA[x1] = join(a[parentsA[x1]], a[parentsA[x2]], i);
        break;
      }
      case 'M': {
        int x2;
        cin >> x2;
        --x2;
        parentsB[x1] = join(b[parentsB[x1]], b[parentsB[x2]], i);
        break;
      }
      case 'A': {
        auto &n = a[parentsA[x1]];
        if (!n.increments.empty()) {
          n.increments.push_back(n.increments.back() + n.size);
        } else {
          n.increments.push_back(n.size);
        }
        n.incrementTimes.push_back(i);
        break;
      }
      case 'Z': {
        auto &n = b[parentsB[x1]];
        n.clearTime = i;
        break;
      }
      case 'Q': {
        int from = clear_time(b, x1);
        cout << solve(a, x1, from) << endl;
        break;
      }
    }
  }
  return 0;
}
