#include #include #include #include #include #include #include #include #include #define in cin #define out cout #define abs(x) ((x>0)?(x):(-(x))) #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define FOR(i, a, b) for(int i = a; i <= b; ++i) #define DOWNFOR(i, a, b) for(int i = a; i >= b; --i) #define FOREACH(i, t) for (typeof(t.begin()) i = t.begin(); i != t.end(); ++i) using namespace std; typedef long long ll; const int Nmax = 100001; vector G[Nmax]; int T[Nmax],L[Nmax],H[Nmax]; int ChainFat[Nmax],PartOfChain[Nmax],NumChains; int N,M; int Dfs(int x,int lev){ L[x]=lev; H[x]=1; for(vector::iterator it=G[x].begin();it!=G[x].end();++it){ H[x]+=Dfs(*it,lev+1); } return H[x]; } void DfsChain(int x,int wh){ PartOfChain[x]=wh; int best=0,ch; for(vector::iterator it=G[x].begin();it!=G[x].end();++it){ if(H[*it]>best) best=H[*it],ch=*it; } for(vector::iterator it=G[x].begin();it!=G[x].end();++it){ if(*it==ch) DfsChain(*it,wh); else{ ChainFat[++NumChains]=x; DfsChain(*it,NumChains); } } } int lca(int x,int y){ while(PartOfChain[x]!=PartOfChain[y]){ if(L[ChainFat[PartOfChain[x]]]>L[ChainFat[PartOfChain[y]]]) x=ChainFat[PartOfChain[x]]; else y=ChainFat[PartOfChain[y]]; } if(L[x] P[Nmax]; int mm[Nmax]; void ddfs(int x){ mm[x]=1; FOREACH(t,P[x]) if(!mm[*t]){ G[x].push_back(*t); ddfs(*t); } } int gt(int r,int x,int y){ int xx=lca(r,x); int yy=lca(r,y); if(xx==r && yy==r){ int l=lca(x,y); if(l==x || l==y) return -1; return l; } else if(xx==r) return r; else if(yy==r) return r; else{ if(xx==yy){ int l=lca(x,y); if(l==x || l==y) return -1; return l; } else if(L[xx]>L[yy]){ if(x==xx) return -1; return xx; } else{ if(y==yy) return -1; return yy; } } } int main(){ #ifndef ONLINE_JUDGE ifstream in("test.in"); ofstream out("test.out"); #endif in>>N>>M; int t,x,y; FOR(i,1,N-1){ in>>x>>y; P[x].push_back(y); P[y].push_back(x); } ddfs(1); Dfs(1,1); DfsChain(1,++NumChains); int root=1; FOR(i,1,M){ in>>t; if(t==1){ in>>x; root=x; } if(t==2){ in>>x>>y; out<