#include <bits/stdc++.h>
using namespace std;
const int RLEN = 1 << 20 | 1;
inline char gc() {
  static char ibuf[RLEN], *ib, *ob;
  (ob == ib) && (ob = (ib = ibuf) + fread(ibuf, 1, RLEN, stdin));
  return (ob == ib) ? EOF : *ib++;
}
inline int read() {
  char ch = gc();
  int res = 0, f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline int readchar(char *s) {
  char ch = gc();
  int top = 0;
  while (!isalpha(ch)) ch = gc();
  while (isalpha(ch)) s[top++] = ch, ch = gc();
  return top;
}
inline void chemx(int &a, int b) { a < b ? a = b : 0; }
inline void chemn(int &a, int b) { a > b ? a = b : 0; }
const int N = 200005;
namespace Tr {
const int N = 400000;
int tr[N + 5];
inline void update(int p, int k) {
  for (; p <= N; p += (p & (-p))) tr[p] += k;
}
inline int query(int p, int res = 0) {
  for (; p; p -= (p & (-p))) res += tr[p];
  return res;
}
}  // namespace Tr
int n, m, val[N], tot;
vector<int> e[N];
char s[N];
namespace Lct {
int son[N][2], fa[N], rev[N], siz[N];
inline bool isrt(int u) {
  return fa[u] ? (son[fa[u]][0] != u && son[fa[u]][1] != u) : 1;
}
inline bool isrc(int u) { return son[fa[u]][1] == u; }
inline void pushnow(int u) { swap(son[u][0], son[u][1]), rev[u] ^= 1; }
inline void pushdown(int u) {
  if (son[u][0]) val[son[u][0]] = val[u];
  if (son[u][1]) val[son[u][1]] = val[u];
  if (!rev[u]) return;
  if (son[u][0]) pushnow(son[u][0]);
  if (son[u][1]) pushnow(son[u][1]);
  rev[u] = 0;
}
inline void pushup(int u) {
  siz[u] = 1;
  if (son[u][0]) siz[u] += siz[son[u][0]];
  if (son[u][1]) siz[u] += siz[son[u][1]];
}
inline void rotate(int v) {
  int u = fa[v], z = fa[u];
  int t = isrc(v);
  if (!isrt(u)) son[z][isrc(u)] = v;
  fa[v] = z;
  fa[son[v][t ^ 1]] = u;
  son[u][t] = son[v][t ^ 1];
  fa[u] = v, son[v][t ^ 1] = u;
  pushup(u), pushup(v);
}
int stk[N], top;
inline void splay(int u) {
  stk[top = 1] = u;
  for (int v = u; !isrt(v); v = fa[v]) stk[++top] = fa[v];
  for (int i = top; i; i--) pushdown(stk[i]);
  while (!isrt(u)) {
    if (!isrt(fa[u])) isrc(u) == isrc(fa[u]) ? rotate(fa[u]) : rotate(u);
    rotate(u);
  }
}
inline void access(int u) {
  for (int v = 0; u; v = u, u = fa[u]) {
    splay(u), son[u][1] = 0, pushup(u);
    Tr::update(val[u], -siz[u]);
    Tr::update(tot, siz[u]);
    son[u][1] = v;
    pushup(u);
  }
}
inline void makert(int u) { access(u), splay(u), pushnow(u); }
inline void update(int u) { tot++, makert(u), val[u] = tot; }
inline int query(int u) {
  splay(u);
  return Tr::query(val[u]) - siz[son[u][0]];
}
}  // namespace Lct
void dfs(int u, int fa) {
  int mx = 0, son = 0;
  val[u] = u;
  for (int &v : e[u]) {
    if (v == fa) continue;
    dfs(v, u);
    if (val[v] > mx) mx = val[v], son = v;
    Lct::fa[v] = u;
  }
  if (mx > val[u]) Lct::son[u][1] = son, val[u] = mx;
  Lct::pushup(u), Tr::update(val[u], 1);
}
int main() {
  tot = n = read(), m = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    e[u].push_back(v), e[v].push_back(u);
  }
  dfs(n, 0);
  while (m--) {
    int len = readchar(s), u = read();
    if (s[0] == 'u') {
      Lct::update(u);
    } else if (s[0] == 'w') {
      cout << Lct::query(u) << '\n';
    } else {
      int v = read();
      cout << (Lct::query(u) > Lct::query(v) ? v : u) << '\n';
    }
  }
}
