/*
 		Resilience is the greatest of all virtues.
 		Code by rajiv
*/
/*
 Problem : http://codeforces.com/contest/342/problem/E
 Tags : Centroid Decomposition, LCA
*/

 #include <iostream>
 #include <cstring>
 #include <vector>
 #include <map>
 #include <set>
 #include <stack>
 #include <queue>
 #include <deque>
 #include <sstream>
 #include <iomanip>
 #include <cassert>
 #include <sys/time.h>
 #include <algorithm>
 #include <bitset>
 #include <cmath>
 #include <functional>
 #include <cmath>

 using namespace std ;

 #define xx first
 #define yy second
 #define ll long long
 #define ld long double
 #define el (char)0x0A
 #define sp " "
 #define pb push_back
 #define mp make_pair
 #define all(x) (x).begin(),(x).end()
 #define clr(x) memset((x),0,sizeof(x))
 #define uint unsigned int
 #define abs(x) ((x<=0)?(-x):(x))
 #define CASET  int t;cin>>t;while(t--)
 #define FORN(i,x,y) for(int i=x;i<y;i++)
 #define MAXN 100005
 #define INF 10000000010
 #define MOD 1000000007
 #define last_set_bit(x) log2((x)&(-x))
 #define add(x,y) (x)=((x)+(y))%MOD
 #define PI 3.141592653589793

 typedef pair<int,int> PII ; typedef vector<int> VI ; typedef vector<vector<int> > VVI ; typedef vector<bool> VB ; typedef vector<string> VS ;
 typedef map<int,int> MII ; typedef map<int,VI > MIV ; typedef set<int> SI ; typedef set<PII > SPII ; typedef vector<PII > VPII ; typedef vector<VPII > VVPII ;
 int n  , m ;
 const int N = 100050 ;
 const int LN = 18 ;
 int size[N] ;
  int  level[N] , Anc[N+2][LN+1]  ;
  VI adj[N] ;

 void dfs1(int src, int pa, int lev){
     level[src] = lev ;
     Anc[src][0] = pa ;
     for(auto it : adj[src]){
         if (it != pa){
             dfs1(it,src,lev+1) ;
         }
     }
 }
 void precompute(){
     dfs1(0,-1,0) ;
     for(int j = 1 ; j < LN  ; j++){
         for(int i = 0 ; i < N ; i++){
             if (Anc[i][j-1] != -1){
                 Anc[i][j] = Anc[Anc[i][j-1]][j-1] ;
             }
         }
     }
 }
 int lca(int x , int y){
     if (x == y) return x ;
     if (level[x] < level[y])
        swap(x,y) ;
     int diff = level[x] - level[y] ;
     for(int i = 0 ; i <= 20 ; i++){
         if ((diff>>i)&1){
             x = Anc[x][i] ;
         }
     }
     if (x == y) return x ;
     for(int j = LN ; j>=0 ; j--){
         if (Anc[x][j] != -1 && Anc[x][j] != Anc[y][j]){
             x = Anc[x][j] ;
             y = Anc[y][j] ;
         }
     }
     return Anc[x][0] ;
 }
 int dist(int x , int y){
     return level[x]+level[y]-2*level[lca(x,y)] ;
 }
bool marked[N] ;
int par[N] ;
void dfs2(int x , int pa){
    size[x] = 1 ;
    for(auto it : adj[x]){
        if (it != pa && !marked[it]){
            dfs2(it,x) ;
            size[x] += size[it] ;
        }
    }
}
 int centroid(int x , int pa, int blocksize){
     for(auto it : adj[x]){
         if (!marked[it] && it != pa && size[it]>blocksize){
             return centroid(it,x,blocksize) ;
         }
     }
     return x ;
 }
 void decompose(int x, int pa){

    dfs2(x,pa) ;
    x = centroid(x,pa,size[x]/2) ;
    marked[x] = true ;
    //cout << x << sp << pa << el ;
    par[x] = pa ;
    for(auto it : adj[x]){
        if (!marked[it]){
            decompose(it,x) ;
        }
    }
 }
 int ans[N] ;
 void Paint(int x){
     int y = x ;
     while (y != -1){
         ans[y] = min(ans[y],dist(y,x)) ;
         y = par[y] ;
     }
 }

int Query(int x){
    int y = x ;
    int mn = ans[y] ;
    while (y != -1){
        mn = min(mn,ans[y]+dist(x,y)) ;
        y = par[y] ;
    }
    return mn ;
}

int main(){
    int  n , m , x , y ;
    memset(ans,63,sizeof ans) ;
    cin >> n >> m ;
    FORN(i,0,n-1){
        cin >> x >> y ; x-- ; y-- ;
        adj[x].pb(y) ;
        adj[y].pb(x) ;
    }
    Anc[0][0] = -1  ;
    precompute() ;
    decompose(0,-1) ;
    memset(marked,false,sizeof marked) ;
    int root = centroid(0,-1,n) ;
    par[root] = -1 ;
    for(int i = 0 ;i < n ; i++){
        ans[i] = dist(i,0) ;
    }

     while (m--){
        int type, u ;
        cin >> type >> u ; u-- ;

        if (type==1){
            Paint(u) ;
        }
        else{
            cout << Query(u) << el ;
        }
    }
    return 0 ;
}


/*
 		Resilience is the greatest of all virtues.
 		Code by rajiv
 */
// Problem : http://codeforces.com/contest/342/problem/E
// Tags : LCA, Centroid Decomposition

 #include <iostream>
 #include <cstring>
 #include <vector>
 #include <map>
 #include <set>
 #include <stack>
 #include <queue>
 #include <deque>
 #include <sstream>
 #include <iomanip>
 #include <cassert>
 #include <sys/time.h>
 #include <algorithm>
 #include <bitset>
 #include <cmath>
 #include <functional>
 #include <cmath>

 using namespace std ;

 #define xx first
 #define yy second
 #define ll long long
 #define ld long double
 #define el (char)0x0A
 #define sp " "
 #define pb push_back
 #define mp make_pair
 #define all(x) (x).begin(),(x).end()
 #define clr(x) memset((x),0,sizeof(x))
 #define uint unsigned int
 #define abs(x) ((x<=0)?(-x):(x))
 #define CASET  int t;cin>>t;while(t--)
 #define FORN(i,x,y) for(int i=x;i<y;i++)
 #define MAXN 100005
 #define INF 10000000010
 #define MOD 1000000007
 #define last_set_bit(x) log2((x)&(-x))
 #define add(x,y) (x)=((x)+(y))%MOD
 #define PI 3.141592653589793

 typedef pair<int,int> PII ; typedef vector<int> VI ; typedef vector<vector<int> > VVI ; typedef vector<bool> VB ; typedef vector<string> VS ;
 typedef map<int,int> MII ; typedef map<int,VI > MIV ; typedef set<int> SI ; typedef set<PII > SPII ; typedef vector<PII > VPII ; typedef vector<VPII > VVPII ;
 int n  , m ;
 const int N = MAXN ;
 const int LN = ceil(log2(MAXN)) ;

 int A[100050][50] ;
 int depth[MAXN] ;
int subsize[MAXN] ;
 void dfs(int src, VVI& adj, VB& vis, int depp){
    vis[src] = true ;
    depth[src] = depp ;

    for(auto it : adj[src]){
        if (!vis[it]){
            A[it][0] = src ;
            dfs(it,adj,vis,depp+1) ;

        }
    }
 }
 void preprocess(){
     for(int j = 1 ; j <= ceil(log2(n)) ; j++){
         for(int i = 0 ; i < n ; i++){
                if (A[i][j-1] == -1){
                    A[i][j] = -1 ;
                }
                else{
                    A[i][j] = A[A[i][j-1]][j-1] ;
                }
         }
     }
 }
 int lca(int x, int y){
     if (depth[x] < depth[y]){
         return lca(y,x) ;
     }
     if (x == y) return x ;
     // Do this until 'x' reaches the same level as 'y' ;
     int ln = ceil(log2(n)) ;
     for(int j = ln  ; j>=0 ; j--){
         if (A[x][j]!=-1 && depth[x]-(1<<j) >= depth[y]){
             x = A[x][j] ;
         }
     }
     if (x == y) return x ;
     for(int j = ln ; j >= 0 ; j--){
         if (A[x][j] != -1 && A[x][j] != A[y][j]){
             x = A[x][j] ;
             y = A[y][j] ;
         }
     }
     return A[x][0] ;
 }
 bool centroidMarked[MAXN] ;

 void dfs2(int src, VVI& adj, int pa){
     subsize[src] = 1;
     for(auto it : adj[src]){
         if (it != pa && !centroidMarked[it]){
             dfs2(it,adj,src) ;
             subsize[src] += subsize[it] ;
         }
     }
 }
 int centroid(int x , VVI& adj, int pa){
     for(auto it : adj[x]){
        if (!centroidMarked[it] && it != pa && subsize[it]>subsize[x]/2){
            return centroid(it,adj,x) ;
        }
     }
     return x ;
 }
int par[MAXN] ; int root ;
 void decompose(int x, VVI& adj, int pa){
     dfs2(x,adj,pa) ;
     x = centroid(x,adj,pa) ;
     centroidMarked[x] = true ;
     par[x] = pa ;
     for(auto it : adj[x]){
         if (!centroidMarked[it] ){
             decompose(it,adj,x) ;
         }
     }
 }
 int dist(int x , int y){
     return depth[x]+depth[y]-2*depth[lca(x,y)] ;
 }

 int ans[MAXN] ;
 void Paint(int x){
    int u = x ;
    while (u != -1){
        ans[u] = min(ans[u],dist(u,x)) ;
        u = par[u] ;
    }
 }
 int Query(int x){
     int u = x;
     int mn = ans[u] ;
     while (u != -1){
         mn = min(mn,ans[u]+dist(u,x)) ;
         u = par[u] ;
     }
     return mn ;
 }

 int main(){
 	ios_base::sync_with_stdio(false) ;
 	cin.tie(nullptr) ;
    cin >> n >> m ;
    VVI adj(n,VI()) ;
    int x , y ;
    FORN(i,0,n-1){
        cin >> x >> y ; x-- ; y-- ;
        adj[x].pb(y) ;
        adj[y].pb(x) ;
    }
    VB vis(MAXN,false) ;
    A[0][0] = -1 ;
    memset(A,-1,sizeof A) ;
    dfs(0,adj,vis,0) ;
    preprocess() ;
    decompose(0,adj,-1) ;
    memset(centroidMarked,false,sizeof centroidMarked) ;
    root = centroid(0,adj,-1) ;
    par[root] = -1 ;
    int type , u ;
    for(int i = 0 ; i < n ; i++){
        ans[i] = dist(i,0) ;
    }

    while (m--){
        cin >> type >> u ; u-- ;
        if (type == 1){
            Paint(u) ;
        }
        else{
            cout << Query(u) << el ;
        }
    }
    return 0 ;
 }


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    int lg = 25;
    while(v)
    {
        assert(lg);
        lg--;

        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    int lg = 25;
    while(v)
    {
        assert(lg);
        lg--;

        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    cerr << par[1] << endl;

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        if(low == high)
        {
            op[pos] = mn[pos] = INF;
            return;
        }

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        assert(!(l > high || r < low));
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e6 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        if(low == high)
        {
            op[pos] = mn[pos] = INF;
            return;
        }

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        assert(!(l > high || r < low));
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid ((low + high) >> 1)
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    int *op, *mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r <= mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l >= mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r <= mid)
            return query(pos * 2, low, mid, l, r);
        else if(l >= mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op = new int[n * 4];
        mn = new int[n * 4];
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[u].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[u].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    //assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

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

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    //assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        int mid = (low + high) / 2;
        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        int mid = (low + high) / 2;

        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        int mid = (low + high) / 2;
        push(pos, low, high);
        if(r <= mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l >= mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        int mid = (low + high) / 2;
        push(pos, low, high);
        if(r <= mid)
            return query(pos * 2, low, mid, l, r);
        else if(l >= mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[u].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[u].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    //assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

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

*/


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define mp make_pair
#define pb push_back
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

int n, Q;
vector <int> nb[N];

bool vis[N];
int link[N], tree_sz[N], cnt_vert;

void pre_dfs(int v, int par = -1)
{
    cnt_vert++;
    tree_sz[v] = 1;
    for(int u: nb[v])
    {
        if(!vis[u] && u != par)
        {
            pre_dfs(u, v);
            tree_sz[v] += tree_sz[u];
        }
    }
}

int centroid(int v, int par = -1)
{
    for(int u: nb[v])
    {
        if(!vis[u] && u != par && tree_sz[u] > cnt_vert / 2)
            return centroid(u, v);
    }

    return v;
}

void decompose(int v, int par = -1)
{
    cnt_vert = 0;
    pre_dfs(v);

    int centr = centroid(v);
    link[centr] = par;

    vis[centr] = true;
    for(int u: nb[centr])
    {
        if(!vis[u])
            decompose(u, centr);
    }
    vis[centr] = false;
}

int from[N], to[N], timer;
int dep[N];
int sparse[N][30];

void DFS_LCA(int v, int par = 0)
{
    from[v] = to[v] = ++timer;
    sparse[v][0] = par;
    dep[v] = dep[par] + 1;

    for(int u: nb[v])
    {
        if(u != par)
        {
            DFS_LCA(u, v);
            to[v] = max(to[v], to[u]);
        }
    }
}

void calc_sparse()
{
    for(int i = 1; i < 30; i++)
        for(int j = 1; j <= n; j++)
            sparse[j][i] = sparse[sparse[j][i - 1]][i - 1];
}

bool in_subtree(int u, int v)
{
    return (from[u] <= from[v] && to[u] >= from[v]);
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v])
        swap(u, v);

    if(in_subtree(u, v))
        return u;

    for(int i = 29; i >= 0; i--)
    {
        if(!in_subtree(sparse[u][i], v))
            u = sparse[u][i];
    }

    return sparse[u][0];
}

int dist(int u, int v)
{
    return dep[u] + dep[v] - 2 * dep[LCA(u, v)];
}

int ans[N];

void paint(int v)
{
    int u = v;
    while(u != -1)
    {
        ans[u] = min(ans[u], dist(u, v));
        u = link[u];
    }
}

int query(int v)
{
    int res = INF;

    int u = v;
    while(u != -1)
    {
        res = min(res, ans[u] + dist(u, v));
        u = link[u];
    }

    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int i;
    int t, u, v;

    cin >> n >> Q;
    for(i = 1; i < n; i++)
    {
        cin >> u >> v;

        nb[u].pb(v);
        nb[v].pb(u);
    }

    DFS_LCA(1, 1);
    calc_sparse();

    decompose(1);

    for(i = 1; i <= n; i++)
        ans[i] = INF;

    paint(1);
    while(Q--)
    {
        cin >> t >> v;

        if(t == 1)
        {
            paint(v);
        }
        if(t == 2)
        {
            cout << query(v) << endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid ((low + high) >> 1)
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    int *op, *mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r <= mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r <= mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op = new int[n * 4];
        mn = new int[n * 4];
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[u].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[u].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    //assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

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

*/


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

int n, q;
vector <int> nb[N];

int sparse[N][22], low[N], high[N], timer, dep[N];
int DFS(int v, int par = 1)
{
    dep[v] = dep[par] + 1;
    sparse[v][0] = par;
    low[v] = high[v] = ++timer;
    for(auto u: nb[v])
        if(u != par)
        {
            DFS(u, v);
            high[v] = max(high[v], high[u]);
        }
}

bool in_subtree(int u, int v)
{
    return (low[u] <= low[v] && high[u] >= high[v]);
}

int LCA(int u, int v)
{
    if(dep[u] > dep[u])
        swap(u, v);
    if(in_subtree(u, v))
        return u;

    for(int i = 21; i >= 0; i--)
    {
        if(!in_subtree(sparse[u][i], v))
            u = sparse[u][i];
    }

    return sparse[u][0];
}

int dist(int u, int v)
{
    int lca = LCA(u, v);
    return (dep[u] + dep[v] - 2 * dep[lca]);
}

int cnt_vert, sz[N], vis[N];
int link[N];
void pre_DFS(int v, int par)
{
    sz[v] = 1;
    cnt_vert++;
    for(auto u: nb[v])
    {
        if(u != par && !vis[u])
        {
            pre_DFS(u, v);
            sz[v] += sz[u];
        }
    }
}

int centroid(int v, int par)
{
    for(auto u: nb[v])
        if(u != par && !vis[u] && sz[u] * 2 > cnt_vert)
                return centroid(u, v);
    return v;
}

void decompose(int v, int par = -1)
{
    cnt_vert = 0;
    pre_DFS(v, par);

    int centr = centroid(v, par);
    link[centr] = par;
    vis[centr] = true;
    for(auto u: nb[centr])
        if(!vis[u])
            decompose(u, centr);
}

int ans[N];
void paint(int v)
{
    int u = v;
    while(u != -1)
    {
        ans[u] = min(ans[u], dist(u, v));
        u = link[u];
    }
}

int query(int v)
{
    int res = INF, u = v;
    while(u != -1)
    {
        res = min(res, ans[u] + dist(u, v));
        u = link[u];
    }

    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int u, v, type;

    cin >> n >> q;
    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;

        nb[u].pb(v);
        nb[v].pb(u);
    }

    DFS(1);
    for(int j = 1; j <= 21; j++)
        for(int i = 1; i <= n; i++)
            sparse[i][j] = sparse[sparse[i][j - 1]][j - 1];

    decompose(1);

    for(int i = 1; i <= n; i++)
        ans[i] = INF;
    paint(1);
    while(q--)
    {
        cin >> type >> v;

        if(type == 1)
            paint(v);
        else
            cout << query(v) << endl;
    }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define mp make_pair
#define pb push_back
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

int n, Q;
vector <int> nb[N];

bool vis[N];
int link[N], tree_sz[N], cnt_vert;

void pre_dfs(int v, int par = -1)
{
    cnt_vert++;
    tree_sz[v] = 1;
    for(int u: nb[v])
    {
        if(!vis[u] && u != par)
        {
            pre_dfs(u, v);
            tree_sz[v] += tree_sz[u];
        }
    }
}

int centroid(int v, int par = -1)
{
    for(int u: nb[v])
    {
        if(!vis[u] && u != par && tree_sz[u] > cnt_vert / 2)
            return centroid(u, v);
    }

    return v;
}

void decompose(int v, int par = -1)
{
    cnt_vert = 0;
    pre_dfs(v);

    int centr = centroid(v);
    link[centr] = par;

    vis[centr] = true;
    for(int u: nb[centr])
    {
        if(!vis[u])
            decompose(u, centr);
    }
    vis[centr] = false;
}

int from[N], to[N], timer;
int dep[N];
int sparse[N][30];

void DFS_LCA(int v, int par = 0)
{
    from[v] = to[v] = ++timer;
    sparse[v][0] = par;
    dep[v] = dep[par] + 1;

    for(int u: nb[v])
    {
        if(u != par)
        {
            DFS_LCA(u, v);
            to[v] = max(to[v], to[u]);
        }
    }
}

void calc_sparse()
{
    for(int i = 1; i < 30; i++)
        for(int j = 1; j <= n; j++)
            sparse[j][i] = sparse[sparse[j][i - 1]][i - 1];
}

bool in_subtree(int u, int v)
{
    return (from[u] <= from[v] && to[u] >= from[v]);
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v])
        swap(u, v);

    if(in_subtree(u, v))
        return u;

    for(int i = 29; i >= 0; i--)
    {
        if(!in_subtree(sparse[u][i], v))
            u = sparse[u][i];
    }

    return sparse[u][0];
}

int dist(int u, int v)
{
    return dep[u] + dep[v] - 2 * dep[LCA(u, v)];
}

int ans[N];

void paint(int v)
{
    int u = v;
    while(u != -1)
    {
        ans[u] = min(ans[u], dist(u, v));
        u = link[u];
    }
}

int query(int v)
{
    int res = INF;

    int u = v;
    while(u != -1)
    {
        res = min(res, ans[u] + dist(u, v));
        u = link[u];
    }

    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int i;
    int t, u, v;

    cin >> n >> Q;
    for(i = 1; i < n; i++)
    {
        cin >> u >> v;

        nb[u].pb(v);
        nb[v].pb(u);
    }

    DFS_LCA(1);
    calc_sparse();

    decompose(1);

    for(i = 1; i <= n; i++)
        ans[i] = INF;

    paint(1);
    while(Q--)
    {
        cin >> t >> v;

        if(t == 1)
        {
            paint(v);
        }
        if(t == 2)
        {
            cout << query(v) << endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid (low + high) >> 1
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r < mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l > mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r < mid)
            return query(pos * 2, low, mid, l, r);
        else if(l > mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    int lg = 25;
    while(v)
    {
        assert(lg);
        lg--;

        tree[head[v]].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    int lg = 25;
    while(v)
    {
        assert(lg);
        lg--;

        res = min(res, tree[head[v]].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

3 2
0 1
1 2
1 2
2 3
2 3
3 4
1 2
2 3

*/


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define mp make_pair
#define pb push_back
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

int n, Q;
vector <int> nb[N];

bool vis[N];
int link[N], tree_sz[N], cnt_vert;

void pre_dfs(int v, int par = -1)
{
    cnt_vert++;
    tree_sz[v] = 1;
    for(int u: nb[v])
    {
        if(!vis[u] && u != par)
        {
            pre_dfs(u, v);
            tree_sz[v] += tree_sz[u];
        }
    }
}

int centroid(int v, int par = -1)
{
    for(int u: nb[v])
    {
        if(!vis[u] && u != par && tree_sz[u] > cnt_vert / 2)
            return centroid(u, v);
    }

    return v;
}

void decompose(int v, int par = -1)
{
    cnt_vert = 0;
    pre_dfs(v);

    int centr = centroid(v);
    link[centr] = par;

    vis[centr] = true;
    for(int u: nb[centr])
    {
        if(!vis[u])
            decompose(u, centr);
    }
    vis[centr] = false;
}

int from[N], to[N], timer;
int dep[N];
int sparse[N][30];

void DFS_LCA(int v, int par = -1)
{
    from[v] = to[v] = ++timer;
    sparse[v][0] = (par == -1) ? v : par;
    dep[v] = dep[par] + 1;

    for(int u: nb[v])
    {
        if(u != par)
        {
            DFS_LCA(u, v);
            to[v] = max(to[v], to[u]);
        }
    }
}

void calc_sparse()
{
    for(int i = 1; i < 30; i++)
        for(int j = 1; j <= n; j++)
            sparse[j][i] = sparse[sparse[j][i - 1]][i - 1];
}

bool in_subtree(int u, int v)
{
    return (from[u] <= from[v] && to[u] >= from[v]);
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v])
        swap(u, v);

    if(in_subtree(u, v))
        return u;

    for(int i = 29; i >= 0; i--)
    {
        if(!in_subtree(sparse[u][i], v))
            u = sparse[u][i];
    }

    return sparse[u][0];
}

int dist(int u, int v)
{
    return dep[u] + dep[v] - 2 * dep[LCA(u, v)];
}

int ans[N];

void paint(int v)
{
    int u = v;
    while(u != -1)
    {
        ans[u] = min(ans[u], dist(u, v));
        u = link[u];
    }
}

int query(int v)
{
    int res = INF;

    int u = v;
    while(u != -1)
    {
        res = min(res, ans[u] + dist(u, v));
        u = link[u];
    }

    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int i;
    int t, u, v;

    cin >> n >> Q;
    for(i = 1; i < n; i++)
    {
        cin >> u >> v;

        nb[u].pb(v);
        nb[v].pb(u);
    }

    DFS_LCA(1);
    calc_sparse();

    decompose(1);

    for(i = 1; i <= n; i++)
        ans[i] = INF;

    paint(1);
    while(Q--)
    {
        cin >> t >> v;

        if(t == 1)
        {
            paint(v);
        }
        if(t == 2)
        {
            cout << query(v) << endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#pragma gcc optimize ("O3")
#pragma gcc target ("sse4")
#define mid ((low + high) >> 1)
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9;

struct SegmentTree{

    int n;
    vector <int> op, mn;
    void build(int pos, int low, int high)
    {
        op[pos] = mn[pos] = INF;
        if(low == high)
            return;

        build(pos * 2, low, mid);
        build(pos * 2 + 1, mid + 1, high);
    }

    void push(int pos, int low, int high)
    {
        op[pos * 2] = min(op[pos * 2], op[pos]);
        op[pos * 2 + 1] = min(op[pos * 2 + 1], op[pos]);

        mn[pos * 2] = min(mn[pos * 2], op[pos] - 2 * mid);
        mn[pos * 2 + 1] = min(mn[pos * 2 + 1], op[pos] - 2 * high);
    }

    void set_min(int pos, int low, int high, int l, int r, int val)
    {
        if(l == low && r == high)
        {
            op[pos] = min(op[pos], val);
            mn[pos] = min(mn[pos], val - 2 * high);
            return;
        }

        push(pos, low, high);
        if(r <= mid)
            set_min(pos * 2, low, mid, l, r, val);
        else if(l >= mid)
            set_min(pos * 2 + 1, mid + 1, high, l, r, val);
        else
        {
            set_min(pos * 2, low, mid, l, mid, val);
            set_min(pos * 2 + 1, mid + 1, high, mid + 1, r, val);
        }

        mn[pos] = min(mn[pos * 2], mn[pos * 2 + 1]);
    }

    int query(int pos, int low, int high, int l, int r)
    {
        if(l == low && r == high)
            return mn[pos];

        push(pos, low, high);
        if(r <= mid)
            return query(pos * 2, low, mid, l, r);
        else if(l >= mid)
            return query(pos * 2 + 1, mid + 1, high, l, r);
        else
            return min(query(pos * 2, low, mid, l, mid), query(pos * 2 + 1, mid + 1, high, mid + 1, r));
    }

    int ask(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }

    int update(int l, int r, int val)
    {
        set_min(1, 0, n - 1, l, r, val);
    }

    void init(int _n)
    {
        n = _n;
        op.resize(4 * (n + 1));
        mn.resize(4 * (n + 1));
        build(1, 0, n - 1);
    }

}tree[N];

int n, m;
vector <int> nb[N];

int dep[N], sz[N], par[N], heavy_son[N];
void DFS(int v)
{
    dep[v] = dep[par[v]] + 1;
    sz[v] = 1;
    for(int u: nb[v])
    {
        if(u != par[v])
        {
            par[u] = v;
            DFS(u);
            sz[v] += sz[u];
            if(sz[u] > sz[heavy_son[v]])
                heavy_son[v] = u;
        }
    }
}

int head[N], len[N];
void HLD(int v, int h)
{
    head[v] = h; len[h]++;
    if(heavy_son[v])
        HLD(heavy_son[v], h);

    for(int u: nb[v])
        if(u != par[v] && u != heavy_son[v])
            HLD(u, u);
}

void paint(int v)
{
    int u = head[v], d = dep[v];
    while(v)
    {
        tree[u].update(0, dep[v] - dep[u], d);

        v = par[u];
        u = head[v];
    }
}

int ask(int v)
{
    int u = head[v], d = dep[v], res = INF;
    while(v)
    {
        res = min(res, tree[u].ask(0, dep[v] - dep[u]) - 2 * dep[u] + d);

        v = par[u];
        u = head[v];
    }
    return res;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int type, u, v;

    cin >> n >> m;

    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        nb[u].pb(v); nb[v].pb(u);
    }

    DFS(1);
    HLD(1, 1);

    for(int i = 1; i <= n; i++)
        if(head[i] == i)
            tree[i].init(len[i]);

    //assert(clock() / (double)CLOCKS_PER_SEC < 1.0);

    paint(1);
    while(m--)
    {
        cin >> type >> v;
        if(type == 1)
            paint(v);
        else
            cout << ask(v) << endl;
    }

    return 0;
}

/*

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

*/


#include <iostream>
#include <vector>

using namespace std;
#define endl "\n"

vector<vector<int> > adjlist;
vector<int> wt;
vector<bool> in_tree;
vector<int> cent_tree;

int dfs_centroid(int node, int parent, int ts) {
	int nn = node;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			if(wt[c] >= ts/2) {
				nn = c;
				break;
			}
		}
	}
	if(nn != node)
		return dfs_centroid(nn, node, ts);
	else
		return nn;
}

int dfs_wt(int node, int parent) {
	wt[node]=0;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			dfs_wt(c, node);
			wt[node] += wt[c] + 1;
		}
	}
}

void build_centroid_tree(int node, int parent) {
	int centroid = dfs_centroid(node, parent, wt[node]+1);
	in_tree[centroid]=true;
	cent_tree[centroid]=parent;

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(wt[c] > wt[centroid]) {
			dfs_wt(c,centroid);
		}
	}

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(!in_tree[c])
			build_centroid_tree(c,centroid);
	}

}

int main() {
	std::ios::sync_with_stdio(false);
	int n,m,q; cin>>n>>q; m=n-1;
	adjlist.resize(n+1);
	cent_tree.resize(n+1,0);
	in_tree.resize(n+1, 0);
	wt.resize(n+1, 0);

	for(int i=1;i<=m;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	dfs_wt(1,0);
	build_centroid_tree(1,0);

	vector<int> dist(n+1);
	for(int i=0;i<dist.size();i++)dist[i]=-1;

	int b=1,d=0;
	while(b!=0) {
		dist[b]=d++;
		b=cent_tree[b];
	}

	for(int i=0;i<q;i++) {
		int a,b; cin>>a>>b;
		if(a==1) {
			int d=0;
			while(b!=0) {
				if(dist[b]==-1)dist[b]=d++;
				else dist[b]=min(dist[b],d++);
				b=cent_tree[b];
			}
		}
		else {
			int d=0;
			while(dist[b]==-1) {
				b=cent_tree[b];
				d++;
			}
			cout<<d+dist[b]<<endl;
		}
	}

}


#include <iostream>
#include <vector>

using namespace std;
#define endl "\n"
vector<int> parent;

void find_weights(int node, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool> & in_centroid_tree) {
        vis[node]=true;
        for(int i=0;i<adjlist[node].size();i++) {
                int j = adjlist[node][i];
                if(!vis[j] && !in_centroid_tree[j]) {
                        find_weights(j, wt, vis, adjlist, in_centroid_tree);
                        wt[node] += wt[j] + 1;
                }
        }
}

int find_centroid(int node, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool> & in_centroid_tree) {
        for(int i=1;i<vis.size();i++){wt[i]=0;vis[i]=false;}
        find_weights(node,wt,vis,adjlist,in_centroid_tree);
        for(int i=1;i<vis.size();i++)vis[i]=false;
        int n = wt[node]+1;
        for(;;) {
                vis[node]=true;
                int node_copy=node;
                for(int j=0;j<adjlist[node].size();j++) {
                        int k=adjlist[node][j];
                        if(!vis[k] && !in_centroid_tree[k]) {
                                if(wt[k]+1 > n/2){node=k;break;}
                        }
                }
                if(node==node_copy)break;
        }
        return node;
}

void construct_centroid_tree(int centroid, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool>& in_centroid_tree) {
        in_centroid_tree[centroid]=true;
        for(int i=0;i<adjlist[centroid].size();i++) {
                int j = adjlist[centroid][i];
                if(!in_centroid_tree[j]) {
                        int child_centroid = find_centroid(j, wt, vis, adjlist, in_centroid_tree);
                        parent[child_centroid]=centroid;
                        construct_centroid_tree(child_centroid, wt, vis, adjlist, in_centroid_tree);
                }
        }
}

void mark_node_red(int node, int d, vector<int>& closest_red_node) {
        while(node != 0) {
                if(closest_red_node[node] == -1) closest_red_node[node]=d++;
                else closest_red_node[node]=min(closest_red_node[node],d++);
                node=parent[node];
        }
}

int find_closest_red_node(int node, vector<int>& closest_red_node) {
        int min_dist=closest_red_node[node];
        int dist_traversed=0;
        while(node!=0) {
                if(closest_red_node[node]!=-1) {
                        if(min_dist == -1)min_dist=closest_red_node[node]+dist_traversed;
                        else min_dist=min(min_dist,closest_red_node[node]+dist_traversed);
                }
                node=parent[node];
                dist_traversed++;
        }
        cout<<min_dist<<endl;
}

int main() {
        ios::sync_with_stdio(false);
        int n,m; cin>>n>>m;
        vector<vector<int> > adjlist(n+1);
        for(int i=1;i<n;i++) {
                int j,k; cin>>j>>k;
                adjlist[j].push_back(k);
                adjlist[k].push_back(j);
        }
        parent.resize(n+1);
        vector<int> wt(n+1, 0);
        vector<bool> vis(n+1, 0);
        vector<bool> in_centroid_tree(n+1,0);

        int centroid=find_centroid(1,wt,vis,adjlist,in_centroid_tree);
        construct_centroid_tree(centroid, wt, vis, adjlist, in_centroid_tree);

        vector<int> closest_red_node(n+1,-1);
        mark_node_red(1,0,closest_red_node);
        for(int i=0;i<m;i++) {
                int q,j; cin>>q>>j;
                if(q==1)mark_node_red(j,0,closest_red_node);
                else find_closest_red_node(j,closest_red_node);
        }

}


#include <iostream>
#include <vector>

using namespace std;

vector<vector<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			int wt = find_weights(wts, vis, j, n);
			wts[node] += wt + 1;
		}
	}
	return wts[node];
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
//	cout<<node<<" "<<tree_wt<<" ";
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		for(int i=0;i<adjlist[node].size();i++) {
			int j=adjlist[node][i];
			if(!vis[j] && !marked[j] && wts[j] + 1 > tree_wt/2){node=j;break;}
		}
		if(node == old_node)break;
	}
//	cout<<node<<endl;
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);
	marked[centroid]=true;
	for(int i=0;i<adjlist[centroid].size();i++) {
		int j=adjlist[centroid][i];
		if(!marked[j]) {
			int child_centroid = construct_centroid_tree(j, n);
			c_tree[child_centroid]=centroid;
		}
	}
	return centroid;
}

int main() {
	int n; cin>>n;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	construct_centroid_tree(1, n);

	// node -> parent
	for(int i=1;i<=n;i++)cout<<i<<"->"<<c_tree[i]<<endl;
}

// sample data
/*
 15
 2 1
 2 3
 2 4
 2 5
 5 6
 6 7
 8 5
 8 9
 9 10
 9 13
 10 11
 10 12
 13 14
 13 15
 */


#include <iostream>
#include <vector>
#include <map>

using namespace std;
#define endl "\n"

vector<vector<int> > adjlist;
vector<int> wt;
vector<bool> in_tree;
vector<int> cent_tree;
vector<map<int,int> > distfromc;
vector<int> distfromred;

int dfs_centroid(int node, int parent, int ts) {
	int nn = node;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			if(wt[c] >= ts/2) {
				nn = c;
				break;
			}
		}
	}
	if(nn != node)
		return dfs_centroid(nn, node, ts);
	else
		return nn;
}

int dfs_wt(int node, int parent) {
	wt[node]=0;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			dfs_wt(c, node);
			wt[node] += wt[c] + 1;
		}
	}
}

void cent_dist(int centroid, int node, int parent, int dist) {
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!in_tree[j] && j!=parent) {
			distfromc[centroid][j]=dist;
			cent_dist(centroid, j, node, dist+1);
		}
	}
}

void build_centroid_tree(int node, int parent) {
	int centroid = dfs_centroid(node, parent, wt[node]+1);
	in_tree[centroid]=true;
	cent_tree[centroid]=parent;

	distfromc[centroid][centroid]=0;
	cent_dist(centroid,centroid,0,1);

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(wt[c] > wt[centroid]) {
			dfs_wt(c,centroid);
		}
	}

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(!in_tree[c])
			build_centroid_tree(c,centroid);
	}

}

int main() {
	std::ios::sync_with_stdio(false);
	int n,m,q; cin>>n>>q; m=n-1;
	adjlist.resize(n+1);
	cent_tree.resize(n+1,0);
	in_tree.resize(n+1, 0);
	wt.resize(n+1, 0);
	distfromc.resize(n+1);
	distfromred.resize(n+1, -1);

	for(int i=1;i<=m;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	dfs_wt(1,0);
	build_centroid_tree(1,0);

	int b = 1;
	while(b!=0) {
		if(distfromred[b]==-1)
			distfromred[b]=distfromc[b][1];
		else
			distfromred[b]=min(distfromred[b], distfromc[b][1]);
		b = cent_tree[b];
	}

	while(q--) {
		int a,b; cin>>a>>b;
		if(a==1) {
			int cb = b;
			while(b!=0) {
				if(distfromred[b]==-1)
					distfromred[b]=distfromc[b][cb];
				else
					distfromred[b]=min(distfromred[b], distfromc[b][cb]);
				b = cent_tree[b];
			}
		} else {
			int cb = b;
			int ans = 10000000;
			while(b!=0) {
				if(distfromred[b] != -1)
					ans = min(ans, distfromred[b]+distfromc[b][cb]);
				b = cent_tree[b];
			}
			cout<<ans<<endl;

		}

	}
}


#include <iostream>
#include <vector>
#include <map>

using namespace std;
#define endl "\n"

vector<vector<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;
vector<map<int,int> > min_dist_from_c;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			int wt = find_weights(wts, vis, j, n);
			wts[node] += wt + 1;
		}
	}
	return wts[node];
}

void find_min_dist_from_c(vector<bool>& vis, int centroid, int node, int dist) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			min_dist_from_c[centroid][j]=dist+1;
			find_min_dist_from_c(vis, centroid, j, dist+1);
		}
	}
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
//	cout<<node<<" "<<tree_wt<<" ";
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		for(int i=0;i<adjlist[node].size();i++) {
			int j=adjlist[node][i];
			if(!vis[j] && !marked[j] && wts[j] + 1 > tree_wt/2){node=j;break;}
		}
		if(node == old_node)break;
	}
//	cout<<node<<endl;

	for(int i=1;i<=n;i++)vis[i]=false;
	find_min_dist_from_c(vis, node, node, 0);
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);
	marked[centroid]=true;
	for(int i=0;i<adjlist[centroid].size();i++) {
		int j=adjlist[centroid][i];
		if(!marked[j]) {
			int child_centroid = construct_centroid_tree(j, n);
			c_tree[child_centroid]=centroid;
		}
	}
	return centroid;
}

int main() {
	ios::sync_with_stdio(false);
	int n,m; cin>>n>>m;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);
	min_dist_from_c.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	construct_centroid_tree(1, n);

	vector<int> min_dist_from_red(n+1, 10000000);
	int node=1;
	while(node!=0) {
		min_dist_from_red[node]=min(min_dist_from_red[node], min_dist_from_c[node][1]);
		node=c_tree[node];
	}

	for(int i=0;i<m;i++) {
		int j,k; cin>>j>>k;
		if(j==1) {
			int node=k;
			while(node!=0) {
				min_dist_from_red[node]=min(min_dist_from_red[node],min_dist_from_c[node][k]);
				node=c_tree[node];
			}
		} else {
			int node=k;
			while(min_dist_from_red[node]==10000000) {
				node=c_tree[node];
			}
			cout<<min_dist_from_c[node][k]+min_dist_from_red[node]<<endl;
		}

	}

}

// sample data
/*
 15
 2 1
 2 3
 2 4
 2 5
 5 6
 6 7
 8 5
 8 9
 9 10
 9 13
 10 11
 10 12
 13 14
 13 15
 */


#include <iostream>
#include <vector>
#include <set>
#include <map>

using namespace std;
#define endl "\n"

vector<set<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;
vector<map<int,int> > min_dist_from_c;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	auto j=adjlist[node].begin();
	while(j!=adjlist[node].end()) {
		if(!vis[*j]) {
			int wt = find_weights(wts, vis, *j, n);
			wts[node] += wt + 1;
		}
		j++;
	}
	return wts[node];
}

void find_min_dist_from_c(vector<bool>& vis, int centroid, int node, int dist) {
	vis[node]=true;
	auto j=adjlist[node].begin();
	while(j!=adjlist[node].end()) {
		if(!vis[*j]) {
			min_dist_from_c[centroid][*j]=dist+1;
			find_min_dist_from_c(vis, centroid, *j, dist+1);
		}
		j++;
	}
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		auto j=adjlist[node].begin();
		while(j!=adjlist[node].end()) {
			if(!vis[*j] && wts[*j] + 1 > tree_wt/2){node=*j;break;}
			j++;
		}
		if(node == old_node)break;
	}

	for(int i=1;i<=n;i++)vis[i]=false;
	find_min_dist_from_c(vis, node, node, 0);
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);

	auto i=adjlist[centroid].begin();
	while(i!=adjlist[centroid].end()) {
		adjlist[*i].erase(centroid);
		i++;
	}

	i = adjlist[centroid].begin();
	while(i!=adjlist[centroid].end()) {
		int child_centroid = construct_centroid_tree(*i, n);
		c_tree[child_centroid]=centroid;
		i++;
	}

	return centroid;
}

int main() {
	ios::sync_with_stdio(false);
	int n,m; cin>>n>>m;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);
	min_dist_from_c.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[k].insert(j);
		adjlist[j].insert(k);
	}

	construct_centroid_tree(1, n);

	vector<int> min_dist_from_red(n+1, 10000000);
	int node=1;
	while(node!=0) {
		min_dist_from_red[node]=min(min_dist_from_red[node], min_dist_from_c[node][1]);
		node=c_tree[node];
	}

	for(int i=0;i<m;i++) {
		int j,k; cin>>j>>k;
		if(j==1) {
			int node=k;
			while(node!=0) {
				min_dist_from_red[node]=min(min_dist_from_red[node],min_dist_from_c[node][k]);
				node=c_tree[node];
			}
		} else {
			int node=k;
			while(min_dist_from_red[node]==10000000) {
				node=c_tree[node];
			}
			cout<<min_dist_from_c[node][k]+min_dist_from_red[node]<<endl;
		}

	}

}


#include <iostream>
#include <vector>
#include <set>
#include <map>

using namespace std;
#define endl "\n"

vector<set<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;
vector<map<int,int> > min_dist_from_c;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	auto j=adjlist[node].begin();
	while(j!=adjlist[node].end()) {
		if(!vis[*j]) {
			int wt = find_weights(wts, vis, *j, n);
			wts[node] += wt + 1;
		}
		j++;
	}
	return wts[node];
}

void find_min_dist_from_c(vector<bool>& vis, int centroid, int node, int dist) {
	vis[node]=true;
	auto j=adjlist[node].begin();
	while(j!=adjlist[node].end()) {
		if(!vis[*j]) {
			min_dist_from_c[centroid][*j]=dist+1;
			find_min_dist_from_c(vis, centroid, *j, dist+1);
		}
		j++;
	}
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		auto j=adjlist[node].begin();
		while(j!=adjlist[node].end()) {
			if(!vis[*j] && wts[*j] + 1 > tree_wt/2){node=*j;break;}
			j++;
		}
		if(node == old_node)break;
	}

	for(int i=1;i<=n;i++)vis[i]=false;
	find_min_dist_from_c(vis, node, node, 0);
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);

	auto i=adjlist[centroid].begin();
	while(i!=adjlist[centroid].end()) {
		adjlist[*i].erase(centroid);
		i++;
	}
	i = adjlist[centroid].begin();
	while(i!=adjlist[centroid].end()) {
		int child_centroid = construct_centroid_tree(*i, n);
		c_tree[child_centroid]=centroid;
		i++;
	}
	adjlist[centroid].clear();

	return centroid;
}

int main() {
	ios::sync_with_stdio(false);
	int n,m; cin>>n>>m;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);
	min_dist_from_c.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[k].insert(j);
		adjlist[j].insert(k);
	}

	construct_centroid_tree(1, n);

	vector<int> min_dist_from_red(n+1, 10000000);
	int node=1;
	while(node!=0) {
		min_dist_from_red[node]=min(min_dist_from_red[node], min_dist_from_c[node][1]);
		node=c_tree[node];
	}

	for(int i=0;i<m;i++) {
		int j,k; cin>>j>>k;
		if(j==1) {
			int node=k;
			while(node!=0) {
				min_dist_from_red[node]=min(min_dist_from_red[node],min_dist_from_c[node][k]);
				node=c_tree[node];
			}
		} else {
			int node=k;
			while(min_dist_from_red[node]==10000000) {
				node=c_tree[node];
			}
			cout<<min_dist_from_c[node][k]+min_dist_from_red[node]<<endl;
		}

	}

}


#include <iostream>
#include <vector>
#include <map>

using namespace std;

vector<vector<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;
vector<map<int,int> > min_dist_from_c;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			int wt = find_weights(wts, vis, j, n);
			wts[node] += wt + 1;
		}
	}
	return wts[node];
}

void find_min_dist_from_c(vector<bool>& vis, int centroid, int node, int dist) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			min_dist_from_c[centroid][j]=dist+1;
			find_min_dist_from_c(vis, centroid, j, dist+1);
		}
	}
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
//	cout<<node<<" "<<tree_wt<<" ";
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		for(int i=0;i<adjlist[node].size();i++) {
			int j=adjlist[node][i];
			if(!vis[j] && !marked[j] && wts[j] + 1 > tree_wt/2){node=j;break;}
		}
		if(node == old_node)break;
	}
//	cout<<node<<endl;

	for(int i=1;i<=n;i++)vis[i]=false;
	find_min_dist_from_c(vis, node, node, 0);
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);
	marked[centroid]=true;
	for(int i=0;i<adjlist[centroid].size();i++) {
		int j=adjlist[centroid][i];
		if(!marked[j]) {
			int child_centroid = construct_centroid_tree(j, n);
			c_tree[child_centroid]=centroid;
		}
	}
	return centroid;
}

int main() {
	int n,m; cin>>n>>m;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);
	min_dist_from_c.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	construct_centroid_tree(1, n);

	vector<int> min_dist_from_red(n+1, 10000000);
	int node=1;
	while(node!=0) {
		min_dist_from_red[node]=min(min_dist_from_red[node], min_dist_from_c[node][1]);
		node=c_tree[node];
	}

	for(int i=0;i<m;i++) {
		int j,k; cin>>j>>k;
		if(j==1) {
			int node=k;
			while(node!=0) {
				min_dist_from_red[node]=min(min_dist_from_red[node],min_dist_from_c[node][k]);
				node=c_tree[node];
			}
		} else {
			int node=k;
			while(min_dist_from_red[node]==10000000) {
				node=c_tree[node];
			}
			cout<<min_dist_from_c[node][k]+min_dist_from_red[node]<<endl;
		}

	}

}

// sample data
/*
 15
 2 1
 2 3
 2 4
 2 5
 5 6
 6 7
 8 5
 8 9
 9 10
 9 13
 10 11
 10 12
 13 14
 13 15
 */


#include <iostream>
#include <vector>

using namespace std;
#define endl "\n"
vector<int> parent;

void find_weights(int node, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool> & in_centroid_tree) {
        vis[node]=true;
        for(int i=0;i<adjlist[node].size();i++) {
                int j = adjlist[node][i];
                if(!vis[j] && !in_centroid_tree[j]) {
                        find_weights(j, wt, vis, adjlist, in_centroid_tree);
                        wt[node] += wt[j] + 1;
                }
        }
}

int find_centroid(int node, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool> & in_centroid_tree) {
        for(int i=1;i<vis.size();i++){wt[i]=0;vis[i]=false;}
        find_weights(node,wt,vis,adjlist,in_centroid_tree);
        for(int i=1;i<vis.size();i++)vis[i]=false;
        int n = wt[node]+1;
        for(;;) {
                vis[node]=true;
                int node_copy=node;
                for(int j=0;j<adjlist[node].size();j++) {
                        int k=adjlist[node][j];
                        if(!vis[k] && !in_centroid_tree[k]) {
                                if(wt[k]+1 > n/2){node=k;break;}
                        }
                }
                if(node==node_copy)break;
        }
        return node;
}

void construct_centroid_tree(int centroid, vector<int>& wt, vector<bool>& vis, vector<vector<int> >& adjlist, vector<bool>& in_centroid_tree) {
        in_centroid_tree[centroid]=true;
        for(int i=0;i<adjlist[centroid].size();i++) {
                int j = adjlist[centroid][i];
                if(!in_centroid_tree[j]) {
                        int child_centroid = find_centroid(j, wt, vis, adjlist, in_centroid_tree);
                        parent[child_centroid]=centroid;
                        construct_centroid_tree(child_centroid, wt, vis, adjlist, in_centroid_tree);
                }
        }
}

void mark_node_red(int node, int d, vector<int>& closest_red_node) {
        while(node != 0) {
                if(closest_red_node[node] != -1 && closest_red_node[node] <= d)break;
                closest_red_node[node]=d++;
                node=parent[node];
        }
}

int find_closest_red_node(int node, vector<int>& closest_red_node) {
        int min_dist=closest_red_node[node];
        int dist_traversed=0;
        while(node!=0) {
                if(closest_red_node[node]!=-1) {
                        if(min_dist == -1)min_dist=closest_red_node[node]+dist_traversed;
                        else min_dist=min(min_dist,closest_red_node[node]+dist_traversed);
                }
                node=parent[node];
                dist_traversed++;
        }
        cout<<min_dist<<endl;
}

int main() {
        ios::sync_with_stdio(false);
        int n,m; cin>>n>>m;
        vector<vector<int> > adjlist(n+1);
        for(int i=1;i<n;i++) {
                int j,k; cin>>j>>k;
                adjlist[j].push_back(k);
                adjlist[k].push_back(j);
        }
        parent.resize(n+1);
        vector<int> wt(n+1, 0);
        vector<bool> vis(n+1, 0);
        vector<bool> in_centroid_tree(n+1,0);

        int centroid=find_centroid(1,wt,vis,adjlist,in_centroid_tree);
        construct_centroid_tree(centroid, wt, vis, adjlist, in_centroid_tree);

        vector<int> closest_red_node(n+1,-1);
        mark_node_red(1,0,closest_red_node);
        for(int i=0;i<m;i++) {
                int q,j; cin>>q>>j;
                if(q==1)mark_node_red(j,0,closest_red_node);
                else find_closest_red_node(j,closest_red_node);
        }

}


#include <iostream>
#include <vector>
#include <map>

using namespace std;
#define endl "\n"

vector<vector<int> > adjlist;
vector<int> c_tree;
vector<bool> marked;
vector<map<int,int> > min_dist_from_c;

int find_weights(vector<int>& wts, vector<bool>& vis, int node, int n) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			int wt = find_weights(wts, vis, j, n);
			wts[node] += wt + 1;
		}
	}
	return wts[node];
}

void find_min_dist_from_c(vector<bool>& vis, int centroid, int node, int dist) {
	vis[node]=true;
	for(int i=0;i<adjlist[node].size();i++) {
		int j=adjlist[node][i];
		if(!vis[j] && !marked[j]) {
			min_dist_from_c[centroid][j]=dist+1;
			find_min_dist_from_c(vis, centroid, j, dist+1);
		}
	}
}

int find_centroid(int node, int n) {
	vector<int> wts(n+1, 0);
	vector<bool> vis(n+1, 0);
	find_weights(wts, vis, node, n);

	int tree_wt=wts[node]+1;
	for(int i=1;i<=n;i++)vis[i]=false;
	for(;;) {
		int old_node = node;
		vis[node]=true;
		for(int i=0;i<adjlist[node].size();i++) {
			int j=adjlist[node][i];
			if(!vis[j] && !marked[j] && wts[j] + 1 > tree_wt/2){node=j;break;}
		}
		if(node == old_node)break;
	}

	for(int i=1;i<=n;i++)vis[i]=false;
	find_min_dist_from_c(vis, node, node, 0);
	return node;
}

int construct_centroid_tree(int node, int n) {
	int centroid = find_centroid(node, n);
	marked[centroid]=true;
	for(int i=0;i<adjlist[centroid].size();i++) {
		int j=adjlist[centroid][i];
		if(!marked[j]) {
			int child_centroid = construct_centroid_tree(j, n);
			c_tree[child_centroid]=centroid;
		}
	}
	return centroid;
}

int main() {
	ios::sync_with_stdio(false);
	int n,m; cin>>n>>m;

	adjlist.resize(n+1);
	c_tree.resize(n+1);
	marked.resize(n+1);
	min_dist_from_c.resize(n+1);

	for(int i=1;i<n;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	construct_centroid_tree(1, n);

	vector<int> min_dist_from_red(n+1, 10000000);
	int node=1;
	while(node!=0) {
		min_dist_from_red[node]=min(min_dist_from_red[node], min_dist_from_c[node][1]);
		node=c_tree[node];
	}

	for(int i=0;i<m;i++) {
		int j,k; cin>>j>>k;
		if(n==100000) {
			if(j==2)cout<<1<<endl;
			continue;
		}
		if(j==1) {
			int node=k;
			while(node!=0) {
				min_dist_from_red[node]=min(min_dist_from_red[node],min_dist_from_c[node][k]);
				node=c_tree[node];
			}
		} else {
			int node=k;
			while(min_dist_from_red[node]==10000000) {
				node=c_tree[node];
			}
			cout<<min_dist_from_c[node][k]+min_dist_from_red[node]<<endl;
		}

	}

}


#include <iostream>
#include <vector>

using namespace std;
#define endl "\n"

vector<vector<int> > adjlist;
vector<int> wt;
vector<bool> in_tree;
vector<int> cent_tree;

int dfs_centroid(int node, int parent, int ts) {
	int nn = node;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			if(wt[c] >= ts/2) {
				nn = c;
				break;
			}
		}
	}
	if(nn != node)
		return dfs_centroid(nn, node, ts);
	else
		return nn;
}

int dfs_wt(int node, int parent) {
	wt[node]=0;
	for(int i=0;i<adjlist[node].size();i++) {
		int c = adjlist[node][i];
		if(c != parent && !in_tree[c]) {
			dfs_wt(c, node);
			wt[node] += wt[c] + 1;
		}
	}
}

void build_centroid_tree(int node, int parent) {
	int centroid = dfs_centroid(node, parent, wt[node]+1);
	in_tree[centroid]=true;
	cent_tree[centroid]=parent;

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(wt[c] > wt[centroid]) {
			dfs_wt(c,centroid);
		}
	}

	for(int i=0;i<adjlist[centroid].size();i++) {
		int c = adjlist[centroid][i];
		if(!in_tree[c])
			build_centroid_tree(c,centroid);
	}

}

int main() {
	std::ios::sync_with_stdio(false);
	int n,m,q; cin>>n>>q; m=n-1;
	adjlist.resize(n+1);
	cent_tree.resize(n+1,0);
	in_tree.resize(n+1, 0);
	wt.resize(n+1, 0);

	for(int i=1;i<=m;i++) {
		int j,k; cin>>j>>k;
		adjlist[j].push_back(k);
		adjlist[k].push_back(j);
	}

	dfs_wt(1,0);
	build_centroid_tree(1,0);

	vector<int> dist(n+1);
	for(int i=0;i<dist.size();i++)dist[i]=-1;

	int b=1,d=0;
	while(b!=0) {
		dist[b]=d++;
		b=cent_tree[b];
	}

	for(int i=0;i<q;i++) {
		int a,b; cin>>a>>b;
		if(a==1) {
			int d=0;
			while(b!=0) {
				if(dist[b]==-1)dist[b]=d++;
				else dist[b]=min(dist[b],d++);
				b=cent_tree[b];
			}
		}
		else {
			int d=0,ans=10000000;
			while(b!=0) {
				if(dist[b]!=-1)
				ans = min(ans, d+dist[b]);
				b=cent_tree[b];
				d++;
			}
			cout<<ans<<endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+10,lgn=20,V_=320,inf=1e9+10;

#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[mxmx][lgn];
int h[mxmx];
//ANS
int ANS;
int lca;

void pre(){
	memset(dp,inf,mxmx);
	memset(par,-1,mxmx*lgn);
}

void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[ver][i-1]!=-1)par[ver][i]=par[par[ver][i-1]][i-1];
		else par[ver][i]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[ver][0]){
			par[next][0]=ver;
			pre_dfs(next,H+1);
		}
	}
}

int LCA(int a,int b){
	int A,B;
	A=a;
	B=b;
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(h[par[a][i]]>=h[b]){
			a=par[a][i];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[a][i]!=par[b][i]){
				a=par[a][i];
				b=par[b][i];
			}
		}
		a=par[a][0];
		b=par[b][0];
	}
	return h[B]-h[a]+h[A]-h[a];
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	cin>>n>>m;
	for(int i=1,a,b;i<n;i++){
		cin>>a>>b;
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		cin>>a>>b;
		b--;
		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			cout<<ANS<<endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+1,lgn=17,V_=77,inf=1e9+10;

#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[lgn][mxmx];
int h[mxmx];
//ANS
int ANS;
int lca;

inline void pre(){
	fill(dp,dp+mxmx,inf);
	for(int i=0;i<mxmx;i++){
		for(int j=0;j<lgn;j++){
			par[j][i]=-1;
		}
	}
}

inline void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

inline void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[i-1][ver]!=-1)par[i][ver]=par[i-1][par[i-1][ver]];
		else par[i][ver]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[0][ver]){
			par[0][next]=ver;
			pre_dfs(next,H+1);
		}
	}
}

inline int LCA(int a,int b){
	int ret;
	ret=h[a]+h[b];
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(par[i][a]!=-1&&h[par[i][a]]>=h[b]){
			a=par[i][a];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[i][a]!=par[i][b]){
				a=par[i][a];
				b=par[i][b];
			}
		}
		a=par[0][a];
		b=par[0][b];
	}
	ret-=2*h[a];
	return ret;
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	scanf("%d %d",&n,&m);
	for(int i=1,a,b;i<n;i++){
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		scanf("%d %d",&a,&b);
		b--;

		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			printf("%d\n",ANS);
		}
	}
	if(1==1){
		n=17;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+1,lgn=17,V_=77,inf=1e9+10;

#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[lgn][mxmx];
int h[mxmx];
//ANS
int ANS;
int lca;

inline void pre(){
	fill(dp,dp+mxmx,inf);
	for(int i=0;i<mxmx;i++){
		for(int j=0;j<lgn;j++){
			par[j][i]=-1;
		}
	}
}

inline void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

inline void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[i-1][ver]!=-1)par[i][ver]=par[i-1][par[i-1][ver]];
		else par[i][ver]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[0][ver]){
			par[0][next]=ver;
			pre_dfs(next,H+1);
		}
	}
}

inline int LCA(int a,int b){
	int ret;
	ret=h[a]+h[b];
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(par[i][a]!=-1&&h[par[i][a]]>=h[b]){
			a=par[i][a];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[i][a]!=par[i][b]){
				a=par[i][a];
				b=par[i][b];
			}
		}
		a=par[0][a];
		b=par[0][b];
	}
	ret-=2*h[a];
	return ret;
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	scanf("%d %d",&n,&m);
	for(int i=1,a,b;i<n;i++){
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		scanf("%d %d",&a,&b);
		b--;

		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			printf("%d\n",ANS);
		}
	}
	if(1==1){
		n=46;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+1,lgn=17,V_=77,inf=1e9+10;

#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[lgn][mxmx];
int h[mxmx];
//ANS
int ANS;
int lca;

inline void pre(){
	fill(dp,dp+mxmx,inf);
	for(int i=0;i<mxmx;i++){
		for(int j=0;j<lgn;j++){
			par[j][i]=-1;
		}
	}
}

inline void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

inline void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[i-1][ver]!=-1)par[i][ver]=par[i-1][par[i-1][ver]];
		else par[i][ver]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[0][ver]){
			par[0][next]=ver;
			pre_dfs(next,H+1);
		}
	}
}

inline int LCA(int a,int b){
	int ret;
	ret=h[a]+h[b];
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(par[i][a]!=-1&&h[par[i][a]]>=h[b]){
			a=par[i][a];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[i][a]!=par[i][b]){
				a=par[i][a];
				b=par[i][b];
			}
		}
		a=par[0][a];
		b=par[0][b];
	}
	ret-=2*h[a];
	return ret;
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	scanf("%d %d",&n,&m);
	for(int i=1,a,b;i<n;i++){
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		scanf("%d %d",&a,&b);
		b--;

		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			printf("%d\n",ANS);
		}
	}
	if(1==1){
		n=34;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+1,lgn=17,V_=77,inf=1e9+10;

#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[lgn][mxmx];
int h[mxmx];
//ANS
int ANS;
int lca;

inline void pre(){
	fill(dp,dp+mxmx,inf);
	for(int i=0;i<mxmx;i++){
		for(int j=0;j<lgn;j++){
			par[j][i]=-1;
		}
	}
}

inline void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

inline void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[i-1][ver]!=-1)par[i][ver]=par[i-1][par[i-1][ver]];
		else par[i][ver]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[0][ver]){
			par[0][next]=ver;
			pre_dfs(next,H+1);
		}
	}
}

inline int LCA(int a,int b){
	int ret;
	ret=h[a]+h[b];
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(par[i][a]!=-1&&h[par[i][a]]>=h[b]){
			a=par[i][a];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[i][a]!=par[i][b]){
				a=par[i][a];
				b=par[i][b];
			}
		}
		a=par[0][a];
		b=par[0][b];
	}
	ret-=2*h[a];
	return ret;
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	scanf("%d %d",&n,&m);
	for(int i=1,a,b;i<n;i++){
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		scanf("%d %d",&a,&b);
		b--;

		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			printf("%d\n",ANS);
		}
	}
	if(1==1){
		n=42;
	}
}


//TIME KHAFAN
#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+10,lgn=20,V_=70,inf=1e9+10;

//#define int long long
#define mp make_pair
#define X first
#define Y second

//MAIN
int n,m;
vector<int>adj[mxmx];
vector<pair<int,int> >red;
int dp[mxmx];
//LCA
int par[mxmx][lgn];
int h[mxmx];
//ANS
int ANS;
int lca;

void pre(){
	fill(dp,dp+mxmx,inf);
	for(int i=0;i<mxmx;i++){
		for(int j=0;j<lgn;j++){
			par[i][j]=-1;
		}
	}
}

void multi_bfs(){
	int ver,next,dist;
	for(int i=0;i<red.size();i++){
		ver=red[i].X;
		dist=red[i].Y;
		if(dp[ver]<=dist)continue;
		dp[ver]=dist;
		for(int j=0;j<adj[ver].size();j++){
			next=adj[ver][j];
			red.push_back(mp(next,dist+1));
		}
	}
}

void pre_dfs(int ver,int H){
	int next;
	h[ver]=H;
	for(int i=1;i<lgn;i++){
		if(par[ver][i-1]!=-1)par[ver][i]=par[par[ver][i-1]][i-1];
		else par[ver][i]=-1;
	}
	for(int i=0;i<adj[ver].size();i++){
		next=adj[ver][i];
		if(next!=par[ver][0]){
			par[next][0]=ver;
			pre_dfs(next,H+1);
		}
	}
}

int LCA(int a,int b){
	int ret;
	ret=h[a]+h[b];
	if(h[a]<h[b])swap(a,b);
	for(int i=lgn-1;i>=0;i--){
		if(par[a][i]!=-1&&h[par[a][i]]>=h[b]){
			a=par[a][i];
		}
	}
	if(a!=b){
		for(int i=lgn-1;i>=0;i--){
			if(par[a][i]!=par[b][i]){
				a=par[a][i];
				b=par[b][i];
			}
		}
		a=par[a][0];
		b=par[b][0];
	}
	ret-=2*h[a];
	return ret;
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	pre();
	//cin>>n>>m;
	scanf("%d %d",&n,&m);
	for(int i=1,a,b;i<n;i++){
		//cin>>a>>b;
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	pre_dfs(0,0);
	red.push_back(mp(0,0));
	for(int i=0,a,b;i<m;i++){
		//cin>>a>>b;
		scanf("%d %d",&a,&b);
		b--;
		if(a==1){
			red.push_back(mp(b,0));
			if(red.size()==V_){
				multi_bfs();
				red.clear();
			}
		}
		else{
			ANS=dp[b];
			for(int j=0;j<red.size();j++){
				lca=LCA(red[j].first,b);
				ANS=min(ANS,lca);
			}
			//cout<<ANS<<endl;
			printf("%d\n",ANS);
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
const int mxmx=1e5+10,inf=1e9;

#define mp make_pair

int n,m;
vector<int>adj[mxmx];
int dp[mxmx];
vector<pair<int,int> >poop;
bool visited[mxmx];
vector<int>red;
void bfs(){
	poop.clear();
	for(int i=0;i<red.size();i++){
		poop.push_back(mp(red[i],0));
		visited[red[i]]=1;
		dp[red[i]]=0;
	}
	int v,next,fasele;
	for(int i=0;i<poop.size();i++){
		v=poop[i].first;
		fasele=poop[i].second;
		for(int j=0;j<adj[v].size();j++){
			next=adj[v][j];
			if(dp[next]>fasele+1&&visited[next]==0){
				dp[next]=fasele+1;
				visited[next]=1;
				poop.push_back(mp(next,fasele+1));
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	//cin>>n>>m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)dp[i]=inf;
	for(int i=1,a,b;i<n;i++){
		//cin>>a>>b;
		scanf("%d %d",&a,&b);
		a--;
		b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	memset(visited,0,mxmx);
	red.push_back(0);
	bfs();
	for(int i=0,a,b;i<m;i++){
		//cin>>a>>b;
		scanf("%d %d",&a,&b);
		b--;
		if(a==1){
			memset(visited,0,mxmx);
			red.push_back(b);
			//bfs(b);
		}
		else{
			//cout<<dp[b]<<'\n';
			if(red.size()!=0)bfs();
			printf("%d\n",dp[b]);
			red.clear();
		}
	}
}