#include <bits/stdc++.h>
const int maxn = 2e5 + 7;
namespace Treap {
int root;
int q[maxn];
int lch[maxn];
int rch[maxn];
int prt[maxn];
int size[maxn];
bool flip[maxn];
inline bool islch(int p) { return lch[prt[p]] == p; }
inline void Flip(int p) { flip[p] ^= 1, std::swap(lch[p], rch[p]); }
inline void Pushup(int p) { size[p] = size[lch[p]] + size[rch[p]] + 1; }
inline void Pushdown(int p) {
  if (!flip[p]) return;
  if (lch[p]) Flip(lch[p]);
  if (rch[p]) Flip(rch[p]);
  flip[p] = false;
}
inline void sPushdown(int p) {
  if (prt[p]) sPushdown(prt[p]);
  Pushdown(p);
}
inline void Dfs(int p) {
  Pushdown(p);
  if (lch[p]) Dfs(lch[p]);
  printf("%d ", p);
  if (rch[p]) Dfs(rch[p]);
}
inline int Build(int rt, int s, int t) {
  int mid = (t + s) >> 1, p = q[mid];
  prt[p] = rt, size[p] = t - s + 1;
  lch[p] = rch[p] = 0, flip[p] = false;
  if (s < mid) lch[p] = Build(p, s, mid - 1);
  if (mid < t) rch[p] = Build(p, mid + 1, t);
  return p;
}
inline int Getrank(int rt) {
  sPushdown(rt);
  int ans = 0;
  bool flag = true;
  while (rt) {
    if (flag) ans += size[lch[rt]] + 1;
    flag = (!islch(rt)), rt = prt[rt];
  }
  return ans;
}
int rand_x = (long long)(new int);
inline int Merge(int x, int y) {
  if (!x || !y) return x + y;
  Pushdown(x), Pushdown(y);
  if ((rand_x = (rand_x * 998244353ll + 20190424)) % (size[x] + size[y]) <
      size[x]) {
    prt[rch[x]] = 0;
    rch[x] = Merge(rch[x], y);
    if (rch[x]) prt[rch[x]] = x;
    return Pushup(x), x;
  } else {
    prt[lch[y]] = 0;
    lch[y] = Merge(x, lch[y]);
    if (lch[y]) prt[lch[y]] = y;
    return Pushup(y), y;
  }
}
struct Pair {
  int first;
  int second;
};
inline Pair Split(int rt, int k) {
  if (!k) return (Pair){0, rt};
  Pair temp;
  Pushdown(rt);
  if (size[lch[rt]] >= k) {
    prt[lch[rt]] = 0;
    temp = Split(lch[rt], k);
    lch[rt] = temp.second;
    if (lch[rt]) prt[lch[rt]] = rt;
    temp.second = rt, Pushup(rt);
  } else {
    prt[rch[rt]] = 0;
    temp = Split(rch[rt], k - size[lch[rt]] - 1);
    rch[rt] = temp.first;
    if (rch[rt]) prt[rch[rt]] = rt;
    temp.first = rt, Pushup(rt);
  }
  return temp;
}
}  // namespace Treap
namespace LCT {
int n;
int prt[maxn];
int size[maxn];
int ch[2][maxn];
bool flip[maxn];
inline bool islch(int p) { return ch[0][prt[p]] == p; }
inline bool isroot(int p) { return ch[0][prt[p]] != p && ch[1][prt[p]] != p; }
inline void Flip(int p) { flip[p] ^= 1, std::swap(ch[0][p], ch[1][p]); }
inline void Pushup(int p) { size[p] = size[ch[0][p]] + size[ch[1][p]] + 1; }
inline void Pushdown(int p) {
  if (!isroot(p)) Pushdown(prt[p]);
  if (flip[p]) {
    if (ch[0][p]) Flip(ch[0][p]);
    if (ch[1][p]) Flip(ch[1][p]);
    flip[p] = false;
  }
}
inline void rotate(int p, int x) {
  int q = ch[!x][p];
  if (!isroot(p)) ch[!islch(p)][prt[p]] = q;
  prt[q] = prt[p], prt[p] = q;
  ch[!x][p] = ch[x][q], ch[x][q] = p;
  if (ch[!x][p]) prt[ch[!x][p]] = p;
  Pushup(p), Pushup(q);
}
inline void splay(int p) {
  Pushdown(p);
  while (!isroot(p)) {
    if (!isroot(prt[p])) {
      if (islch(p) == islch(prt[p]))
        rotate(prt[prt[p]], islch(prt[p]));
      else
        rotate(prt[p], islch(p));
    }
    rotate(prt[p], islch(p));
  }
}
inline void Access(int p) {
  int q = 0;
  for (; p; q = p, p = prt[p]) {
    splay(p), ch[1][p] = q, Pushup(p);
    int k = Treap::Getrank(p);
    Treap::Pair x = Treap::Split(Treap::root, k - 1);
    Treap::Pair y = Treap::Split(x.second, size[ch[0][p]] + 1);
    Treap::root = Treap::Merge(x.first, y.second);
    Treap::root = Treap::Merge(Treap::root, y.first);
  }
  Treap::Pair x = Treap::Split(Treap::root, n - size[q]);
  Treap::Flip(x.second), Treap::root = Treap::Merge(x.first, x.second);
}
inline void Makeroot(int p) { Access(p), splay(p), Flip(p); }
}  // namespace LCT
struct Edge {
  int to;
  int last;
} a[maxn << 1];
int n, m;
int tot;
int in[maxn];
int head[maxn];
inline void HA(int x, int y) {
  a[++tot] = (Edge){y, head[x]};
  head[x] = tot;
  a[++tot] = (Edge){x, head[y]};
  head[y] = tot;
}
inline void Dfs(int x, int prt) {
  LCT::size[x] = 1;
  LCT::prt[x] = prt;
  for (int i = head[x]; i; i = a[i].last)
    if (a[i].to != prt) ++in[x], Dfs(a[i].to, x);
}
int main() {
  scanf("%d%d", &n, &m), LCT::n = n;
  for (int i = 1, x, y; i < n; ++i) scanf("%d%d", &x, &y), HA(x, y);
  Dfs(n, 0);
  int cnt = 0;
  std::set<int> S;
  for (int i = 1; i <= n; ++i)
    if (!in[i]) S.insert(i);
  while (!S.empty()) {
    int x = *S.begin();
    S.erase(S.begin());
    Treap::q[++cnt] = x;
    if (!(--in[LCT::prt[x]])) S.insert(LCT::prt[x]);
  }
  Treap::root = Treap::Build(0, 1, n);
  for (int i = 1; i <= m; ++i) {
    char s[66];
    scanf("%s", s);
    if (s[0] == 'u') {
      int x;
      scanf("%d", &x);
      LCT::Makeroot(x);
    }
    if (s[0] == 'w') {
      int x;
      scanf("%d", &x);
      printf("%d\n", Treap::Getrank(x));
    }
    if (s[0] == 'c') {
      int x, y;
      scanf("%d%d", &x, &y);
      int kx = Treap::Getrank(x);
      int ky = Treap::Getrank(y);
      printf("%d\n", kx < ky ? x : y);
    }
  }
  return 0;
}
