#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int g[N], v[N], nxt[N], ed;
int size[N], f[N], st[N], son[N], d[N], top[N];
int dfn;
void dfs(int x) {
  size[x] = 1;
  for (int i = g[x]; i; i = nxt[i]) {
    if (v[i] != f[x]) {
      f[v[i]] = x;
      d[v[i]] = d[x] + 1;
      dfs(v[i]);
      size[x] += size[v[i]];
      if (size[v[i]] > size[son[x]]) son[x] = v[i];
    }
  }
}
void dfs2(int x, int y) {
  st[x] = ++dfn;
  top[x] = y;
  if (son[x]) dfs2(son[x], y);
  for (int i = g[x]; i; i = nxt[i])
    if (v[i] != son[x] && v[i] != f[x]) dfs2(v[i], v[i]);
}
void change(int v);
struct Cg {
  int first, second, s;
};
list<Cg> ve;
void chain(int x, int y, int v) {
  ve.clear();
  auto it = ve.begin();
  int s = 1;
  for (; top[x] != top[y]; x = f[top[x]]) {
    if (d[top[x]] < d[top[y]]) {
      swap(x, y);
      s ^= 1;
    }
    it = ve.insert(it, Cg{st[top[x]], st[x], s});
    if (s) ++it;
  }
  if (d[x] < d[y]) {
    swap(x, y);
    s ^= 1;
  }
  ve.insert(it, Cg{st[y], st[x], s});
  change(v);
}
void add(int x, int y) {
  v[++ed] = y;
  nxt[ed] = g[x];
  g[x] = ed;
  v[++ed] = x;
  nxt[ed] = g[y];
  g[y] = ed;
}
struct Node {
  int a, mx, tag, flag, d;
  int l, r;
  int mid() { return l + r >> 1; }
  int len() { return r - l + 1; }
};
struct Res {
  int mx, l, r;
};
struct Seg {
  Node seg[N];
  Node& lc(int i) { return seg[i << 1]; }
  Node& rc(int i) { return seg[i << 1 | 1]; }
  void build(int i, int l, int r) {
    seg[i].l = l;
    seg[i].r = r;
    seg[i].mx = inf;
    seg[i].d = seg[i].a = seg[i].tag = seg[i].flag = 0;
    if (l != r) {
      int m = l + r >> 1;
      build(i << 1, l, m);
      build(i << 1 | 1, m + 1, r);
    }
  }
  inline void pushdown(int i) {
    if (!seg[i].flag) return;
    rc(i).mx = lc(i).mx = seg[i].mx;
    lc(i).d = rc(i).d = seg[i].d;
    lc(i).a = seg[i].a;
    rc(i).a = seg[i].a + lc(i).len() * seg[i].d;
    lc(i).tag = rc(i).tag = lc(i).flag = rc(i).flag = 1;
    seg[i].flag = 0;
  }
  void update(int i, int l, int r, int v, int a, int d) {
    if (seg[i].l == l && seg[i].r == r) {
      seg[i].flag = 1;
      seg[i].mx = v;
      seg[i].a = a;
      seg[i].tag = 1;
      seg[i].d = d;
      if (!v) {
        seg[i].mx = inf;
      }
      if (i != 1) up(i >> 1);
      return;
    }
    pushdown(i);
    int m = seg[i].mid();
    if (r <= m)
      update(i << 1, l, r, v, a, d);
    else if (l > m)
      update(i << 1 | 1, l, r, v, a, d);
    else {
      update(i << 1, l, m, v, a, d);
      update(i << 1 | 1, m + 1, r, v, a + (m - l + 1) * d, d);
    }
    seg[i].mx = min(lc(i).mx, rc(i).mx);
    seg[i].tag = lc(i).tag && rc(i).tag && lc(i).mx == rc(i).mx;
  }
  void up(int i) {
    seg[i].mx = min(lc(i).mx, rc(i).mx);
    seg[i].tag = lc(i).tag && rc(i).tag && lc(i).mx == rc(i).mx;
    if (i != 1) up(i >> 1);
  }
  Res query(int i, int l, int r, int v) {
    if (seg[i].mx > v) return Res{0, 0, 0};
    if (seg[i].l >= l && r >= seg[i].r && seg[i].tag || seg[i].l == seg[i].r) {
      return Res{seg[i].mx, seg[i].l, seg[i].r};
    }
    pushdown(i);
    int m = seg[i].mid();
    if (r <= m)
      return query(i << 1, l, r, v);
    else if (l > m)
      return query(i << 1 | 1, l, r, v);
    Res res = query(i << 1, l, m, v);
    if (!res.mx) {
      res = query(i << 1 | 1, m + 1, r, v);
    }
    return res;
  }
  int queryfast(int i, int l, int r, int v) {
    if (seg[i].mx > v) return i;
    if (seg[i].l >= l && r >= seg[i].r && seg[i].tag || seg[i].l == seg[i].r) {
      return i;
    }
    int m = seg[i].mid();
    pushdown(i);
    if (r <= m)
      return queryfast(i << 1, l, r, v);
    else if (l > m)
      return queryfast(i << 1 | 1, l, r, v);
    return i;
  }
  pair<int, int> queryA(int i, int pos) {
    if (seg[i].l == seg[i].r) {
      int res = seg[i].a;
      res += (pos - seg[i].l) * seg[i].d;
      return make_pair(res, seg[i].mx);
    }
    pushdown(i);
    int m = seg[i].mid();
    if (pos <= m) return queryA(i << 1, pos);
    return queryA(i << 1 | 1, pos);
  }
} seg;
struct Bit {
  int c[N];
  int n;
  void add(int x, int v) {
    if (!x) return;
    for (; x <= n; x += x & -x) c[x] += v;
  }
  int sum(int x) {
    int res = 0;
    for (; x > 0; x = x & (x - 1)) {
      res += c[x];
    }
    return res;
  }
} bit;
void change(int v) {
  int a = 0;
  for (Cg p : ve) {
    int start = seg.queryfast(1, p.first, p.second, v);
    Res res = seg.query(start, p.first, p.second, v);
    p.s = p.s + 1 - p.s * 3;
    while (res.mx) {
      bit.add(res.mx, -(res.r - res.l + 1));
      seg.update(start, res.l, res.r, 0, 0, 0);
      res = seg.query(start, p.first, p.second, v);
    }
    int bg = a + 1;
    if (p.s == -1) bg += p.second - p.first;
    seg.update(start, p.first, p.second, v, bg, p.s);
    a += p.second - p.first + 1;
  }
  bit.add(v, a);
}
int when(int x) {
  pair<int, int> res = seg.queryA(1, st[x]);
  return res.first + bit.sum(res.second - 1);
}
struct Deal {
  int mx, mxpos;
  Deal() {
    mx = 0;
    mxpos = 1;
  }
  void up(int v) {
    chain(mxpos, v, ++mx);
    mxpos = v;
  }
} deal;
void work() {
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < (n - 1); ++i) {
    int u, v;
    cin >> u >> v;
    add(u, v);
  }
  string s;
  bit.n = n + q + 5;
  seg.build(1, 1, n);
  dfs(1);
  dfs2(1, 1);
  for (int v = (1); v <= (n); ++v) {
    deal.up(v);
  }
  for (int _ = 0; _ < (q); ++_) {
    int v;
    cin >> s >> v;
    if (s == "up") {
      deal.up(v);
    } else if (s == "when") {
      cout << when(v) << endl;
    } else {
      int u;
      cin >> u;
      if (when(u) > when(v)) swap(u, v);
      cout << u << endl;
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  work();
}
