#include <bits/stdc++.h>
using std::pair;
const int MAX = 2e5 + 7;
void read_int(int &a) {
  char c = getchar();
  a = 0;
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') a = (a << 1) + (a << 3) - 48 + c, c = getchar();
  return;
}
int get_type() {
  char c = getchar();
  while (c != 'u' && c != 'w' && c != 'c') c = getchar();
  return c == 'u' ? 0 : (c == 'w' ? 1 : 2);
}
int n, m;
struct edge {
  int point, next;
} r[MAX << 1];
int last[MAX];
void link(int x, int y) {
  static int tot = 0;
  r[++tot] = (edge){y, last[x]};
  last[x] = tot;
  r[++tot] = (edge){x, last[y]};
  last[y] = tot;
  return;
}
int depth[MAX], f[MAX], size[MAX], son[MAX];
void pre_dfs1(int now) {
  size[now] = 1;
  depth[now] = depth[f[now]] + 1;
  for (int i = last[now]; i; i = r[i].next)
    if (r[i].point != f[now]) {
      f[r[i].point] = now;
      pre_dfs1(r[i].point);
      size[now] += size[r[i].point];
      if (size[r[i].point] > size[son[now]]) son[now] = r[i].point;
    }
  return;
}
int num[MAX], top[MAX];
void pre_dfs2(int now) {
  static int cnt = 0;
  num[now] = ++cnt;
  top[now] = (now == son[f[now]]) ? top[f[now]] : now;
  if (!son[now]) return;
  pre_dfs2(son[now]);
  for (int i = last[now]; i; i = r[i].next)
    if (r[i].point != son[now] && r[i].point != f[now]) pre_dfs2(r[i].point);
  return;
}
int tag[MAX << 2], have;
void add(int now, int left, int right, int x, int y, int val) {
  if (left == x && right == y) {
    tag[now] += val;
    return;
  }
  const int mid = (left + right) >> 1;
  if (y <= mid)
    add(now << 1, left, mid, x, y, val);
  else if (x > mid)
    add(now << 1 | 1, mid + 1, right, x, y, val);
  else
    add(now << 1, left, mid, x, mid, val),
        add(now << 1 | 1, mid + 1, right, mid + 1, y, val);
  return;
}
int ask(int now, int left, int right, int pos) {
  if (left == right) return tag[now];
  const int mid = (left + right) >> 1;
  if (pos <= mid) return ask(now << 1, left, mid, pos) + tag[now];
  return ask(now << 1 | 1, mid + 1, right, pos) + tag[now];
}
int sum[MAX << 2];
void add(int now, int left, int right, int pos, int val) {
  sum[now] += val;
  if (left == right) return;
  const int mid = (left + right) >> 1;
  if (pos <= mid)
    add(now << 1, left, mid, pos, val);
  else
    add(now << 1 | 1, mid + 1, right, pos, val);
  return;
}
int ask(int now, int left, int right, int x, int y) {
  if (left == x && right == y) return sum[now];
  const int mid = (left + right) >> 1;
  if (y <= mid) return ask(now << 1, left, mid, x, y);
  if (x > mid) return ask(now << 1 | 1, mid + 1, right, x, y);
  return ask(now << 1, left, mid, x, mid) +
         ask(now << 1 | 1, mid + 1, right, mid + 1, y);
}
int ival[MAX], deg[MAX];
std::priority_queue<int, std::vector<int>, std::greater<int>> q;
void calc_value() {
  for (int cur = 1; cur <= n; cur++)
    for (int i = last[cur]; i; i = r[i].next) ++deg[r[i].point];
  for (int cur = 1; cur <= n; cur++)
    if (deg[cur] == 1) q.push(cur);
  while (q.size()) {
    static int cnt = 0, cur;
    ival[num[cur = q.top()]] = ++cnt;
    q.pop();
    for (int i = last[cur]; i; i = r[i].next)
      if (--deg[r[i].point] == 1) q.push(r[i].point);
  }
  return;
}
int rt[MAX];
std::map<pair<int, int>, int> col[MAX];
void init() {
  calc_value();
  rt[0] = have = n;
  for (int i = 1; i <= n; i++) add(1, 1, n, i, n, 1);
  for (int i = 1; i <= n; i++)
    if (!son[i]) col[top[i]][pair<int, int>(num[top[i]], num[i])] = 0;
  return;
}
pair<int, int> get_range(int cur, int pos) {
  auto ans = col[cur].upper_bound(pair<int, int>(pos, n + 1));
  return ans == col[cur].end() ? col[cur].rbegin()->first : (--ans)->first;
}
void merge(int cur, int x, int y, int val) {
  pair<int, int> left = get_range(cur, x), right = get_range(cur, y);
  auto posl = col[cur].find(left), posr = col[cur].find(right);
  int typ_left = posl->second, typ_right = posr->second;
  auto point = posl;
  while (true) {
    if (!point->second) {
      have -= point->first.second - point->first.first + 1;
      int sl = std::max(x, point->first.first),
          tr = std::min(y, point->first.second);
      for (int i = sl; i <= tr; i++) add(1, 1, n, ival[i], n, -1);
    } else
      add(1, 1, m, point->second,
          -(point->first.second - point->first.first + 1));
    if (point++ == posr) break;
  }
  col[cur].erase(posl, ++posr);
  if (x > left.first) {
    col[cur][pair<int, int>(left.first, x - 1)] = typ_left;
    if (typ_left)
      add(1, 1, m, typ_left, x - left.first);
    else
      have += x - left.first;
  }
  if (y < right.second) {
    col[cur][pair<int, int>(y + 1, right.second)] = typ_right;
    if (typ_right)
      add(1, 1, m, typ_right, right.second - y);
    else
      have += right.second - y;
  }
  col[cur][pair<int, int>(x, y)] = val;
  add(1, 1, m, val, y - x + 1);
  return;
}
void up(int cur) {
  static int cnt = 0;
  rt[++cnt] = cur;
  int x = cur, y = rt[cnt - 1];
  while (top[x] != top[y]) {
    if (depth[top[x]] > depth[top[y]])
      merge(top[x], num[top[x]], num[x], cnt), x = f[top[x]];
    else
      merge(top[y], num[top[y]], num[y], cnt), y = f[top[y]];
  }
  if (depth[x] > depth[y])
    merge(top[x], num[y], num[x], cnt);
  else
    merge(top[y], num[x], num[y], cnt);
  return;
}
int get_col(int cur) { return col[top[cur]][get_range(top[cur], num[cur])]; }
int get_dis(int x, int y) {
  int ans = 0;
  while (top[x] != top[y])
    if (depth[top[x]] > depth[top[y]])
      ans += num[x] - num[top[x]] + 1, x = f[top[x]];
    else
      ans += num[y] - num[top[y]] + 1, y = f[top[y]];
  return ans + (num[x] > num[y] ? num[x] - num[y] : num[y] - num[x]) + 1;
}
int when(int cur) {
  auto range = col[top[cur]].find(get_range(top[cur], num[cur]));
  if (!range->second) return ask(1, 1, n, ival[num[cur]]);
  int ans = have;
  if (range->second > 1) ans += ask(1, 1, m, 1, range->second - 1);
  if (get_col(rt[range->second - 1]) == range->second)
    ans += get_dis(rt[range->second - 1], cur);
  else
    ++ans;
  return ans;
}
int main() {
  read_int(n);
  read_int(m);
  for (int i = 1, x, y; i < n; i++) read_int(x), read_int(y), link(x, y);
  pre_dfs1(1);
  pre_dfs2(1);
  init();
  for (int i = 1; i <= m; i++) {
    static int u, v;
    int type = get_type();
    if (type == 0)
      read_int(v), up(v);
    else if (type == 1)
      read_int(v), printf("%d\n", when(v));
    else
      read_int(v), read_int(u), printf("%d\n", when(v) < when(u) ? v : u);
  }
  return 0;
}
