Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes indexed from 1 to n. We will also consider the first node to be initially painted red, and the other nodes — to be painted blue.

The distance between two tree nodes v and u is the number of edges in the shortest path between v and u.

Xenia needs to learn how to quickly execute queries of two types:

  1. paint a specified blue node in red; 
  2. calculate which red node is the closest to the given one and print the shortest distance to the closest red node. 



Your task is to write a program which will execute the described queries.

Input

The first line contains two integers n and m (2 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of nodes in the tree and the number of queries. Next n - 1 lines contain the tree edges, the i-th line contains a pair of integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — an edge of the tree.

Next m lines contain queries. Each query is specified as a pair of integers ti, vi (1 ≤ ti ≤ 2, 1 ≤ vi ≤ n). If ti = 1, then as a reply to the query we need to paint a blue node vi in red. If ti = 2, then we should reply to the query by printing the shortest distance from some red node to node vi.

It is guaranteed that the given graph is a tree and that all queries are correct.

Output

For each second type query print the reply in a single line.

Examples

Input

5 4
1 2
2 3
2 4
4 5
2 1
2 5
1 2
2 5


Output

0
3
2
#include <bits/stdc++.h>
using namespace std;
template <typename T, bool maximum_mode = false>
struct RMQ {
  int n = 0, levels = 0;
  vector<T> values;
  vector<vector<int>> range_low;
  RMQ(const vector<T> &_values = {}) {
    if (!_values.empty()) build(_values);
  }
  static int largest_bit(int x) { return 31 - __builtin_clz(x); }
  int better_index(int a, int b) const {
    return (values[a] < values[b]) ^ maximum_mode ? a : b;
  }
  void build(const vector<T> &_values) {
    values = _values;
    n = values.size();
    levels = largest_bit(n) + 1;
    range_low.resize(levels);
    for (int k = 0; k < levels; k++) range_low[k].resize(n - (1 << k) + 1);
    for (int i = 0; i < n; i++) range_low[0][i] = i;
    for (int k = 1; k < levels; k++)
      for (int i = 0; i <= n - (1 << k); i++)
        range_low[k][i] = better_index(range_low[k - 1][i],
                                       range_low[k - 1][i + (1 << (k - 1))]);
  }
  int query_index(int a, int b) const {
    assert(0 <= a && a < b && b <= n);
    int level = largest_bit(b - a);
    return better_index(range_low[level][a],
                        range_low[level][b - (1 << level)]);
  }
  T query_value(int a, int b) const { return values[query_index(a, b)]; }
};
struct LCA {
  int n = 0;
  vector<vector<int>> adj;
  vector<int> parent, depth, subtree_size;
  vector<int> euler, first_occurrence;
  vector<int> tour_start, tour_end, tour_list;
  vector<int> heavy_root;
  RMQ<int> rmq;
  LCA(int _n = 0) { init(_n); }
  LCA(const vector<vector<int>> &_adj) { init(_adj); }
  void init(int _n) {
    n = _n;
    adj.assign(n, {});
    parent.resize(n);
    depth.resize(n);
    subtree_size.resize(n);
    first_occurrence.resize(n);
    tour_start.resize(n);
    tour_end.resize(n);
    tour_list.resize(n);
    heavy_root.resize(n);
  }
  void init(const vector<vector<int>> &_adj) {
    init(_adj.size());
    adj = _adj;
  }
  void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  void dfs(int node, int par) {
    parent[node] = par;
    depth[node] = par < 0 ? 0 : depth[par] + 1;
    subtree_size[node] = 1;
    if (par >= 0)
      adj[node].erase(find(adj[node].begin(), adj[node].end(), par));
    for (int &child : adj[node]) {
      dfs(child, node);
      subtree_size[node] += subtree_size[child];
      if (subtree_size[child] > subtree_size[adj[node].front()])
        swap(child, adj[node].front());
    }
  }
  int tour;
  void tour_dfs(int node, bool heavy) {
    heavy_root[node] = heavy ? heavy_root[parent[node]] : node;
    first_occurrence[node] = euler.size();
    euler.push_back(node);
    tour_list[tour] = node;
    tour_start[node] = tour++;
    bool heavy_child = true;
    for (int child : adj[node]) {
      tour_dfs(child, heavy_child);
      euler.push_back(node);
      heavy_child = false;
    }
    tour_end[node] = tour;
  }
  void build() {
    parent.assign(n, -1);
    for (int i = 0; i < n; i++)
      if (parent[i] < 0) dfs(i, -1);
    tour = 0;
    for (int i = 0; i < n; i++)
      if (parent[i] < 0) {
        tour_dfs(i, false);
        euler.push_back(-1);
      }
    assert((int)euler.size() == 2 * n);
    vector<int> euler_depths;
    for (int node : euler)
      euler_depths.push_back(node < 0 ? node : depth[node]);
    rmq.build(euler_depths);
  }
  int get_lca(int a, int b) const {
    a = first_occurrence[a];
    b = first_occurrence[b];
    if (a > b) swap(a, b);
    return euler[rmq.query_index(a, b + 1)];
  }
  bool is_ancestor(int a, int b) const {
    return tour_start[a] <= tour_start[b] && tour_start[b] < tour_end[a];
  }
  bool on_path(int x, int a, int b) const {
    int anc = get_lca(a, b);
    return is_ancestor(anc, x) && (is_ancestor(x, a) || is_ancestor(x, b));
  }
  int get_dist(int a, int b) const {
    return depth[a] + depth[b] - 2 * depth[get_lca(a, b)];
  }
  int child_ancestor(int a, int b) const {
    assert(a != b);
    assert(is_ancestor(a, b));
    int child =
        euler[rmq.query_index(first_occurrence[a], first_occurrence[b] + 1) +
              1];
    assert(is_ancestor(child, b));
    return child;
  }
};
const int INF = 1e9 + 5;
struct edge {
  int node;
  edge(int _node = -INF) : node(_node) {}
};
int N, M;
vector<vector<edge>> adj;
vector<int> centroid_parent;
vector<int> closest;
LCA lca;
void add_edge(int a, int b) {
  assert(a != b);
  adj[a].emplace_back(b);
  adj[b].emplace_back(a);
}
void erase_edge(int from, int to) {
  for (edge &e : adj[from])
    if (e.node == to) {
      swap(e, adj[from].back());
      adj[from].pop_back();
      return;
    }
  assert(false);
}
vector<int> depth;
vector<int> subtree_size;
vector<int> node_list;
int dfs(int node, int parent = -INF) {
  if (parent < 0) node_list.clear();
  depth[node] = parent < 0 ? 0 : depth[parent] + 1;
  subtree_size[node] = 1;
  node_list.push_back(node);
  for (edge &e : adj[node])
    if (e.node != parent) subtree_size[node] += dfs(e.node, node);
  return subtree_size[node];
}
int centroid(int root) {
  int n = dfs(root);
  bool found;
  do {
    found = false;
    for (edge &e : adj[root])
      if (subtree_size[e.node] < subtree_size[root] &&
          2 * subtree_size[e.node] >= n) {
        root = e.node;
        found = true;
        break;
      }
  } while (found);
  return root;
}
void centroid_decomposition(int root) {
  root = centroid(root);
  for (int node : node_list)
    if (node != root) centroid_parent[node] = root;
  for (edge &e : adj[root]) erase_edge(e.node, root);
  for (edge &e : adj[root]) centroid_decomposition(e.node);
}
void paint_red(int node) {
  int original = node;
  while (node >= 0) {
    closest[node] = min(closest[node], lca.get_dist(node, original));
    node = centroid_parent[node];
  }
}
int find_closest(int node) {
  int original = node, best = INF;
  while (node >= 0) {
    best = min(best, closest[node] + lca.get_dist(node, original));
    node = centroid_parent[node];
  }
  return best;
}
int main() {
  scanf("%d %d", &N, &M);
  adj.assign(N, {});
  depth.resize(N);
  subtree_size.resize(N);
  centroid_parent.assign(N, -1);
  lca.init(N);
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    a--;
    b--;
    add_edge(a, b);
    lca.add_edge(a, b);
  }
  centroid_decomposition(0);
  lca.build();
  closest.assign(N, INF);
  paint_red(0);
  for (int i = 0; i < M; i++) {
    int type, node;
    scanf("%d %d", &type, &node);
    node--;
    if (type == 1) {
      paint_red(node);
    } else if (type == 2) {
      printf("%d\n", find_closest(node));
    } else {
      assert(false);
    }
  }
}
