#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500005;
int n, m, col[MAXN];
int f[MAXN], ch[MAXN][2], siz[MAXN], rev[MAXN];
struct FenwickTree {
  int tree[MAXN * 2];
  inline void upd(int p, int v) {
    while (p <= n + m) tree[p] += v, p += (p & -p);
  }
  inline int query(int p) {
    int res = 0;
    while (p) res += tree[p], p -= (p & -p);
    return res;
  }
} BIT;
vector<int> G[MAXN];
inline void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    (x *= 10) += ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void push_up(int p) { siz[p] = siz[ch[p][0]] + siz[ch[p][1]] + 1; }
inline int not_root(int p) { return ch[f[p]][0] == p || ch[f[p]][1] == p; }
inline int get_which(int p) { return ch[f[p]][1] == p; }
inline void push_rev(int p) {
  swap(ch[p][0], ch[p][1]);
  rev[p] ^= 1;
}
inline void push_down(int p) {
  if (rev[p]) {
    if (ch[p][0]) push_rev(ch[p][0]);
    if (ch[p][1]) push_rev(ch[p][1]);
    rev[p] = 0;
  }
  if (ch[p][0]) col[ch[p][0]] = col[p];
  if (ch[p][1]) col[ch[p][1]] = col[p];
}
inline void rotate(int x) {
  int fa = f[x], gr = f[fa], x_w = get_which(x), son = ch[x][x_w ^ 1];
  if (not_root(fa)) ch[gr][get_which(fa)] = x;
  ch[x][x_w ^ 1] = fa;
  ch[fa][x_w] = son;
  f[son] = fa;
  f[fa] = x;
  f[x] = gr;
  push_up(fa);
  push_up(x);
}
int stk[MAXN], top;
inline void splay(int x) {
  top = 0;
  int p = x;
  stk[++top] = p;
  while (not_root(p)) p = f[p], stk[++top] = p;
  while (top) push_down(stk[top]), top--;
  while (not_root(x)) {
    if (not_root(f[x])) rotate(get_which(x) == get_which(f[x]) ? f[x] : x);
    rotate(x);
  }
}
inline void access(int p) {
  for (int son = 0; p; son = p, p = f[p]) {
    splay(p);
    BIT.upd(col[p], -(siz[p] - siz[ch[p][1]]));
    ch[p][1] = son;
    push_up(p);
  }
}
inline void make_root(int p) {
  access(p);
  splay(p);
  push_rev(p);
}
int tot;
inline void modify(int p) {
  make_root(p);
  col[p] = ++tot;
  BIT.upd(col[p], siz[p]);
}
inline int query(int p) {
  return splay(p), BIT.query(col[p] - 1) + 1 + siz[ch[p][1]];
}
void dfs(int u, int c_fa) {
  f[u] = c_fa;
  BIT.upd(col[u], 1);
  siz[u] = 1;
  for (int v : G[u])
    if (v != c_fa) dfs(v, u);
}
inline void prepare() {
  int deg[MAXN];
  for (int i = 1; i <= n; i++) deg[i] = G[i].size();
  priority_queue<int, vector<int>, greater<int> > q;
  for (int i = 1; i <= n; i++)
    if (deg[i] == 1) q.push(i);
  for (int i = 1; i <= n; i++) {
    int u = q.top();
    q.pop();
    col[u] = i;
    for (int v : G[u])
      if (--deg[v] == 1) q.push(v);
  }
  dfs(n, 0);
  tot = n;
}
int main() {
  n = read(), m = read();
  for (int i = 1; i < n; i++) add_edge(read(), read());
  prepare();
  char opt[11];
  for (int i = 1, x, y; i <= m; i++) {
    scanf("%s", opt);
    if (opt[0] == 'w') printf("%d\n", query(read()));
    if (opt[0] == 'u') modify(read());
    if (opt[0] == 'c')
      x = read(), y = read(), printf("%d\n", query(x) > query(y) ? y : x);
  }
  return 0;
}
