#include <bits/stdc++.h>
using namespace std;
int gi() {
  char cc = getchar();
  int cn = 0, flus = 1;
  while (cc < '0' || cc > '9') {
    if (cc == '-') flus = -flus;
    cc = getchar();
  }
  while (cc >= '0' && cc <= '9') cn = cn * 10 + cc - '0', cc = getchar();
  return cn * flus;
}
const int N = 2e5 + 5;
const int M = 50 + 5;
struct LCT {
  int mk, fa, ch[2], col, sz, c;
} t[N];
int n, Q, idnum, maxn, st[N], top, tree[N << 1];
vector<int> G[N];
char s[M];
void add(int x, int k) {
  for (register int i = x; i <= maxn; i += (i & (-i))) tree[i] += k;
}
int query(int x) {
  int sum = 0;
  for (register int i = x; i; i -= (i & (-i))) sum += tree[i];
  return sum;
}
bool isroot(int x) {
  return (t[t[x].fa].ch[1] != x) && (t[t[x].fa].ch[0] != x);
}
void dfs(int x, int fa) {
  if (fa ^ x) t[x].fa = fa;
  for (int v : G[x])
    if (fa ^ v) dfs(v, x);
}
void pushmark(int x) {
  if (t[x].mk)
    swap(t[x].ch[0], t[x].ch[1]), t[t[x].ch[0]].mk ^= 1, t[t[x].ch[1]].mk ^= 1,
        t[x].mk = 0;
  if (t[x].c)
    t[t[x].ch[0]].col = t[x].c, t[t[x].ch[1]].col = t[x].c,
    t[t[x].ch[0]].c = t[x].c, t[t[x].ch[1]].c = t[x].c, t[x].c = 0;
}
void rotate(int x) {
  int f = t[x].fa, ff = t[f].fa, d = (t[f].ch[1] == x), c = t[x].ch[d ^ 1];
  t[x].fa = ff;
  if (!isroot(f)) t[ff].ch[t[ff].ch[1] == f] = x;
  t[x].ch[d ^ 1] = f, t[f].fa = x, t[f].ch[d] = c, t[c].fa = f,
              (t[f].sz = t[t[f].ch[0]].sz + t[t[f].ch[1]].sz + 1),
              (t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1);
}
void Splay(int x) {
  int u = x;
  st[++top] = u;
  while (!isroot(u)) st[++top] = (u = t[u].fa);
  while (top) pushmark(st[top--]);
  while (!isroot(x)) {
    int f = t[x].fa, ff = t[f].fa;
    if (!isroot(f))
      (t[ff].ch[1] == f) ^ (t[f].ch[1] == x) ? rotate(x) : rotate(f);
    rotate(x);
  }
}
void makeroot(int u) {
  int x = u;
  ++idnum;
  for (int y = 0; x; y = x, x = t[x].fa) {
    Splay(x), t[x].ch[1] = 0,
              (t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1),
              add(t[x].col, -t[x].sz);
    t[x].ch[1] = y, (t[x].sz = t[t[x].ch[0]].sz + t[t[x].ch[1]].sz + 1);
  }
  Splay(u), t[u].col = idnum, t[u].c = idnum, t[u].mk ^= 1, pushmark(u),
            add(t[u].col, t[u].sz);
}
int Query(int x) {
  Splay(x);
  int ans = query(t[x].col - 1) + t[t[x].ch[1]].sz + 1;
  return ans;
}
void Compare(int x, int y) {
  int fx = Query(x), fy = Query(y);
  printf("%d\n", (fx < fy) ? x : y);
}
void init() {
  int cnt = n, u, s, v;
  for (register int i = n; i >= 1; --i) {
    if (t[i].col) continue;
    u = i, s = v = 0;
    while (!t[u].col && u) {
      t[u].col = cnt, t[u].ch[1] = v,
      (t[u].sz = t[t[u].ch[0]].sz + t[t[u].ch[1]].sz + 1), v = u, u = t[u].fa,
      ++s;
    }
    add(cnt, s), --cnt;
  }
}
signed main() {
  n = gi(), Q = gi();
  int x, y;
  for (register int i = (1); i <= (n); ++i) t[i].sz = 1;
  for (register int i = (2); i <= (n); ++i)
    x = gi(), y = gi(), G[x].push_back(y), G[y].push_back(x);
  dfs(n, n), maxn = n + Q, idnum = n;
  init();
  while (Q--) {
    scanf("%s", s + 1);
    if (s[1] == 'u') x = gi(), makeroot(x);
    if (s[1] == 'w') x = gi(), printf("%d\n", Query(x));
    if (s[1] == 'c') x = gi(), y = gi(), Compare(x, y);
  }
  return 0;
}
