#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int maxn = 2e5 + 10, mod = 1e9 + 7;
const long long inf = 1e18;
vector<int> v[maxn];
int SZ[maxn], st[maxn], who[maxn], tp[maxn], h[maxn], start;
void dfssz(int u, int par = -1) {
  SZ[u] = 1;
  for (int y : v[u]) {
    if (y != par) dfssz(y, u), SZ[u] += SZ[y];
  }
}
void prep(int u, int par = -1, bool is = 1) {
  sort(v[u].begin(), v[u].end(), [&](int a, int b) { return SZ[a] < SZ[b]; });
  if (par == -1) v[u].push_back(-1);
  st[u] = start;
  who[start] = u;
  h[u] = par == -1 ? 0 : h[par] + 1;
  start++;
  tp[u] = is ? u : tp[par];
  if (int((v[u]).size()) > 1) prep(v[u][int((v[u]).size()) - 2], u, 0);
  for (int i = 0; i < int((v[u]).size()) - 2; i++) {
    prep(v[u][i], u, 1);
  }
}
template <long long Max, int Mxnode>
struct Segment {
  int nxt[Mxnode], Lz[Mxnode], Val[Mxnode], C = 1;
  void add(long long f, long long s, int x, long long l = 0, long long r = Max,
           int id = 0) {
    if (s <= l || r <= f) return;
    if (f <= l && r <= s) {
      Lz[id] += x;
      Val[id] += (r - l) * x;
      return;
    }
    if (nxt[id] == 0) nxt[id] = C, C += 2;
    long long mid = (l + r) >> 1;
    add(f, s, x, l, mid, nxt[id]), add(f, s, x, mid, r, nxt[id] + 1);
    Val[id] = Val[nxt[id]] + Val[nxt[id] + 1] + (r - l) * Lz[id];
  }
  int ask(long long f, long long s, long long l = 0, long long r = Max,
          int id = 0, int nw = 0) {
    if (s <= l || r <= f) return 0;
    if (f <= l && r <= s) return Val[id] + nw * (r - l);
    if (nxt[id] == 0) {
      nw += Lz[id];
      return nw * (min(r, s) - max(l, f));
    }
    long long mid = (l + r) >> 1;
    return ask(f, s, l, mid, nxt[id], nw + Lz[id]) +
           ask(f, s, mid, r, nxt[id] + 1, nw + Lz[id]);
  }
};
Segment<40000200000, 22345678> seg;
set<pair<pair<int, int>, pair<long long, long long> > > Set;
void add(int l, int r, long long f, long long s) {
  auto it = --Set.lower_bound((
      pair<pair<int, int>, pair<long long, long long> >){{l, 1e9}, {1e9, 1e9}});
  if ((it->first.first) != l) {
    auto x = *it;
    Set.erase(it);
    bool bl = x.second.first < x.second.second;
    long long num = x.second.first + (bl ? 1 : -1) * (l - x.first.first);
    Set.insert({{x.first.first, l - 1}, {x.second.first, num + (bl ? -1 : 1)}});
    Set.insert({{l, x.first.second}, {num, x.second.second}});
  }
  it = --Set.lower_bound((pair<pair<int, int>, pair<long long, long long> >){
      {r, 1e9}, {1e9, 1e9}});
  if ((it->first.second) != r) {
    auto x = *it;
    Set.erase(it);
    bool bl = x.second.first < x.second.second;
    long long num = x.second.second - (bl ? 1 : -1) * (x.first.second - r);
    Set.insert({{x.first.first, r}, {x.second.first, num}});
    Set.insert(
        {{r + 1, x.first.second}, {num + (bl ? 1 : -1), x.second.second}});
  }
  it = --Set.lower_bound((pair<pair<int, int>, pair<long long, long long> >){
      {l, 1e9}, {1e9, 1e9}});
  while (it != Set.end() && (it->first.first) != r + 1) {
    long long A = it->second.first, B = it->second.second;
    if (A > B) swap(A, B);
    seg.add(A, B + 1, -1);
    ++it, Set.erase(prev(it));
  }
  Set.insert({{l, r}, {f, s}});
  if (f > s) swap(f, s);
  seg.add(f, s + 1, 1);
}
int ask(int pos) {
  auto x =
      *(--Set.lower_bound((pair<pair<int, int>, pair<long long, long long> >){
          {pos, 1e9}, {1e9, 1e9}}));
  bool bl = x.second.first < x.second.second;
  long long num = x.second.first + (bl ? 1 : -1) * (pos - x.first.first);
  return seg.ask(0, num) + 1;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    v[a].push_back(b), v[b].push_back(a);
  }
  priority_queue<int, vector<int>, greater<int> > pq;
  int dg[maxn], ans[maxn];
  for (int i = 0; i < n; i++) {
    dg[i] = int((v[i]).size());
    if (dg[i] == 1) pq.push(i);
  }
  long long C = 0;
  while (int((pq).size())) {
    int u = pq.top();
    pq.pop();
    dg[u] = 0;
    for (int y : v[u]) {
      if (--dg[y] == 1) pq.push(y);
    }
    ans[u] = C, C++;
  }
  int lst = n - 1;
  dfssz(0);
  prep(0);
  seg.add(0, n, 1);
  for (int i = 0; i < n; i++) {
    Set.insert({{st[i], st[i]}, {ans[i], ans[i]}});
  }
  while (q--) {
    string task;
    cin >> task;
    if (task == "up") {
      int u;
      cin >> u;
      --u;
      long long vA = C, vB = C + n - 1;
      C += n;
      int A = lst, B = u;
      lst = u;
      while (tp[A] != tp[B]) {
        if (h[tp[A]] < h[tp[B]]) swap(A, B), swap(vA, vB);
        int cnt = st[A] - st[tp[A]] + 1;
        if (vA < vB)
          add(st[tp[A]], st[A], vA + cnt - 1, vA), vA += cnt;
        else
          add(st[tp[A]], st[A], vA - cnt + 1, vA), vA -= cnt;
        A = v[tp[A]].back();
      }
      if (h[A] < h[B]) swap(A, B), swap(vA, vB);
      int cnt = st[A] - st[B] + 1;
      if (vA < vB)
        add(st[B], st[A], vA + cnt - 1, vA);
      else
        add(st[B], st[A], vA - cnt + 1, vA);
    }
    if (task == "when") {
      int a;
      cin >> a;
      --a;
      cout << ask(st[a]) << "\n";
    }
    if (task == "compare") {
      int a, b;
      cin >> a >> b;
      --a, --b;
      cout << (ask(st[a]) < ask(st[b]) ? a + 1 : b + 1) << "\n";
    }
  }
  return 0;
}
