#include <bits/stdc++.h>
using namespace std;
const int N = 200000;
int n, cq, c[N * 2 + 9];
void Add(int p, int v) {
  if (!p) return;
  for (; p <= n + cq; p += p & -p) c[p] += v;
}
int Query(int p) {
  int res = 0;
  for (; p; p -= p & -p) res += c[p];
  return res;
}
struct tree {
  int fa, s[2], rev, siz, col, cov;
} tr[N + 9];
int sta[N + 9], cst;
bool Isroot(int k) { return tr[tr[k].fa].s[0] ^ k && tr[tr[k].fa].s[1] ^ k; }
void Pushup(int k) { tr[k].siz = tr[tr[k].s[0]].siz + 1 + tr[tr[k].s[1]].siz; }
void Update_rev(int k) {
  swap(tr[k].s[0], tr[k].s[1]);
  tr[k].rev ^= 1;
}
void Update_cov(int k, int v) { tr[k].col = tr[k].cov = v; }
void Pushdown(int k) {
  int x = tr[k].s[0], y = tr[k].s[1];
  if (tr[k].rev) {
    Update_rev(x);
    Update_rev(y);
    tr[k].rev = 0;
  }
  if (tr[k].cov) {
    if (x) Update_cov(x, tr[k].cov);
    if (y) Update_cov(y, tr[k].cov);
    tr[k].cov = 0;
  }
}
void Rotate(int x) {
  int y = tr[x].fa, z = tr[y].fa, b = tr[y].s[1] == x;
  if (!Isroot(y)) tr[z].s[tr[z].s[1] == y] = x;
  tr[x].fa = z;
  tr[y].s[b] = tr[x].s[b ^ 1];
  if (tr[x].s[b ^ 1]) tr[tr[x].s[b ^ 1]].fa = y;
  tr[x].s[b ^ 1] = y;
  tr[y].fa = x;
  Pushup(y);
  Pushup(x);
}
void Splay(int x) {
  sta[cst = 1] = x;
  for (int i = x; !Isroot(i); i = tr[i].fa) sta[++cst] = tr[i].fa;
  for (; cst; --cst) Pushdown(sta[cst]);
  for (; !Isroot(x); Rotate(x)) {
    int y = tr[x].fa, z = tr[y].fa;
    if (!Isroot(y)) tr[z].s[1] == y ^ tr[y].s[1] == x ? Rotate(x) : Rotate(y);
  }
  Pushup(x);
}
void Access(int k, int c) {
  for (int t = 0; k; t = k, k = tr[k].fa) {
    Splay(k);
    if (c) {
      int y = tr[k].s[0];
      Add(tr[k].col, -tr[y].siz - 1);
      Add(c, tr[y].siz + 1);
    }
    tr[k].s[1] = t;
    Pushup(k);
    if (c) Update_cov(k, c);
  }
}
void Makeroot(int k, int c) {
  Access(k, c);
  Splay(k);
  Update_rev(k);
}
void Link(int x, int y) {
  Makeroot(y, 0);
  tr[y].fa = x;
}
int Query_rank(int k) {
  Splay(k);
  return tr[tr[k].s[1]].siz + Query(tr[k].col - 1) + 1;
}
void into() {
  scanf("%d%d", &n, &cq);
  for (int i = 1; i <= n; ++i) tr[i].siz = 1;
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    Link(x, y);
  }
}
void Get_tr() {
  Makeroot(1, 0);
  for (int i = 1; i <= n; ++i) Makeroot(i, i);
}
void work() { Get_tr(); }
void outo() {
  int now = n;
  for (int cas = 1; cas <= cq; ++cas) {
    char opt[10];
    scanf("%s", opt);
    if (opt[0] == 'u') {
      int x;
      scanf("%d", &x);
      Makeroot(x, ++now);
    } else if (opt[0] == 'w') {
      int x;
      scanf("%d", &x);
      printf("%d\n", Query_rank(x));
    } else {
      int x, y;
      scanf("%d%d", &x, &y);
      printf("%d\n", Query_rank(x) < Query_rank(y) ? x : y);
    }
  }
}
int main() {
  into();
  work();
  outo();
  return 0;
}
