#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m;
int tr[N<<2];
void pushup(int p){tr[p]=tr[p<<1]+tr[p<<1|1];}
void update(int p,int pl,int pr,int x)
{
if(x<pl||pr<x)
return ;
if(pl==x&&pr==x)
{
tr[p]^=1;
return ;
}
int mid=(pl+pr)>>1;
update(p<<1,pl,mid,x);
update(p<<1|1,mid+1,pr,x);
pushup(p);
}
int query(int p,int pl,int pr,int L,int R)
{
if(R<pl||pr<L)
return 0;
if(L<=pl&&pr<=R)
return tr[p];
int mid=(pl+pr)>>1;
return query(p<<1,pl,mid,L,R)+query(p<<1|1,mid+1,pr,L,R);
}
vector<int>edge[N];
int dp[N][21],dep[N],sz[N],son[N];
int dfn[N],rnk[N],top[N],id;
void dfs1(int u,int ft)
{
dp[u][0]=ft;
dep[u]=dep[ft]+1;
sz[u]=1;
son[u]=-1;
for(int i=1;i<=20;++i)
dp[u][i]=dp[dp[u][i-1]][i-1];
for(auto &v:edge[u])
{
if(v==ft)
continue;
dfs1(v,u);
sz[u]+=sz[v];
if(son[u]==-1||sz[v]>sz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int t)
{
top[u]=t;
dfn[u]=++id;
rnk[id]=u;
if(~son[u])
dfs2(son[u],t);
for(auto &v:edge[u])
{
if(v==son[u]||v==dp[u][0])
continue;
dfs2(v,v);
}
}
int calc(int x,int k)
{
int res=x;
for(int i=20;i>=0;--i)
if(k&(1<<i))
res=dp[res][i];
return res;
}
int qrange(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
res+=query(1,1,n,dfn[top[x]],dfn[x]);
x=dp[top[x]][0];
}
if(dep[x]>dep[y])
swap(x,y);
return res+query(1,1,n,dfn[x],dfn[y]);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<n;++i)
{
int u,v;
cin>>u>>v;
edge[u].emplace_back(v);
edge[v].emplace_back(u);
}
dfs1(1,0);
dfs2(1,1);
while(m--)
{
int op,x;
cin>>op>>x;
if(!op)
update(1,1,n,dfn[x]);
else
{
if(qrange(x,x))
{
cout<<x<<'\n';
continue;
}
int l=0,r=n+1;
while(l+1<r)
{
int mid=(l+r)>>1;
if(!calc(x,mid)||qrange(x,calc(x,mid)))
r=mid;
else
l=mid;
}
if(!calc(x,r))
cout<<"-1\n";
else
cout<<calc(x,r)<<'\n';
}
}
}