#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline long long rand(long long x, long long y) {
  return rng() % (y + 1 - x) + x;
}
string inline to_string(char c) {
  string second(1, c);
  return second;
}
template <typename T>
inline T gcd(T a, T b) {
  return a == 0 ? llabs(b) : gcd(b % a, a);
}
using ll = long long;
using ld = long double;
using pi = pair<ll, ll>;
using spi = pair<pi, ll>;
using dpi = pair<pi, pi>;
ll n, q, fw[(400006)];
vector<int> v[(400006) / 2];
void update(int x, ll nval) {
  for (; x < (400006); x += x & (-x)) fw[x] += nval;
}
ll sum(int x) {
  ll res = 0;
  for (; x; x -= x & (-x)) res += fw[x];
  return res;
}
int st[(400006)], co, p[(400006)], head[(400006)], heavy[(400006)],
    depth[(400006)], bck[(400006)], mx, now = 1;
map<pi, ll> mp[(400006) / 2];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> q;
  for (ll i = 0; i <= ll(n - 2); ++i) {
    ll a, b;
    cin >> a >> b;
    v[a].emplace_back(b), v[b].emplace_back(a);
  }
  function<ll(ll, ll)> dfs = [&](ll x, ll par) {
    p[x] = par;
    ll sz = 1, mx_sz = 0;
    for (auto i : v[x])
      if (i ^ par) {
        depth[i] = depth[x] + 1;
        ll c_sz = dfs(i, x);
        sz += c_sz;
        if (mx_sz < c_sz) mx_sz = c_sz, heavy[x] = i;
      }
    return sz;
  };
  function<void(ll, ll, ll)> hld = [&](ll x, ll p, ll h) {
    st[x] = co++, head[x] = h;
    if (heavy[x]) hld(heavy[x], x, h);
    for (auto i : v[x])
      if (i != p && i != heavy[x]) {
        hld(i, x, i);
      }
  };
  dfs(1, 1), hld(1, 1, 1);
  auto dist = [&](ll x, ll y) {
    ll ans = 0;
    for (; head[x] ^ head[y]; x = p[head[x]]) {
      if (depth[head[x]] < depth[head[y]]) swap(x, y);
      ans += st[x] - st[head[x]] + 1;
    }
    ans += max(st[x], st[y]) - min(st[x], st[y]) + 1;
    return ans;
  };
  auto re = [&](ll c, ll x) { update(c, -x); };
  auto proc = [&](ll x, ll a, ll b) {
    while (1) {
      auto it = mp[x].lower_bound(pi(a, 0));
      if (it == mp[x].end() || it->first.second > b) break;
      re(it->second, it->first.second - it->first.first + 1);
      mp[x].erase(it);
    }
    auto it = mp[x].lower_bound(pi(a, 0));
    if (it != mp[x].end() && it->first.first <= b) {
      assert(it->first.second > b);
      spi val = *it;
      re(val.second, b - val.first.first + 1);
      mp[x].erase(it);
      val.first.first = b + 1;
      mp[x].insert(val);
      it = mp[x].lower_bound(pi(a, 0));
    }
    if (it != mp[x].begin()) {
      --it;
      if (it->first.second >= a) {
        spi val = *it;
        re(val.second, val.first.second - a + 1);
        mp[x].erase(it);
        val.first.second = a - 1;
        mp[x].insert(val);
      }
    }
  };
  auto up = [&](ll node) {
    bck[++mx] = now;
    update(mx, dist(now, node));
    ll x = now, y = node;
    for (; head[x] ^ head[y]; x = p[head[x]]) {
      if (depth[head[x]] < depth[head[y]]) swap(x, y);
      proc(head[x], st[head[x]], st[x]);
      mp[head[x]][pi(st[head[x]], st[x])] = mx;
    }
    proc(head[x], min(st[x], st[y]), max(st[x], st[y]));
    mp[head[x]][pi(min(st[x], st[y]), max(st[x], st[y]))] = mx;
    now = node;
  };
  auto when = [&](ll x) {
    auto c = mp[head[x]].upper_bound(pi(st[x], ((long long)1e18)));
    assert(c != mp[head[x]].begin()), --c;
    return sum(c->second - 1) + dist(bck[c->second], x);
  };
  for (ll i = 1; i <= ll(n); ++i) up(i);
  while (q--) {
    string op;
    cin >> op;
    if (op == "up") {
      ll x;
      cin >> x;
      up(x);
    } else if (op == "when") {
      ll x;
      cin >> x;
      cout << when(x) << '\n';
    } else {
      ll x, y;
      cin >> x >> y;
      cout << (when(x) < when(y) ? x : y) << '\n';
    }
  }
}
