#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200007;
const int LOGN = 18;
vector<int> edg[MAXN];
int sbtr[MAXN], lvl[MAXN], pr[MAXN][LOGN];
int chainIdx[MAXN], chainHead[MAXN], flatIdx[MAXN], flat[MAXN];
int chainCnt, flatCnt;
void dfs(int u, int p) {
  lvl[u] = lvl[p] + 1;
  pr[u][0] = p;
  for (int k = 1; k < LOGN; k++) {
    pr[u][k] = pr[pr[u][k - 1]][k - 1];
  }
  sbtr[u] = 1;
  for (int v : edg[u]) {
    if (v == p) continue;
    dfs(v, u);
    sbtr[u] += sbtr[v];
  }
}
int getLCA(int u, int v) {
  if (lvl[u] < lvl[v]) swap(u, v);
  for (int k = LOGN - 1; k >= 0; k--) {
    if (lvl[u] - (1 << k) >= lvl[v]) {
      u = pr[u][k];
    }
  }
  if (u == v) return u;
  for (int k = LOGN - 1; k >= 0; k--) {
    if (pr[u][k] != pr[v][k]) {
      u = pr[u][k];
      v = pr[v][k];
    }
  }
  return pr[u][0];
}
int distance(int u, int v) { return lvl[u] + lvl[v] - 2 * lvl[getLCA(u, v)]; }
void HLD(int u, int p) {
  chainIdx[u] = chainCnt;
  flatIdx[u] = flatCnt;
  flat[flatCnt] = u;
  flatCnt++;
  int biggie = -1, mx = 0;
  for (int v : edg[u]) {
    if (v == p) continue;
    if (mx < sbtr[v]) {
      mx = sbtr[v];
      biggie = v;
    }
  }
  if (biggie == -1) return;
  HLD(biggie, u);
  for (int v : edg[u]) {
    if (v == p || v == biggie) continue;
    chainCnt++;
    chainHead[chainCnt] = v;
    HLD(v, u);
  }
}
void upSegments(int l, int u, vector<pair<int, int> >& vp) {
  while (chainIdx[l] != chainIdx[u]) {
    int uhead = chainHead[chainIdx[u]];
    vp.push_back(pair<int, int>(flatIdx[uhead], flatIdx[u]));
    u = pr[uhead][0];
  }
  if (l != u) {
    vp.push_back(pair<int, int>(flatIdx[l] + 1, flatIdx[u]));
  }
}
vector<pair<int, int> > getChainSegments(int u, int v) {
  int l = getLCA(u, v);
  vector<pair<int, int> > rt;
  rt.push_back(pair<int, int>(flatIdx[l], flatIdx[l]));
  if (u == v) return rt;
  upSegments(l, u, rt);
  upSegments(l, v, rt);
  return rt;
}
void performHLD(int root) {
  dfs(root, 0);
  chainCnt = 0;
  flatCnt = 0;
  chainHead[0] = root;
  HLD(root, 0);
}
struct BIT {
  int a[MAXN];
  void add(int idx, int v) {
    while (idx < MAXN) {
      a[idx] += v;
      idx += idx & (-idx);
    }
  }
  int ask(int idx) {
    int ans = 0;
    while (idx > 0) {
      ans += a[idx];
      idx -= idx & (-idx);
    }
    return ans;
  }
} fen;
int deg[MAXN];
int initial[MAXN];
int from[MAXN];
int n;
void pre() {
  priority_queue<int> q;
  for (int i = 1; i <= n; i++) {
    if (edg[i].size() == 1) q.push(-i);
    deg[i] = edg[i].size();
  }
  int now = 0;
  while (!q.empty()) {
    int u = -q.top();
    q.pop();
    initial[u] = ++now;
    for (int v : edg[u]) {
      deg[v]--;
      if (deg[v] == 1) q.push(-v);
    }
  }
}
int last;
int color;
BIT adi;
map<int, int> mp;
int first[MAXN];
void update(int l, int r) {
  auto it = mp.lower_bound(l);
  if (it == mp.end() || it->first > l) {
    it--;
    assert(first[it->first] > 1);
    if (it->second <= r) {
      fen.add(first[it->first], -(it->second - l + 1));
      it->second = l - 1;
      it++;
    } else {
      fen.add(first[it->first], -(r - l + 1));
      int x = it->second;
      it->second = l - 1;
      first[r + 1] = first[it->first];
      mp[r + 1] = x;
      it = mp.end();
    }
  }
  while (it != mp.end() && it->first <= r) {
    if (it->second > r) {
      assert(first[it->first] > 1);
      fen.add(first[it->first], -(r - it->first + 1));
      first[r + 1] = first[it->first];
      int x = it->second;
      mp.erase(it);
      mp[r + 1] = x;
      break;
    }
    if (first[it->first] == 1) {
      adi.add(initial[flat[it->first]], -1);
    }
    fen.add(first[it->first], -(it->second - it->first + 1));
    it = mp.erase(it);
  }
  mp[l] = r;
  first[l] = color;
}
int query(int idx) {
  auto it = mp.upper_bound(idx);
  it--;
  return first[it->first];
}
void change(int u) {
  if (last == u) return;
  ++color;
  vector<pair<int, int> > vp = getChainSegments(last, u);
  int sm = 0;
  for (pair<int, int> pr : vp) {
    update(pr.first, pr.second);
    sm += pr.second - pr.first + 1;
  }
  fen.add(color, sm);
  from[color] = last;
  last = u;
}
int when(int u) {
  int c = query(flatIdx[u]);
  if (c == 1) {
    return adi.ask(initial[u]);
  }
  int ans = fen.ask(c - 1);
  return ans + distance(from[c], u) + 1;
}
void askAll() {
  for (int i = 1; i <= n; i++) {
    cout << i << " -> " << when(i) << endl;
  }
  cout << endl;
  for (pair<int, int> pr : mp) {
    cout << "(" << pr.first << "," << pr.second << ")"
         << ":" << first[pr.first] << " ";
  }
  cout << endl;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int q;
  cin >> n >> q;
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    edg[u].push_back(v);
    edg[v].push_back(u);
  }
  pre();
  for (int i = 1; i <= n; i++) adi.add(i, 1);
  performHLD(1);
  fen.add(1, n);
  for (int i = 0; i < n; i++) {
    mp[i] = i;
    first[i] = 1;
  }
  last = n;
  color = 1;
  while (q--) {
    string s;
    cin >> s;
    if (s == "up") {
      int v;
      cin >> v;
      change(v);
    } else if (s == "when") {
      int v;
      cin >> v;
      cout << when(v) << "\n";
    } else {
      int v, u;
      cin >> v >> u;
      cout << (when(u) < when(v) ? u : v) << "\n";
    }
  }
  return 0;
}
