#include <bits/stdc++.h>
typedef long long ll;
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(r)       (int)r.size()
#define MOD        1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define deb(r) cout << #r << "=" << r << endl
#define deb2(r, y) cout << #r << "=" << r << "," << #y << "=" << y << endl
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define boost				ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int MAXN = 200005;
const ll inf = 1e18;
using namespace std;

vi adj[MAXN];
int l[MAXN];
bool vis[MAXN];

void solve(){
	int n;
	cin>>n;
	int u,v;
	rep(i,0,n-1){
		cin>>u>>v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	vi s(n);
	rep(i,1,n+1)
		cin>>s[i];

	queue<int> q;
	q.push(1);
	int c = 1;

	while(!q.empty()){
		int r = q.front();
		q.pop();
		for(int i=0; i<adj[r].size()-(r!=1); i++){
			if(!binary_search(adj[r].begin(), adj[r].end(), s[++c])){
				// deb2(r, s[c-1]);
				cout<<"No";
				return;
			}
			else{
				// deb(s[c]);
				q.push(s[c]);
			}
		}
	}

	cout<<"Yes";
}

int main(){
	boost;
	int t=1;
	// cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(r)       (int)r.size()
#define MOD        1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define deb(r) cout << #r << "=" << r << endl
#define deb2(r, y) cout << #r << "=" << r << "," << #y << "=" << y << endl
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define boost				ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int MAXN = 200005;
const ll inf = 1e18;
using namespace std;

vi adj[MAXN];
int l[MAXN];
bool vis[MAXN];

void solve(){
	int n;
	cin>>n;
	int u,v;
	rep(i,0,n-1){
		cin>>u>>v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	vi s(n+1);
	rep(i,1,n+1)
		cin>>s[i];

	if(s[1]!=1){
		cout<<"No";
		return;
	}

	queue<int> q;
	q.push(1);
	int c = 1;

	while(!q.empty()){
		int r = q.front();
		q.pop();
		for(int i=0; i<adj[r].size()-(r!=1); i++){
			if(!binary_search(adj[r].begin(), adj[r].end(), s[++c])){
				// deb2(r, s[c-1]);
				cout<<"No";
				return;
			}
			else{
				// deb(s[c]);
				q.push(s[c]);
			}
		}
	}

	cout<<"Yes";
}

int main(){
	boost;
	int t=1;
	// cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(r)       (int)r.size()
#define MOD        1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define deb(r) cout << #r << "=" << r << endl
#define deb2(r, y) cout << #r << "=" << r << "," << #y << "=" << y << endl
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define boost				ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int MAXN = 200005;
const ll inf = 1e18;
using namespace std;

vi adj[MAXN];
int l[MAXN];
bool vis[MAXN];

void solve(){
	int n;
	cin>>n;
	int u,v;
	rep(i,0,n-1){
		cin>>u>>v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	vi s(n);
	rep(i,0,n)
		cin>>s[i];

	queue<int> q;
	q.push(1);
	int c = 0;

	while(!q.empty()){
		int r = q.front();
		q.pop();
		for(int i=0; i<adj[r].size()- (r!=1); i++){
			if(!binary_search(adj[r].begin(), adj[r].end(), s[++c])){
				// deb2(r, s[c-1]);
				cout<<"No";
				return;
			}
			else{
				// deb(s[c]);
				q.push(s[c]);
			}
		}
	}

	cout<<"Yes";
}

int main(){
	boost;
	int t=1;
	// cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(r)       (int)r.size()
#define MOD        1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define deb(r) cout << #r << "=" << r << endl
#define deb2(r, y) cout << #r << "=" << r << "," << #y << "=" << y << endl
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define boost				ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int MAXN = 200005;
const ll inf = 1e18;
using namespace std;

vi adj[MAXN];
int l[MAXN];
bool vis[MAXN];

void bfs(int r){
	queue<int> que;

    que.push(r);

    l[r] = 0;

    vis[r] = true;

    while (!que.empty()) {

        r = que.front();

        que.pop();

        for (int i = 0; i < adj[r].size(); i++) {
            int b = adj[r][i];

            if (!vis[b]) {

                que.push(b);

                l[b] = l[r] + 1;

                vis[b] = true;
            }
        }
    }
}

void solve(){
	int n;
	cin>>n;
	int u,v;
	rep(i,0,n){
		cin>>u>>v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	bfs(1);
	int ml = 0;
	rep(i,0,n){
		cin>>u;
		if(l[u]<ml){
			cout<<"No";
			return;
		}
		else
			ml = max(ml, l[u]);
	}
	cout<<"Yes";
}

int main(){
	boost;
	int t=1;
	// cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
typedef long long ll;
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(r)       (int)r.size()
#define MOD        1000000007
#define endl        '\n'
#define rep(i,a,b)	for(int i=a;i<b;i++)
#define deb(r) cout << #r << "=" << r << endl
#define deb2(r, y) cout << #r << "=" << r << "," << #y << "=" << y << endl
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define boost				ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
const int MAXN = 200005;
const ll inf = 1e18;
using namespace std;

vi adj[MAXN];
int l[MAXN];
bool vis[MAXN];

void solve(){
	int n;
	cin>>n;
	int u,v;
	rep(i,0,n-1){
		cin>>u>>v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	vi s(n);
	rep(i,0,n)
		cin>>s[i];
	queue<int> q;
	q.push(1);
	int c = 1;
	while(!q.empty()){
		int r = q.front();
		q.pop();
		for(int i=0; i<adj[r].size() - (r!=1); i++){
			if(binary_search(adj[r].begin(), adj[r].end(), s[c++])){
				cout<<"No";
				return;
			}
			else
				q.push(s[c]);
		}
	}
	cout<<"Yes";
}

int main(){
	boost;
	int t=1;
	// cin>>t;
	while(t--){
		solve();
	}
	return 0;
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 3e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

void dfs(int v){
    odw[v] = 1;
    for(auto i: graph[v]){
        if(!odw[i]){
            depth[i] = depth[v]+1;
            oj[i] = v;
            dfs(i);
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    dfs(1);
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] < depth[arr[i-1]])flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
        cout << oj[arr[i]] << " ";
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 3e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
int kol[maxn];
bool odw[maxn];

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++){
        cin >> arr[i];
        kol[arr[i]] = i;
    }
    bfs();
    bool flag = 1;
    oj[1] = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] != depth[arr[i-1]] and depth[i]-1 != depth[arr[i-1]])
            flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
//        cout << arr[i] << " " << kol[oj[arr[i]]] << " " << kol[oj[arr[i-1]]] << endl;
        if(kol[oj[arr[i]]] < kol[oj[arr[i-1]]])flag = 0;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 1e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];
int layer[maxn];
vi keks;
void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        keks.pb(v);
        for(auto i: graph[v]){
            if(!odw[i]){
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    int it = 1;
    if(arr[1] != 1){
        cout << "No";
        return 0;
    }
    for(int i = 1; i <= n; i++){
        int m = graph[arr[i]].size()-1;
        if(arr[i] == 1)m++;
        sort(arr+it+1, arr+it+1+m);
        it += m;
//        cout << arr[i] << " ";
    }
    bfs();
//    cout << endl;
    for(int i = 1; i <= n; i++){
//        cout << keks[i-1] << " ";
        if(arr[i] != keks[i-1]){
            cout << "No";
            return 0;
        }
    }
    cout << "Yes";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    bfs();
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i] != depth[arr[i-1]]] and depth[i] != depth[arr[i-1]]-1)
            flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 1e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
bool odw[maxn];

void dfs(int v){
    odw[v] = 1;
    for(auto i: graph[v]){
        if(!odw[i]){
            depth[i] = depth[v]+1;
            dfs(i);
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    dfs(1);
    bool flag = 1;
    for(int i = 1; i <= n; i++){
        arr[i] = depth[arr[i]];
        if(arr[i] < arr[i-1])flag = 0;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 1e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

void dfs(int v){
    odw[v] = 1;
    for(auto i: graph[v]){
        if(!odw[i]){
            depth[i] = depth[v]+1;
            oj[i] = v;
            dfs(i);
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    dfs(1);
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] < depth[arr[i-1]])flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
//        cout << i << " " << oj[arr[i]] << endl;./
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 1e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];
int layer[maxn];
vi keks;
void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        keks.pb(v);
        for(auto i: graph[v]){
            if(!odw[i]){
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    int it = 1;
    for(int i = 1; i <= n; i++){
        int m = graph[arr[i]].size()-1;
        if(arr[i] == 1)m++;
        sort(arr+it+1, arr+it+1+m);
        it += m;
//        cout << arr[i] << " ";
    }
    bfs();
//    cout << endl;
    for(int i = 1; i <= n; i++){
//        cout << keks[i-1] << " ";
        if(arr[i] != keks[i-1]){
            cout << "No";
            return 0;
        }
    }
    cout << "Yes";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 3e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];
int layer[maxn];
vi keks;
void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        keks.pb(v);
        for(auto i: graph[v]){
            if(!odw[i]){
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    int it = 1;
    for(int i = 1; i <= n; i++){
        int m = graph[arr[i]].size()-1;
        if(arr[i] == 1)m++;
        sort(arr+it+1, arr+it+1+m);
        it += m;
    }
    bfs();
    for(int i = 1; i <= n; i++){
        if(arr[i] != keks[i-1]){
            cout << "No";
            return 0;
        }
    }
    cout << "Yes";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 3e5+100;

vi graph[maxn];
int arr[maxn];
int wag[maxn];
bool odw[maxn];
vi keks;

bool cmp(int a, int b){
    if(wag[a] != wag[b])return wag[a] < wag[b];
    return false;
}

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        keks.pb(v);
        for(auto i: graph[v]){
            if(!odw[i]){
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++){
        cin >> arr[i];
        wag[arr[i]] = i;
    }
    for(int i = 1; i <= n; i++)
        sort(graph[i].begin(), graph[i].end(), cmp);
    bfs();
    for(int i = 1; i <= n; i++){
        if(arr[i] != keks[i-1])return cout << "No", 0;
    }
    cout << "Yes";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 3e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

void dfs(int v){
    odw[v] = 1;
    for(auto i: graph[v]){
        if(!odw[i]){
            depth[i] = depth[v]+1;
            oj[i] = v;
            dfs(i);
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    dfs(1);
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] < depth[arr[i-1]])flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
//        cout << oj[arr[i]] << " ";
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
bool odw[maxn];
int depth[maxn];
queue <int> asked;
set <pii> que;

bool bfs(){
    depth[1] = 1;
    odw[1] = 1;
    que.insert(mp(1, 1));
    int lDepth = 0;
    while(asked.size()){
        int v = asked.front(); asked.pop();
        if(depth[v] < lDepth)return false;
        else lDepth = depth[v];
        if(que.find(mp(v, lDepth)) == que.end())return false;
        else que.erase(mp(v, lDepth));
        for(auto i: graph[v]){
            if(!odw[i]){
                odw[i] = 1;
                depth[i] = depth[v]+1;
                que.insert(mp(i, depth[i]));
            }
        }
    }
    return true;
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 0; i < n; i++){
        int x;
        cin >> x;
        asked.push(x);
    }
    if(bfs())cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
int kol[maxn];
bool odw[maxn];

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++){
        cin >> arr[i];
        kol[arr[i]] = i;
    }
    bfs();
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] != depth[arr[i-1]] and depth[i]-1 != depth[arr[i-1]])
            flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
//        cout << arr[i] << " " << kol[oj[arr[i]]] << " " << kol[oj[arr[i-1]]] << endl;
        if(kol[oj[arr[i]]] < kol[oj[arr[i-1]]])flag = 0;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
int kol[maxn];
bool odw[maxn];

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++){
        kol[arr[i]] = i;
        cin >> arr[i];
    }
    bfs();
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] != depth[arr[i-1]] and depth[i]-1 != depth[arr[i-1]])
            flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
        if(kol[oj[arr[i]]] < kol[oj[arr[i-1]]])flag = 0;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

//void dfs(int v){
//    odw[v] = 1;
//    for(auto i: graph[v]){
//        if(!odw[i]){
//            depth[i] = depth[v]+1;
//            oj[i] = v;
//            dfs(i);
//        }
//    }
//}

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    bfs();
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] < depth[arr[i-1]])flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug(x) cout << #x << " " << x << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxn = 2e5+100;

vi graph[maxn];
int arr[maxn];
int depth[maxn];
int oj[maxn];
bool odw[maxn];

void bfs(){
    queue <int> que;
    que.push(1);
    odw[1] = 1;
    depth[1] = 1;
    while(que.size()){
        int v = que.front(); que.pop();
        for(auto i: graph[v]){
            if(!odw[i]){
                depth[i] = depth[v]+1;
                oj[i] = v;
                odw[i] = 1;
                que.push(i);
            }
        }
    }
}

int main(){
    bust
    int n;
    cin >> n;
    for(int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    for(int i = 1; i <= n; i++)
        cin >> arr[i];
    bfs();
    bool flag = 1;
    for(int i = 1; i <= n; i++)
        if(depth[arr[i]] != depth[arr[i-1]] and depth[i]-1 != depth[arr[i-1]])
            flag = 0;
    klar(odw);
    for(int i = 2; i <= n; i++){
        if(odw[oj[arr[i]]]){
            if(oj[arr[i]] != oj[arr[i-1]])
                flag = 0;
        }
        else odw[oj[arr[i]]] = 1;
    }
    if(flag)cout << "Yes";
    else cout << "No";
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main()
{
    ll n,x,y;
    cin>>n;
    set<ll>v[n];
    for(ll i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--;y--;
        v[x].insert(y);
        v[y].insert(x);
    }
    ll a[n];
    for(ll i=0;i<n;i++){
        cin>>a[i];a[i]--;}

    if(a[0]!=0)
    {
        cout<<"No";
        return 0;
    }
    queue<ll>q;
    q.push(0);
    ll ind = 1;
    while(!q.empty())
    {
        ll p = q.front();
        q.pop();
        while(v[p].size())
        {
            if(v[p].find(a[ind])==v[p].end())
            {
                cout<<"No";
                return 0;
            }
            v[p].erase(a[ind]);
            v[a[ind]].erase(p);
            ind++;
        }
    }
    cout<<"Yes";
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main()
{
    ll n,x,y;
    cin>>n;
    set<ll>v[n];
    for(ll i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--;y--;
        v[x].insert(y);
        v[y].insert(x);
    }
    ll a[n];
    for(ll i=0;i<n;i++){
        cin>>a[i];a[i]--;}

    if(a[0]!=0)
    {
        cout<<"No";
        return 0;
    }
    queue<ll>q;
    q.push(0);
    ll ind = 1;
    while(!q.empty())
    {
        ll p = q.front();
        q.pop();
        while(v[p].size())
        {
            if(v[p].find(a[ind])==v[p].end())
            {
                cout<<"No";
                return 0;
            }
            v[p].erase(a[ind]);
            v[a[ind]].erase(p);
            ind++;
        }
    }
    if(ind!=n)cout<<"No";else
    cout<<"Yes";
}


#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;

int n;
vector <int> adj[N];
bool seen[N];
int order[N];
int parent[N];
int childs[N];
int idx;

void solve(int u, int par) {
   if(par != -1) {
      parent[u] = par;
   }
   for(int i = 0; i < adj[u].size(); ++i) {
       if(adj[u][i] != par) {
       	solve(adj[u][i] , u);
       	childs[u]++;
       }
   }
}

bool ok(int node) {
    if(childs[node] > 0) {
    int from = idx;
    int to = idx + childs[node] - 1;
    for(int i = from; i <= to; ++i) {
        if(parent[order[i]] != node) {
        	return false;
        }
    }
    } else {
    	return true;
    }
}

int main() {
   cin >> n;
   for(int i = 1; i < n; ++i) {
       int u , v;
       cin >> u >> v;
       adj[u].push_back(v);
       adj[v].push_back(u);
   }
   for(int i = 1; i <= n; ++i) {
      cin >> order[i];
   }
   solve(1, -1);
   queue <int> q;
   q.push(1);
   idx = 2;
   while(!q.empty()) {
   int node = q.front(); q.pop();
   if(!ok(node)) {
   	cout << "No" << endl;
   	return 0;
   }
   int from = idx;
   int to = idx + childs[node] - 1;
   for(int i = from; i <= to; ++i) {
        q.push(order[i]);
   }
   idx += childs[node];
   }
   cout << "Yes" << endl;
   return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main()
{
    ll n,x,y;
    cin>>n;
    vector<ll>v[n];
    for(ll i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--;y--;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    ll a[n];
    for(ll i=0;i<n;i++){
        cin>>a[i];a[i]--;}

    if(a[0]!=0)
    {
        cout<<"No";
        return 0;
    }
    queue<ll>q;
    q.push(0);
    ll ind = 1;
    while(!q.empty())
    {
        ll p = q.front();
        q.pop();
        while(v[p].size())
        {
            if(find(v[p].begin(),v[p].end(),a[ind])==v[p].end())
            {
                cout<<"No";
                return 0;
            }
            v[p].erase(std::remove(v[p].begin(), v[p].end(), a[ind]), v[p].end());
            v[a[ind]].erase(std::remove(v[a[ind]].begin(), v[a[ind]].end(), p), v[a[ind]].end());
            ind++;
        }
    }
    cout<<"Yes";
}


#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
using namespace std;
#define mod (int)(1e9+7)
#define for0(i,n) for(int i=0;i<n;i++)
#define for1(i,n) for(int i=1;i<=n;i++)
#define forab(i,a,b) for(int i=a;i<=b;i++)
#define tc(t) int t;cin >>t;while(t--)
#define int long long
#define pb(i) push_back(i)
#define fio ios_base::sync_with_stdio(false),cin.tie(NUint)
#define in(x) scanf("%intd",&x)
#define rr return 0
#define mp make_pair
#define maxheap priority_queue<int>
#define minheap priority_queue<int,vector<int>,greater<int>>
#define inf (int)(1e18)
const int N = (int)(2*1e5+10);
int mult(int a,int b, int p){return ((a%p)*(b%p))%p;}
int add(int a, int b, int p){return (a%p + b%p)%p;}
int fpow(int n, int k, int p) {int r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
int gcd(int a,int b) { if (a == 0) return b; return gcd(b%a, a);}
int max(int a,int b){if(a>b) return a; else return b;}
int min(int a,int b){if(a<b) return a; else return b;}
signed main()
{
#ifndef ONLINE_JUDGE
// for getting input from input.txt
freopen("input.txt", "r", stdin);
// for writing output to output.txt
freopen("output.txt", "w", stdout);
#endif
int n;
cin >> n;
set<int>v[n+1];
for0(i,n-1)
{
    int x,y;
    cin >> x >> y;
    v[x].insert(y);
    v[y].insert(x);
}
int a[n];
for0(i,n)
cin >> a[i];

if(a[0]!=1)
{
cout << "No";
rr;
}

queue<int>q;
q.push(1);
int ind = 1;

while(q.empty()==false)
{
    int top = q.front();
    q.pop();
    while(v[top].size()>0)
    {
            int temp=a[ind];
            ind++;
            if(v[top].end()==v[top].find(temp)){
                cout<<"No";
                rr;
            }

            v[temp].erase(top);
            v[top].erase(temp);
             q.push(temp);

    }

}

if(ind!=n)
{
    cout << "No";
}
else
cout << "Yes";

rr;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main()
{
    ll n,x,y;
    cin>>n;
    vector<ll>v[n];
    for(ll i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--;y--;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    ll a[n];
    for(ll i=0;i<n;i++){
        cin>>a[i];a[i]--;}

    if(a[0]!=0)
    {
        cout<<"No";
        return 0;
    }
    for(ll i=0;i<n;i++)
        sort(v[i].begin(),v[i].end());
    queue<ll>q;
    q.push(0);
    ll ind = 1;
    while(!q.empty())
    {
        ll p = q.front();
        q.pop();
        while(v[p].size())
        {
            if(find(v[p].begin(),v[p].end(),a[ind])==v[p].end())
            {
                cout<<"No";
                return 0;
            }
            v[p].erase(std::remove(v[p].begin(), v[p].end(), a[ind]), v[p].end());
            v[a[ind]].erase(std::remove(v[a[ind]].begin(), v[a[ind]].end(), p), v[a[ind]].end());
            ind++;
        }
    }
    cout<<"Yes";
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ll,int> pli;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
#define F first
#define S second
typedef vector<pli> vpli;
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define all(v) v.begin(),v.end()
#define tests int t; cin>>t; while(t--)
#define take(a,b,c) for(b=0;b<c;b++) cin>>a[b];
typedef long long ll;
vector<int> ans,adj[200007];
bool vis[200007];
int inputorder[200007],relorder[200007];
bool cmp(int a,int b){
	return relorder[a]<relorder[b];
}
int main()
{
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n,x,a,b,i,j;
	cin>>n;
	for(i=0;i<n-1;i++){
		cin>>a>>b;
		adj[a].pb(b);
		adj[b].pb(a);
	}
	for(i=0;i<n;i++){
		cin>>inputorder[i];
		relorder[inputorder[i]]=i;
	}
	for(i=1;i<=n;i++)
		sort(all(adj[i]),cmp);
	queue<int> q;
	q.push(1);
	//cout<<adj[1][0]<<" "<<adj[1][1]<<endl;
	memset(vis,false,sizeof(vis));
	while(!(q.empty())){
		queue<int> temp;
		while(!(q.empty())){
			int x= q.front();
			q.pop();
			ans.pb(x);
			//cout<<x<<endl;
			vis[x]=true;
			for(j=0;j<adj[x].size();j++)
				if(vis[adj[x][j]]==false){//cout<<adj[x][j]<<endl;
					temp.push(adj[x][j]);}
			}
		q=temp;
	}
	for(i=0;i<n;i++)
		if(inputorder[i]!=ans[i]){
			cout<<"No"; return 0;}
	cout<<"Yes";

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ll,int> pli;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
#define F first
#define S second
typedef vector<pli> vpli;
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define all(v) v.begin(),v.end()
#define tests int t; cin>>t; while(t--)
#define take(a,b,c) for(b=0;b<c;b++) cin>>a[b];
typedef long long ll;
vector<int> ans,adj[200007];
bool vis[200007];
int inputorder[200007],relorder[200007];
bool cmp(int a,int b){
	return relorder[a]<relorder[b];
}
int main()
{
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n,x,a,b,i,j;
	cin>>n;
	for(i=0;i<n-1;i++){
		cin>>a>>b;
		adj[a].pb(b);
		adj[b].pb(a);
	}
	for(i=0;i<n;i++){
		cin>>inputorder[i];
		relorder[inputorder[i]]=i;
	}
	for(i=1;i<=n;i++)
		sort(all(adj[i]),cmp);
	queue<int> q;
	q.push(1);
	//cout<<adj[1][0]<<" "<<adj[1][1]<<endl;
	memset(vis,false,sizeof(vis));
	while(!(q.empty())){
		queue<int> temp;
		while(!(q.empty())){
			int x= q.front();
			q.pop();
			ans.pb(x);
			//cout<<x<<endl;
			vis[x]=true;
			for(j=0;j<adj[x].size();j++)
				if(vis[adj[x][j]]==false){cout<<adj[x][j]<<endl;
					temp.push(adj[x][j]);}
			}
		q=temp;
	}
	for(i=0;i<n;i++)
		if(inputorder[i]!=ans[i]){
			cout<<"No"; return 0;}
	cout<<"Yes";

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long

int main()
{
    ll n,x,y;
    cin>>n;
    vector<ll>v[n];
    for(ll i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--;y--;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    ll a[n];
    for(ll i=0;i<n;i++){
        cin>>a[i];a[i]--;}

    if(a[0]!=0)
    {
        cout<<"No";
        return 0;
    }
    queue<ll>q;
    q.push(0);
    ll ind = 1;
    while(!q.empty())
    {
        ll p = q.front();
        q.pop();
        while(v[p].size())
        {
            if(find(v[p].begin(),v[p].end(),a[ind])==v[p].end())
            {
                cout<<"No";
                return 0;
            }
            v[p].erase(std::remove(v[p].begin(), v[p].end(), a[ind]), v[p].end());
            v[a[ind]].erase(std::remove(v[a[ind]].begin(), v[a[ind]].end(), p), v[a[ind]].end());
            ind++;
        }
    }
    if(ind!=n)cout<<"No";else
    cout<<"Yes";
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool used2[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		used2[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used2[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to] && subtreeSize[to] > rootSize) isCentroid = false;
	}
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		//u = i;
		//v = i + 1;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	int lcnt = 0;
	while (!lastLayer.empty())
	{
		lcnt++;
		assert(lcnt < 40);
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>

using namespace std;

#define PB push_back
#define SZ(s) (int) s.size ()

using namespace std;

typedef vector<int> vi;

const int N = 200009;
const int inf = (int) 2e9;

int n;
int m;

int l;
int cnt;
int timer;
int tin[N];
int tout[N];
int dist[N];
int up[N][50];

int u[N];
int sz[N];
int par[N];
int ans[N];
int anspos[N];
vi g[N];
vi d[N];

void dfs0(int v, int p = 0) {
	tin[v] = timer++;
	up[v][0] = p;
	for (int i = 1; i <= l; i++) {
		up[v][i] = up[up[v][i - 1]][i - 1];
	}
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to != p) {
			dist[to] = dist[v] + 1;
			dfs0(to, v);
		}
	}
	tout[v] = timer++;
}
void dfs1(int v, int p = -1) {
	cnt++;
	sz[v] = 1;
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to == p || u[to]) {
			continue;
		}
		else {
			dfs1(to, v);
			sz[v] += sz[to];
		}
	}
}
int dfs2(int v, int p = -1) {
	int mx = cnt - sz[v];
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (!u[to] && to != p) {
			mx = max(mx, sz[to]);
		}
	}
	if (mx <= cnt / 2) {
		return v;
	}
	else {
		for (int i = 0; i < SZ(g[v]); i++) {
			int to = g[v][i];
			if (to == p || u[to]) {
				continue;
			}
			else {
				int res = dfs2(to, v);
				if (res != -1) {
					return res;
				}
			}
		}
	}
	return -1;
}
void dfs3(int v) {
	for (int i = 0; i < SZ(d[v]); i++) {
		int to = d[v][i];
		if (to != par[v]) {
			par[to] = v;
			dfs3(to);
		}
	}
}
int decompose(int v) {
	cnt = 0;
	dfs1(v);
	int c = dfs2(v);
	u[c] = 1;
	for (int i = 0; i < SZ(g[c]); i++) {
		int to = g[c][i];
		if (!u[to]) {
			to = decompose(to);
			d[c].PB(to);
			d[to].PB(c);
		}
	}
	return c;
}
bool upper(int a, int b) {
	return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca(int a, int b) {
	if (upper(a, b)) {
		return a;
	}
	else if (upper(b, a)) {
		return b;
	}
	else {
		for (int i = l; i >= 0; i--) {
			if (!upper(up[a][i], b)) {
				a = up[a][i];
			}
		}
		return up[a][0];
	}
}
int f(int a, int b) {
	return dist[a] + dist[b] - 2 * dist[lca(a, b)];
}
void update(int v) {
	int u = v;
	while (v) {
		if (f(u, v) < ans[v])
		{
			ans[v] = f(u, v);
			anspos[v] = u;
		}
		v = par[v];
	}
}
int get(int v) {
	int u = v;
	int res = inf;
	while (v) {
		if (anspos[v] != -1)
		{
			res = min(res, f(u,anspos[v]));
		}
		v = par[v];
	}
	return res;
}
int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n - 1; i++) {
		int a, b;
		scanf("%d %d", &a, &b);
		g[a].PB(b);
		g[b].PB(a);
	}
	while ((1 << l) <= n) {
		l++;
	}
	dfs0(1);
	int c = decompose(1);
	for (int i = 1; i <= n; i++) {
		par[i] = -1;
		ans[i] = inf;
		anspos[i] = -1;
	}
	dfs3(c);
	for (int i = 1; i <= n; i++) {
		if (i != c) {
			assert(par[i] != -1);
		}
	}
	update(1);
	while (m--) {
		int t, v;
		scanf("%d %d", &t, &v);
		if (t == 1) {
			update(v);
		}
		else {
			printf("%d\n", get(v));
		}
	}
	return 0;
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearUsed(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
}
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	int lcnt = 0;
	while (!lastLayer.empty())
	{
		lcnt++;
		assert(lcnt < 40);
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool used2[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		used2[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used2[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to] && subtreeSize[to] > rootSize) isCentroid = false;
	}
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		//u = i;
		//v = i + 1;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	int lcnt = 0;
	while (!lastLayer.empty())
	{
		lcnt++;
		assert(lcnt < 40);
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearUsed(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
}
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to] && subtreeSize[to] > rootSize) isCentroid = false;
	}
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	int lcnt = 0;
	while (!lastLayer.empty())
	{
		lcnt++;
		assert(lcnt < 40);
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool used2[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		used2[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used2[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to] && subtreeSize[to] > rootSize) isCentroid = false;
	}
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used2[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		//u = i;
		//v = i + 1;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	int lcnt = 0;
	while (!lastLayer.empty())
	{
		lcnt++;
		assert(lcnt < 40);
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}

#include <bits/stdc++.h>

using namespace std;

#define PB push_back
#define SZ(s) (int) s.size ()

using namespace std;

typedef vector<int> vi;

const int N = 200009;
const int inf = (int) 2e9;

int n;
int m;

int l;
int cnt;
int timer;
int tin[N];
int tout[N];
int dist[N];
int up[N][50];

int u[N];
int sz[N];
int par[N];
int ans[N];
int anspos[N];
vi g[N];
vi d[N];

void dfs0(int v, int p = 0) {
	tin[v] = timer++;
	up[v][0] = p;
	for (int i = 1; i <= l; i++) {
		up[v][i] = up[up[v][i - 1]][i - 1];
	}
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to != p) {
			dist[to] = dist[v] + 1;
			dfs0(to, v);
		}
	}
	tout[v] = timer++;
}
void dfs1(int v, int p = -1) {
	cnt++;
	sz[v] = 1;
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to == p || u[to]) {
			continue;
		}
		else {
			dfs1(to, v);
			sz[v] += sz[to];
		}
	}
}
int dfs2(int v, int p = -1) {
	int mx = cnt - sz[v];
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (!u[to] && to != p) {
			mx = max(mx, sz[to]);
		}
	}
	if (mx <= cnt / 2) {
		return v;
	}
	else {
		for (int i = 0; i < SZ(g[v]); i++) {
			int to = g[v][i];
			if (to == p || u[to]) {
				continue;
			}
			else {
				int res = dfs2(to, v);
				if (res != -1) {
					return res;
				}
			}
		}
	}
	return -1;
}
void dfs3(int v) {
	for (int i = 0; i < SZ(d[v]); i++) {
		int to = d[v][i];
		if (to != par[v]) {
			par[to] = v;
			dfs3(to);
		}
	}
}
int decompose(int v) {
	cnt = 0;
	dfs1(v);
	int c = dfs2(v);
	u[c] = 1;
	for (int i = 0; i < SZ(g[c]); i++) {
		int to = g[c][i];
		if (!u[to]) {
			to = decompose(to);
			d[c].PB(to);
			d[to].PB(c);
		}
	}
	return c;
}
bool upper(int a, int b) {
	return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca(int a, int b) {
	if (upper(a, b)) {
		return a;
	}
	else if (upper(b, a)) {
		return b;
	}
	else {
		for (int i = l; i >= 0; i--) {
			if (!upper(up[a][i], b)) {
				a = up[a][i];
			}
		}
		return up[a][0];
	}
}
int f(int a, int b) {
	return dist[a] + dist[b] - 2 * dist[lca(a, b)];
}
void update(int v) {
	int u = v;
	while (v) {
		if (f(u, v) < ans[v])
		{
			ans[v] = min(ans[v], f(u, v));
			anspos[v] = v;
		}
		v = par[v];
	}
}
int get(int v) {
	int u = v;
	int res = inf;
	while (v) {
		if (anspos[v] != -1)
		{
			res = min(res, f(v, anspos[u]) + f(u, v));
		}
		v = par[v];
	}
	return res;
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n - 1; i++) {
		int a, b;
		scanf("%d %d", &a, &b);
		g[a].PB(b);
		g[b].PB(a);
	}
	while ((1 << l) <= n) {
		l++;
	}
	dfs0(1);
	int c = decompose(1);
	for (int i = 1; i <= n; i++) {
		par[i] = -1;
		ans[i] = inf;
		anspos[i] = -1;
	}
	dfs3(c);
	for (int i = 1; i <= n; i++) {
		if (i != c) {
			assert(par[i] != -1);
		}
	}
	update(1);
	while (m--) {
		int t, v;
		scanf("%d %d", &t, &v);
		if (t == 1) {
			update(v);
		}
		else {
			printf("%d\n", get(v));
		}
	}
	return 0;
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearUsed(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
}
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	while (!lastLayer.empty())
	{
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>

using namespace std;

#define PB push_back
#define SZ(s) (int) s.size ()

using namespace std;

typedef vector<int> vi;

const int N = 200009;
const int inf = (int) 2e9;

int n;
int m;

int l;
int cnt;
int timer;
int tin[N];
int tout[N];
int dist[N];
int up[N][50];

int u[N];
int sz[N];
int par[N];
int ans[N];
int anspos[N];
vi g[N];
vi d[N];

void dfs0(int v, int p = 0) {
	tin[v] = timer++;
	up[v][0] = p;
	for (int i = 1; i <= l; i++) {
		up[v][i] = up[up[v][i - 1]][i - 1];
	}
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to != p) {
			dist[to] = dist[v] + 1;
			dfs0(to, v);
		}
	}
	tout[v] = timer++;
}
void dfs1(int v, int p = -1) {
	cnt++;
	sz[v] = 1;
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (to == p || u[to]) {
			continue;
		}
		else {
			dfs1(to, v);
			sz[v] += sz[to];
		}
	}
}
int dfs2(int v, int p = -1) {
	int mx = cnt - sz[v];
	for (int i = 0; i < SZ(g[v]); i++) {
		int to = g[v][i];
		if (!u[to] && to != p) {
			mx = max(mx, sz[to]);
		}
	}
	if (mx <= cnt / 2) {
		return v;
	}
	else {
		for (int i = 0; i < SZ(g[v]); i++) {
			int to = g[v][i];
			if (to == p || u[to]) {
				continue;
			}
			else {
				int res = dfs2(to, v);
				if (res != -1) {
					return res;
				}
			}
		}
	}
	return -1;
}
void dfs3(int v) {
	for (int i = 0; i < SZ(d[v]); i++) {
		int to = d[v][i];
		if (to != par[v]) {
			par[to] = v;
			dfs3(to);
		}
	}
}
int decompose(int v) {
	cnt = 0;
	dfs1(v);
	int c = dfs2(v);
	u[c] = 1;
	for (int i = 0; i < SZ(g[c]); i++) {
		int to = g[c][i];
		if (!u[to]) {
			to = decompose(to);
			d[c].PB(to);
			d[to].PB(c);
		}
	}
	return c;
}
bool upper(int a, int b) {
	return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca(int a, int b) {
	if (upper(a, b)) {
		return a;
	}
	else if (upper(b, a)) {
		return b;
	}
	else {
		for (int i = l; i >= 0; i--) {
			if (!upper(up[a][i], b)) {
				a = up[a][i];
			}
		}
		return up[a][0];
	}
}
int f(int a, int b) {
	return dist[a] + dist[b] - 2 * dist[lca(a, b)];
}
void update(int v) {
	int u = v;
	while (v) {
		if (f(u, v) < ans[v])
		{
			ans[v] = min(ans[v], f(u, v));
			anspos[v] = v;
		}
		v = par[v];
	}
}
int get(int v) {
	int u = v;
	int res = inf;
	while (v) {
		if (anspos[v] != -1)
		{
			res = min(res, f(v, anspos[u]) + f(u, v));
		}
		v = par[v];
	}
	return res;
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n - 1; i++) {
		int a, b;
		scanf("%d %d", &a, &b);
		g[a].PB(b);
		g[b].PB(a);
	}
	while ((1 << l) <= n) {
		l++;
	}
	dfs0(1);
	int c = decompose(1);
	for (int i = 1; i <= n; i++) {
		par[i] = -1;
		ans[i] = inf;
		anspos[i] = -1;
	}
	dfs3(c);
	for (int i = 1; i <= n; i++) {
		if (i != c) {
			assert(par[i] != -1);
		}
	}
	update(1);
	while (m--) {
		int t, v;
		scanf("%d %d", &t, &v);
		if (t == 1) {
			update(v);
		}
		else {
			printf("%d\n", get(v));
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define PB push_back
#define SZ(s) (int) s.size ()

using namespace std;

typedef vector<int> vi;

const int N = 200009;
const int inf = (int) 2e9;

int n;
int m;

int l;
int cnt;
int timer;
int tin[N];
int tout[N];
int dist[N];
int up[N][50];

int u[N];
int sz[N];
int par[N];
int ans[N];

vi g[N];
vi d[N];

void dfs0 (int v, int p = 0) {
        tin[v] = timer++;
        up[v][0] = p;
        for (int i = 1; i <= l; i++) {
                up[v][i] = up[up[v][i - 1]][i - 1];
        }
        for (int i = 0; i < SZ (g[v]); i++) {
                int to = g[v][i];
                if (to != p) {
                        dist[to] = dist[v] + 1;
                        dfs0 (to, v);
                }
        }
        tout[v] = timer++;
}
void dfs1 (int v, int p = -1) {
        cnt++;
        sz[v] = 1;
        for (int i = 0; i < SZ (g[v]); i++) {
                int to = g[v][i];
                if (to == p || u[to]) {
                        continue;
                } else {
                        dfs1 (to, v);
                        sz[v] += sz[to];
                }
        }
}
int dfs2 (int v, int p = -1) {
        int mx = cnt - sz[v];
        for (int i = 0; i < SZ (g[v]); i++) {
                int to = g[v][i];
                if (!u[to] && to != p) {
                        mx = max (mx, sz[to]);
                }
        }
        if (mx <= cnt / 2) {
                return v;
        } else {
                for (int i = 0; i < SZ (g[v]); i++) {
                        int to = g[v][i];
                        if (to == p || u[to]) {
                                continue;
                        } else {
                                int res = dfs2 (to, v);
                                if (res != -1) {
                                        return res;
                                }
                        }
                }
        }
        return -1;
}
void dfs3 (int v) {
        for (int i = 0; i < SZ (d[v]); i++) {
                int to = d[v][i];
                if (to != par[v]) {
                        par[to] = v;
                        dfs3 (to);
                }
        }
}
int decompose (int v) {
        cnt = 0;
        dfs1 (v);
        int c = dfs2 (v);
        u[c] = 1;
        for (int i = 0; i < SZ (g[c]); i++) {
                int to = g[c][i];
                if (!u[to]) {
                        to = decompose (to);
                        d[c].PB (to);
                        d[to].PB (c);
                }
        }
        return c;
}
bool upper (int a, int b) {
        return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca (int a, int b) {
        if (upper (a, b)) {
                return a;
        } else if (upper (b, a)) {
                return b;
        } else {
                for (int i = l; i >= 0; i--) {
                        if (!upper (up[a][i], b)) {
                                a = up[a][i];
                        }
                }
                return up[a][0];
        }
}
int f (int a, int b) {
        return dist[a] + dist[b] - 2 * dist[lca (a, b)];
}
void update (int v) {
        int u = v;
        while (v != -1) {
                ans[v] = min (ans[v], f (u, v));
                v = par[v];
        }
}
int get (int v) {
        int u = v;
        int res = inf;
        while (v != -1) {
                res = min (res, ans[v] + f (u, v));
                v = par[v];
        }
        return res;
}
int main () {
        scanf ("%d %d", &n, &m);
        for (int i = 1; i <= n - 1; i++) {
                int a, b;
                scanf ("%d %d", &a, &b);
                g[a].PB (b);
                g[b].PB (a);
        }
        while ((1 << l) <= n) {
                l++;
        }
        dfs0 (1);
        int c = decompose (1);
        for (int i = 1; i <= n; i++) {
                par[i] = -1;
                ans[i] = inf;
        }
        dfs3 (c);
        for (int i = 1; i <= n; i++) {
                if (i != c) {
                        assert (par[i] != -1);
                }
        }
        update (1);
        while (m--) {
                int t, v;
                scanf ("%d %d", &t, &v);
                if (t == 1) {
                        update (v);
                } else {
                        printf ("%d\n", get (v));
                }
        }
        return 0;
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<list>
#include<cmath>
#include<bitset>
#include<cassert>
using namespace std;
const int MAXN = 100 * 1000 + 7, LOGMAXN = 20;
const int INF = 1000 * 1000 * 1000 + 7;
vector<int>tree[MAXN];
int height[MAXN], timeIn[MAXN], timeOut[MAXN];
int ancestor[MAXN][LOGMAXN];
bool used[MAXN];
bool wasCentroid[MAXN];
int subtreeSize[MAXN];
int decompositionParent[MAXN];
int bestLen[MAXN], bestPos[MAXN];
int dfsTimer = 1;
void clearUsed(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
}
void clearFull(int n)
{
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
		subtreeSize[i] = 0;
	}
}
void precalcLCA(int v, int parent = 1, int curHeight = 1)
{
	used[v] = true;
	timeIn[v] = dfsTimer;
	dfsTimer++;
	ancestor[v][0] = parent;
	height[v] = curHeight;
	for (int i = 1; i < LOGMAXN; i++)
	{
		ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1];
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to])
		{
			precalcLCA(to, v, curHeight + 1);
		}
	}
	timeOut[v] = dfsTimer;
	dfsTimer++;
}
bool isAncestor(int u, int v)
{
	return timeIn[u] <= timeIn[v] && timeOut[u] >= timeOut[v];
}
int LCA(int u, int v)
{
	for (int i = LOGMAXN - 1; i >= 0; i--)
	{
		if (!isAncestor(ancestor[u][i], v))
		{
			u = ancestor[u][i];
		}
	}
	return ancestor[u][0];
}
int verticalPathLength(int u, int v)
{
	return height[v] - height[u];
}
int pathLength(int u, int v)
{
	if (isAncestor(u, v))
	{
		return verticalPathLength(u, v);
	}
	else if (isAncestor(v, u))
	{
		return verticalPathLength(v, u);
	}
	else
	{
		int lca = LCA(u, v);
		return verticalPathLength(lca, u) + verticalPathLength(lca, v);
	}
}
void calcSizes(int v)
{
	used[v] = true;
	subtreeSize[v] = 1;
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			calcSizes(to);
			subtreeSize[v] += subtreeSize[to];
		}
	}
}
int findCentroid(int v, int rootSize = -1, int upSize = 0)
{
	used[v] = true;
	if (rootSize == -1)
	{
		rootSize = (subtreeSize[v] + 1) / 2;
	}
	int ans = -1;
	bool isCentroid = true;
	if (upSize > rootSize) isCentroid = false;
	if (isCentroid)
	{
		ans = v;
	}
	for (int i = 0; i < tree[v].size(); i++)
	{
		int to = tree[v][i];
		if (!used[to] && !wasCentroid[to])
		{
			int tmp = findCentroid(to, rootSize, upSize + subtreeSize[v] - subtreeSize[to]);
			if (tmp != -1)
			{
				ans = tmp;
			}
		}
	}
	return ans;
}
void color(int v)
{
	int u = v;
	while (u != -1)
	{
		int curLen = pathLength(u, v);
		if (curLen < bestLen[u])
		{
			bestLen[u] = curLen;
			bestPos[u] = v;
		}
		u = decompositionParent[u];
	}
}
int findNearest(int v)
{
	int u = v;
	int ans = INF;
	while (u != -1)
	{
		if (bestPos[u] != -1)
		{
			ans = min(ans, pathLength(bestPos[u], v));
		}
		u = decompositionParent[u];
	}
	return ans;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	precalcLCA(1);
	clearFull(n);
	calcSizes(1);
	int decompositionRoot = findCentroid(1);
	decompositionParent[decompositionRoot] = -1;
	wasCentroid[decompositionRoot] = true;
	vector<int>lastLayer;
	lastLayer.push_back(decompositionRoot);
	for (int layer = 1; layer <= n; layer *= 2)
	{
		clearFull(n);
		vector<int>newCentroids;
		for (int i = 0; i < lastLayer.size(); i++)
		{
			int v = lastLayer[i];
			for (int j = 0; j < tree[v].size(); j++)
			{
				int to = tree[v][j];
				if (!wasCentroid[to] && !used[to])
				{
					calcSizes(to);
					int curCenter = findCentroid(to);
					decompositionParent[curCenter] = v;
					wasCentroid[curCenter] = true;
					newCentroids.push_back(curCenter);
				}
			}
		}
		lastLayer = newCentroids;
	}
	for (int i = 1; i <= n; i++)
	{
		bestLen[i] = INF;
		bestPos[i] = -1;
	}
	color(1);
	for (int i = 1; i <= m; i++)
	{
		int type;
		scanf("%d", &type);
		if (type == 1)
		{
			int v;
			scanf("%d", &v);
			color(v);
		}
		else
		{
			int v;
			scanf("%d", &v);
			printf("%d\n", findNearest(v));
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb push_back
const int N = 100005;
const int inf = 1e7;
bool deb = 0;

bool vis[N],centroid[N];
int subsize[N],c_depth[N],c_parent[N],ans[N],pa[N][18],depth[N];
vector<int> graph[N],c_graph[N];
void dfs(int u)
{
	vis[u] = 1;
	subsize[u] = 1;
	for(int v:graph[u])
	{
		if(!vis[v] && !centroid[v])
			{dfs(v);subsize[u]+=subsize[v];}
	}
}
int getCentroid(int u)
{
	int sz = subsize[u];
	int heavy_node;
	bool is;
	int vv = u;
	while(1)
	{
		heavy_node = 0;
		vis[u]=1;
		for(int v:graph[u])
		{
			if(!vis[v] && !centroid[v])
			{
				if(subsize[v]>sz/2)
					is = 0;
				if(heavy_node==0 || subsize[v]>subsize[heavy_node])
					heavy_node = v;
			}
		}
		if(is && sz-subsize[u]<=sz/2)
			return u;
		u = heavy_node;
		if(vv==u)
			return u;
		vv = u;
	}
}
int decompose(int u,int p)
{
	fill(vis,vis+N,0);
	fill(subsize,subsize+N,0);
	dfs(u);
	fill(vis,vis+N,0);
	int c = getCentroid(u);
	centroid[c]=1;
	c_depth[c] = c_depth[p]+1;
	c_parent[c] = p;
	for(int v:graph[c])
	{
		if(v==p)continue;
		int cs = decompose(v,c);
		c_graph[cs].pb(c);
		c_graph[c].pb(cs);
	}
	return c;
}
int c_lca(int u,int v)
{
	while(c_depth[u]<c_depth[v])
		v = c_parent[v];
	while(c_depth[u]>c_depth[v])
		u = c_parent[u];
	while(u!=v)
		u = c_parent[u],v = c_parent[v];
	return u;
}
void dfs2(int u,int p)
{
	depth[u] = depth[p]+1;
	pa[u][0] = p;
	for(int v:graph[u])
	{
		if(v==p) continue;
		dfs2(v,u);
	}
}
int pre(int n)
{
	for(int k=1;k<18;k++)
		for(int u=1;u<=n;u++)
			pa[u][k] = pa[pa[u][k-1]][k-1];
}
int lca(int u,int v)
{
	if(depth[u]>depth[v])
		swap(u,v);
	for(int k=17;k>=0;k--)
	{
		if(depth[pa[v][k]]>=depth[u])
			v = pa[v][k];
	}
	if(u==v)
		return u;
	for(int k=17;k>=0;k--)
	{
		if(pa[u][k]!=pa[v][k])
			u=pa[u][k],v=pa[v][k];
	}
	return pa[u][0];
}
int dist(int u,int v)
{
	return depth[u]+depth[v]-2*depth[lca(u,v)];
}
int main()
{
	//freopen("inputf.txt","r",stdin);
	int n,m,u,v,t;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		ans[i] = inf;
	for(int i=1;i<n;i++)
	{
		scanf("%d %d",&u,&v);
		graph[u].pb(v);
		graph[v].pb(u);
	}
	int c_root = decompose(1,0);
	dfs2(1,0);
	pre(n);
	ans[c_root] = min(ans[c_root],dist(1,c_root));
	int x = 1;
	while(x!=c_root)
	{
		ans[x] = min(ans[x],dist(x,1));
		x = c_parent[x];
	}
	while(m--)
	{
		scanf("%d %d",&t,&v);
		if(t==1)
		{
			ans[c_root] = min(ans[c_root],dist(v,c_root));
			int x = v;
			while(x!=c_root)
			{
				ans[x] = min(ans[x],dist(x,v));
				x = c_parent[x];
			}
		}
		else
		{
			int mini = dist(v,c_root)+ans[c_root];
			int x = v;
			while(x!=c_root)
			{
				mini = min(mini,dist(v,x)+ans[x]);
				x = c_parent[x];
			}
			printf("%d\n",mini);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb insert
const int inf = 1e7;
const int LOGN = 18;
const int N = int(1e5) + 10;

int n,m,nn;
set<int> graph[N];
int dp[LOGN][N],depth[N],sub[N],ans[N],par[N];
void dfs2(int u,int p)
{
	for(int v:graph[u])
	{
		if(v==p) continue;
		dp[0][v] = u;
		depth[v] = depth[u]+1;
		dfs2(v,u);
	}
}
void preprocess()
{
	depth[1] = 0;
	dp[0][1] = 1;
	dfs2(1,0);
	for(int k=1;k<LOGN;k++)
		for(int i=1;i<=n;i++)
			dp[k][i] = dp[k-1][dp[k-1][i]];
}
int lca(int u,int v)
{
	if(depth[u]>depth[v])swap(u,v);
	int d = depth[v]-depth[u];
	for(int k=LOGN-1;k>=0;k--)
	{
		if(d&(1<<k))
			v = dp[k][v];
	}
	if(u==v)
		return u;
	for(int k=LOGN-1;k>=0;k--)
	{
		if(dp[k][u]!=dp[k][v])
			u=dp[k][u],v=dp[k][v];
	}
	return dp[0][u];
}
int dist(int a,int b)
{
	return depth[a]+depth[b]-2*depth[lca(a,b)];
}
//->centroid decomposition
void dfs(int u,int p)
{
	sub[u]=1;
	for(int v:graph[u])
	{
		if(v!=p)
			{dfs(v,u);sub[u]+=sub[v];}
	}
}
int dfs1(int u,int p)
{
	for(int v:graph[u])
		if(v!=p && sub[v]>nn/2)
			return dfs1(v,u);
	return u;
}
void decompose(int u,int p)
{
	nn = 0;
	dfs(u,0);
	int c = dfs1(u,0);
	if(p==0) p = c;
	par[c] = p;
	for(int v:graph[c])
	{
		graph[v].erase(c);
		decompose(v,c);
	}
	graph[c].clear();
}
//->Queries
void update(int u)
{
	int x = u;
	while(1)
	{
		ans[x] = min(ans[x],dist(x,u));
		if(x==par[x])
			return;
		x = par[x];
	}
}
int query(int u)
{
	int x = u,val=inf;
	while(1)
	{
		val = min(val,dist(u,x)+ans[x]);
		if(x==par[x])
			return val;
		x = par[x];
	}
}
int main()
{
	//freopen("inputf.txt","r",stdin);
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int u,v;
		scanf("%d %d",&u,&v);
		graph[u].pb(v);
		graph[v].pb(u);
	}
	preprocess();
	decompose(1,0);
	for(int i=1;i<=n;i++)
		ans[i] = inf;
	update(1);
	while(m--)
	{
		int t,v;
		scanf("%d %d",&t,&v);
		if(t==1)
			update(v);
		else
			printf("%d\n",query(v));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb insert
const int inf = 1e7;
const int LOGN = 18;
const int N = int(1e5) + 10;

int n,m,nn;
set<int> graph[N];
int dp[LOGN][N],depth[N],sub[N],ans[N],par[N];
void dfs2(int u,int p)
{
	for(int v:graph[u])
	{
		if(v==p) continue;
		dp[0][v] = u;
		depth[v] = depth[u]+1;
		dfs2(v,u);
	}
}
void preprocess()
{
	depth[1] = 0;
	dp[0][1] = 1;
	dfs2(1,0);
	for(int k=1;k<LOGN;k++)
		for(int i=1;i<=n;i++)
			dp[k][i] = dp[k-1][dp[k-1][i]];
}
int lca(int u,int v)
{
	if(depth[u]>depth[v])swap(u,v);
	int d = depth[v]-depth[u];
	for(int k=LOGN-1;k>=0;k--)
	{
		if(d&(1<<k))
			v = dp[k][v];
	}
	if(u==v)
		return u;
	for(int k=LOGN-1;k>=0;k--)
	{
		if(dp[k][u]!=dp[k][v])
			u=dp[k][u],v=dp[k][v];
	}
	return dp[0][u];
}
int dist(int a,int b)
{
	return depth[a]+depth[b]-2*depth[lca(a,b)];
}
//->centroid decomposition
void dfs(int u,int p)
{
	sub[u]=1;
	for(int v:graph[u])
	{
		if(v!=p)
			{dfs(v,u);sub[u]+=sub[v];}
	}
}
int dfs1(int u,int p)
{
	for(int v:graph[u])
		if(v!=p && sub[v]>nn/2)
			return dfs1(v,u);
	return u;
}
void decompose(int root,int p)
{
	nn=0;
	dfs1(root,root);
	int centroid = dfs1(root,root);
	if(p==-1)p=centroid;
	par[centroid]=p;
	for(auto it=graph[centroid].begin();it!=graph[centroid].end();it++)
	{
		graph[*it].erase(centroid);
		decompose(*it,centroid);
	}
	graph[centroid].clear();
}
//->Queries
void update(int u)
{
	int x = u;
	while(1)
	{
		ans[x] = min(ans[x],dist(x,u));
		if(x==par[x])
			break;
		x = par[x];
	}
}
int query(int u)
{
	int x = u;
	int ret=inf;
	while(1)
	{
		ret = min(ret,dist(u,x) + ans[x]);
		if(x==par[x])
			break;
		x = par[x];
	}
	return ret;
}
int main()
{
	//freopen("inputf.txt","r",stdin);
	scanf("%d %d",&n,&m);
	for(int i=0;i<n-1;i++)
	{
		int u,v;
		scanf("%d %d",&u,&v);
		graph[u].pb(v);
		graph[v].pb(u);
	}
	preprocess();
	decompose(1,-1);
	for(int i=1;i<=n;i++)
		ans[i] = inf;
	update(1);
	while(m--)
	{
		int t,v;
		scanf("%d %d",&t,&v);
		if(t==1)
			update(v);
		else
			printf("%d\n",query(v));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb push_back
const int N = 100005;
const int inf = 1e7;
const int LOGN = 18;

bool vis[N],centroid[N];
int subsize[N],c_depth[N],c_parent[N],ans[N],pa[N][21],depth[N],nn;
vector<int> graph[N],c_graph[N];
void dfs(int u)
{
	vis[u] = 1;
	nn++;
	for(int v:graph[u])
	{
		if(!vis[v] && !centroid[v])
			{dfs(v);subsize[u]+=subsize[v];}
	}
	subsize[u]++;
}
int getCentroid(int u)
{
	int sz = nn;
	int heavy_node;
	bool is;
	while(1)
	{
		is = 1;
		heavy_node = 0;
		vis[u]=1;
		for(int v:graph[u])
		{
			if(!vis[v] && !centroid[v])
			{
				if(subsize[v]>sz/2)
					is = 0;
				if(heavy_node==0 || subsize[v]>subsize[heavy_node])
					heavy_node = v;
			}
		}
		if(is)
			return u;
		u = heavy_node;
	}
}
int decompose(int u,int p)
{
	fill(vis,vis+N,0);
	fill(subsize,subsize+N,0);
	nn = 0;
	dfs(u);
	fill(vis,vis+N,0);
	int c = getCentroid(u);
	centroid[c]=1;
	c_depth[c] = c_depth[p]+1;
	c_parent[c] = p;
	for(int v:graph[c])
	{
		if(!centroid[v])
		{
			int cs = decompose(v,c);
			c_graph[cs].pb(c);
			c_graph[c].pb(cs);
		}
	}
	return c;
}
int c_lca(int u,int v)
{
	while(c_depth[u]<c_depth[v])
		v = c_parent[v];
	while(c_depth[u]>c_depth[v])
		u = c_parent[u];
	while(u!=v)
		u = c_parent[u],v = c_parent[v];
	return u;
}
void dfs2(int u,int p)
{
	depth[u] = depth[p]+1;
	pa[u][0] = p;
	for(int v:graph[u])
	{
		if(v==p) continue;
		dfs2(v,u);
	}
}
int pre(int n)
{
	for(int k=1;k<21;k++)
		for(int u=1;u<=n;u++)
			pa[u][k] = pa[pa[u][k-1]][k-1];
}
int lca(int u,int v)
{
	if(depth[u]>depth[v])swap(u,v);
	int d = depth[v]-depth[u];
	for(int k=LOGN-1;k>=0;k--)
	{
		if(d&(1<<k))
			v = pa[v][k];
	}
	if(u==v)
		return u;
	for(int k=LOGN-1;k>=0;k--)
	{
		if(pa[u][k]!=pa[v][k])
			u=pa[u][k],v=pa[v][k];
	}
	return pa[u][0];
}
int dist(int u,int v)
{
	return depth[u]+depth[v]-2*depth[lca(u,v)];
}
/*void dfs3(int u,int p)
{
	cout<<u<<endl;
	for(int v:c_graph[u])
	{
		if(v==p)continue;
		dfs3(v,u);
	}
}*/
int main()
{
	//freopen("inputf.txt","r",stdin);
	int n,m,u,v,t;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		ans[i] = inf;
	for(int i=1;i<n;i++)
	{
		scanf("%d %d",&u,&v);
		graph[u].pb(v);
		graph[v].pb(u);
	}
	int c_root = decompose(1,0);
	dfs2(1,0);
	pre(n);
	ans[c_root] = min(ans[c_root],dist(1,c_root));
	int x = 1;
	while(x!=c_root)
	{
		ans[x] = min(ans[x],dist(x,1));
		x = c_parent[x];
	}
	while(m--)
	{
		scanf("%d %d",&t,&v);
		if(t==1)
		{
			ans[c_root] = min(ans[c_root],dist(v,c_root));
			int x = v;
			while(x!=c_root)
			{
				ans[x] = min(ans[x],dist(x,v));
				x = c_parent[x];
			}
		}
		else
		{
			int mini = dist(v,c_root)+ans[c_root];
			int x = v;
			while(x!=c_root)
			{
				mini = min(mini,dist(v,x)+ans[x]);
				x = c_parent[x];
			}
			printf("%d\n",mini);
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define pb push_back
const int N = 100005;
const int inf = 1e7;

bool vis[N],centroid[N];
int subsize[N],c_depth[N],c_parent[N],ans[N],pa[N][18],depth[N];
vector<int> graph[N],c_graph[N];
void dfs(int u)
{
	vis[u] = 1;
	subsize[u] = 1;
	for(int v:graph[u])
	{
		if(!vis[v] && !centroid[v])
			{dfs(v);subsize[u]+=subsize[v];}
	}
}
int getCentroid(int u)
{
	int sz = subsize[u];
	int heavy_node;
	bool is;
	int vv = u;
	while(1)
	{
		is = 1;
		heavy_node = 0;
		vis[u]=1;
		for(int v:graph[u])
		{
			if(!vis[v] && !centroid[v])
			{
				if(subsize[v]>sz/2)
					is = 0;
				if(heavy_node==0 || subsize[v]>subsize[heavy_node])
					heavy_node = v;
			}
		}
		if(is && sz-subsize[u]<=sz/2)
			return u;
		u = heavy_node;
		if(vv==u)
			return u;
		vv = u;
	}
}
int decompose(int u,int p)
{
	fill(vis,vis+N,0);
	fill(subsize,subsize+N,0);
	dfs(u);
	fill(vis,vis+N,0);
	int c = getCentroid(u);
	centroid[c]=1;
	c_depth[c] = c_depth[p]+1;
	c_parent[c] = p;
	for(int v:graph[c])
	{
		if(v==p)continue;
		int cs = decompose(v,c);
		c_graph[cs].pb(c);
		c_graph[c].pb(cs);
	}
	return c;
}
int c_lca(int u,int v)
{
	while(c_depth[u]<c_depth[v])
		v = c_parent[v];
	while(c_depth[u]>c_depth[v])
		u = c_parent[u];
	while(u!=v)
		u = c_parent[u],v = c_parent[v];
	return u;
}
void dfs2(int u,int p)
{
	depth[u] = depth[p]+1;
	pa[u][0] = p;
	for(int v:graph[u])
	{
		if(v==p) continue;
		dfs2(v,u);
	}
}
int pre(int n)
{
	for(int k=1;k<18;k++)
		for(int u=1;u<=n;u++)
			pa[u][k] = pa[pa[u][k-1]][k-1];
}
int lca(int u,int v)
{
	if(depth[u]>depth[v])
		swap(u,v);
	for(int k=17;k>=0;k--)
	{
		if(depth[pa[v][k]]>=depth[u])
			v = pa[v][k];
	}
	if(u==v)
		return u;
	for(int k=17;k>=0;k--)
	{
		if(pa[u][k]!=pa[v][k])
			u=pa[u][k],v=pa[v][k];
	}
	return pa[u][0];
}
int dist(int u,int v)
{
	return depth[u]+depth[v]-2*depth[lca(u,v)];
}
/*void dfs3(int u,int p)
{
	cout<<u<<endl;
	for(int v:c_graph[u])
	{
		if(v==p)continue;
		dfs3(v,u);
	}
}*/
int main()
{
	//freopen("inputf.txt","r",stdin);
	int n,m,u,v,t;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		ans[i] = inf;
	for(int i=1;i<n;i++)
	{
		scanf("%d %d",&u,&v);
		graph[u].pb(v);
		graph[v].pb(u);
	}
	int c_root = decompose(1,0);
	dfs2(1,0);
	pre(n);
	ans[c_root] = min(ans[c_root],dist(1,c_root));
	int x = 1;
	while(x!=c_root)
	{
		ans[x] = min(ans[x],dist(x,1));
		x = c_parent[x];
	}
	while(m--)
	{
		scanf("%d %d",&t,&v);
		if(t==1)
		{
			ans[c_root] = min(ans[c_root],dist(v,c_root));
			int x = v;
			while(x!=c_root)
			{
				ans[x] = min(ans[x],dist(x,v));
				x = c_parent[x];
			}
		}
		else
		{
			int mini = dist(v,c_root)+ans[c_root];
			int x = v;
			while(x!=c_root)
			{
				mini = min(mini,dist(v,x)+ans[x]);
				x = c_parent[x];
			}
			printf("%d\n",mini);
		}
	}
	return 0;
}