#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, n_, nn, x, y, xx, yy;
int lowbit(int x) { return x & (-x); }
struct bit {
  int t[N << 1];
  void update(int x, int v) {
    for (int i = x; i <= n_; i += lowbit(i)) t[i] += v;
  }
  int inquiry(int x) {
    int res = 0;
    for (int i = x; i; i -= lowbit(i)) res += t[i];
    return res;
  }
} t;
int anc[N], son[N][2], f[N];
int rev[N], v[N], cov[N], size[N];
int to[N << 1], nextn[N << 1], h[N], edg;
bool bb[N];
void add(int x, int y) {
  edg++;
  to[edg] = y;
  nextn[edg] = h[x];
  h[x] = edg;
}
bool isroot(int x) { return son[anc[x]][0] != x && son[anc[x]][1] != x; }
bool p(int x) { return son[anc[x]][1] == x; }
void rev_(int x) {
  son[x][0] ^= son[x][1] ^= son[x][0] ^= son[x][1];
  rev[x] ^= 1;
}
void cov_(int x, int w) { cov[x] = v[x] = w; }
void fix(int x) { size[x] = size[son[x][0]] + size[son[x][1]] + 1; }
void pushdown(int x) {
  if (rev[x]) {
    if (son[x][0]) rev_(son[x][0]);
    if (son[x][1]) rev_(son[x][1]);
    rev[x] = 0;
  }
  if (cov[x]) {
    if (son[x][0]) cov_(son[x][0], cov[x]);
    if (son[x][1]) cov_(son[x][1], cov[x]);
    cov[x] = 0;
  }
}
void rotate(int x) {
  int y = anc[x], xx = anc[y];
  bool b = p(x), bb = p(y);
  anc[x] = xx;
  if (!isroot(y)) son[xx][bb] = x;
  son[y][b] = son[x][b ^ 1];
  anc[son[x][b ^ 1]] = y;
  son[x][b ^ 1] = y;
  anc[y] = x;
  fix(y);
  fix(x);
  if (xx) fix(xx);
}
void pushall(int x) {
  if (!isroot(x)) pushall(anc[x]);
  pushdown(x);
}
void splay(int x) {
  pushall(x);
  for (int i = anc[x]; i = anc[x], !isroot(x); rotate(x))
    if (!isroot(i)) {
      if (p(i) == p(x))
        rotate(i);
      else
        rotate(x);
    }
}
int inquiry(int x) {
  splay(x);
  return t.inquiry(v[x]) - size[son[x][0]];
}
void access(int x) {
  for (int y = 0; x; y = x, x = anc[x]) {
    splay(x);
    t.update(v[x], -size[son[x][0]] - 1);
    son[x][1] = y;
    fix(x);
  }
}
void makeroot(int x) {
  access(x);
  splay(x);
  nn++;
  t.update(nn, size[x]);
  cov_(x, nn);
  rev_(x);
}
int id[N], rk[N], a[N], b[N], w[N];
priority_queue<int> q;
int deg[N], ord[N];
int build(int anc_, int l, int r, int c) {
  if (l > r) return 0;
  int mid = (l + r) >> 1;
  int x = a[mid];
  anc[x] = anc_;
  v[x] = c;
  if (l == r) {
    size[x] = 1;
    return x;
  }
  son[x][0] = build(x, l, mid - 1, c);
  son[x][1] = build(x, mid + 1, r, c);
  fix(x);
  return x;
}
void pre() {
  for (int i = 1; i < n; i++)
    scanf("%d%d", &x, &y), deg[x]++, deg[y]++, add(x, y), add(y, x);
  for (int i = 1; i <= n; i++)
    if (deg[i] == 1) q.push(-i);
  int k = 0;
  while (!q.empty()) {
    int x = -q.top();
    q.pop();
    bb[x] = 1;
    ord[++k] = x;
    w[x] = k;
    for (int i = h[x]; i; i = nextn[i]) {
      int y = to[i];
      if (bb[y]) continue;
      f[x] = y;
      deg[y]--;
      if (deg[y] == 1) q.push(-y);
    }
  }
  k = 0;
  for (int i = 1; i <= n; i++) {
    int x = ord[i], y = ord[i + 1];
    b[++k] = x;
    if (f[x] != y || i == n) {
      nn++;
      t.update(nn, k);
      for (int i = 1; i <= k; i++) a[i] = b[k - i + 1];
      build(f[x], 1, k, nn);
      k = 0;
    }
  }
}
char opt[10];
int main() {
  scanf("%d%d", &n, &m);
  n_ = n + m;
  pre();
  while (m--) {
    scanf("%s", opt);
    scanf("%d", &x);
    if (opt[0] == 'u') makeroot(x);
    if (opt[0] == 'w') printf("%d\n", inquiry(x));
    if (opt[0] == 'c') {
      scanf("%d", &y);
      xx = inquiry(x), yy = inquiry(y);
      printf("%d\n", xx < yy ? x : y);
    }
  }
}
