#include <bits/stdc++.h>
using namespace std;
template <typename T>
void read(T &a) {
  T x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  a = x * f;
}
template <typename T>
void write(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (x < 10) return (void)putchar(x + '0');
  write(x / 10);
  putchar(x % 10 + '0');
}
template <typename T>
void writeln(T x) {
  write(x);
  putchar('\n');
}
template <typename T>
void writes(T x) {
  write(x);
  putchar(' ');
}
template <typename T, typename... Args>
void read(T &t, Args &...args) {
  read(t);
  read(args...);
}
template <typename T, typename... Args>
void writes(T t, Args... args) {
  writes(t);
  writes(args...);
}
template <typename T, typename... Args>
void writeln(T t, Args... args) {
  writes(t);
  writes(args...);
  putchar('\n');
}
long long n, m, head[200005], pnt[200005 << 1], nxt[200005 << 1], E = 0;
long long id[200005], cnt;
void add_edge(long long u, long long v) {
  pnt[E] = v;
  nxt[E] = head[u];
  head[u] = E++;
}
struct BIT {
  long long tr[200005 << 1];
  long long lowbit(long long x) { return x & (-x); }
  void update(long long x, long long k) {
    while (x <= n + m) {
      tr[x] += k;
      x += lowbit(x);
    }
  }
  long long query(long long x) {
    long long res = 0;
    while (x) {
      res += tr[x];
      x -= lowbit(x);
    }
    return res;
  }
} T;
namespace LCT {
long long siz[200005], ch[200005][2], fa[200005], rev[200005];
long long check(long long x) { return x == ch[fa[x]][1]; }
long long isroot(long long x) { return x != ch[fa[x]][0] && x != ch[fa[x]][1]; }
void pushup(long long x) { siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; }
void pushr(long long x) {
  swap(ch[x][0], ch[x][1]);
  rev[x] ^= 1;
}
void pushdown(long long x) {
  id[ch[x][0]] = id[x];
  id[ch[x][1]] = id[x];
  if (!rev[x]) return;
  pushr(ch[x][0]);
  pushr(ch[x][1]);
  rev[x] = 0;
}
void rotate(long long x) {
  long long y = fa[x], z = fa[y], k = check(x), w = ch[x][!k];
  if (!isroot(y)) ch[z][check(y)] = x;
  ch[x][!k] = y;
  ch[y][k] = w;
  if (w) fa[w] = y;
  fa[y] = x;
  fa[x] = z;
  pushup(y);
}
void splay(long long x) {
  long long y = x;
  std::vector<long long> sk;
  sk.push_back(y);
  while (!isroot(y)) sk.push_back(fa[y]), y = fa[y];
  while (!sk.empty()) pushdown(sk.back()), sk.pop_back();
  while (!isroot(x)) {
    y = fa[x];
    if (!isroot(y)) rotate((check(x) ^ check(y)) ? x : y);
    rotate(x);
  }
  pushup(x);
}
void access(long long x) {
  long long y = 0;
  while (x) {
    splay(x);
    T.update(id[x], -siz[ch[x][0]] - 1);
    T.update(cnt, siz[ch[x][0]] + 1);
    ch[x][1] = y;
    pushup(x);
    y = x;
    x = fa[x];
  }
}
}  // namespace LCT
void dfs(long long u, long long f) {
  LCT::fa[u] = f;
  LCT::siz[u] = 1;
  id[u] = u;
  for (long long i = head[u]; i != -1; i = nxt[i]) {
    long long v = pnt[i];
    if (v == f) continue;
    dfs(v, u);
    if (id[u] < id[v]) {
      id[u] = id[v];
      LCT::ch[u][1] = v;
      LCT::siz[u] = LCT::siz[v] + 1;
    }
  }
  T.update(id[u], 1);
}
signed main() {
  memset(head, -1, sizeof(head));
  read(n, m);
  for (long long i = 1; i < n; i++) {
    long long u, v;
    read(u, v);
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs(n, 0);
  cnt = n;
  for (long long i = 1; i <= m; i++) {
    char opt[7];
    scanf("%s", opt);
    if (opt[0] == 'u') {
      long long u;
      read(u);
      cnt++;
      LCT::access(u);
      LCT::splay(u);
      LCT::pushr(u);
      id[u] = cnt;
    }
    if (opt[0] == 'w') {
      long long u;
      read(u);
      LCT::splay(u);
      writeln(T.query(id[u]) - LCT::siz[LCT::ch[u][0]]);
    }
    if (opt[0] == 'c') {
      long long u, v;
      read(u, v);
      LCT::splay(u);
      long long au = T.query(id[u]) - LCT::siz[LCT::ch[u][0]];
      LCT::splay(v);
      long long av = T.query(id[v]) - LCT::siz[LCT::ch[v][0]];
      writeln(au < av ? u : v);
    }
  }
  return 0;
}
