#include #include #include #include #include #include #define NN 100005 #define INF 0x3f3f3f3f #define pb push_back using namespace std; ofstream out("lca.out"); ifstream in("mind.in"); int n , m ; int K; int Lev[ NN * 2 ] , Eul[ NN * 2] , First[ NN ] ; int arb[ NN << 4]; int lsol , sol , st , dr; vector < int > G[NN]; typedef vector< int >::iterator IT; bitset < NN > uz; void Read(); void Dfs( int start , int level ); void build( int nod , int li , int lf ); void query( int nod , int li , int lf ); int lca( int x , int y ); int main() { Read(); Dfs(1,0); build(1,1,K); for( ; m ; --m ) { int x , y; int cod; cin >> cod; if( cod == 2 ) { cin >> x >> y; int ll = lca(x , y); if( ll == x || ll == y ) cout << -1 << '\n'; else cout << ll << '\n'; } else { cin >> x; uz.reset(); memset(Lev,0,sizeof(Lev)); memset(Eul,0,sizeof(Lev)); memset(First,0,sizeof(Lev)); memset(arb,0,sizeof(Lev)); Dfs(x,0); build(1,1,K); } } return 0; } void Read() { cin >> n >> m; for( int i=1 ; i> x >> y; G[x].pb(y); G[y].pb(x); } } void Dfs( int nod , int level ) { uz[nod] = 1; Eul[ ++K ] = nod; Lev[ K ] = level; First[ nod ] = K; for( IT i = G[nod].begin(); i!=G[nod].end(); ++i) if(!uz[*i]) { Dfs( *i , level + 1 ); Eul[ ++K ] = nod; Lev[ K ] = level; } } void build( int nod , int li , int lf ) { if( li == lf ) { arb[nod] = li; return; } int mid = ( li + lf ) >> 1; build( ( nod << 1 ) , li , mid ); build( ( nod << 1 ) + 1 , mid + 1 ,lf ); if( Lev[arb[ (nod<<1) ]] <= Lev[arb[ (nod<<1)+1]] ) arb[nod] = arb[(nod<<1)]; else arb[nod] = arb[(nod<<1)+1]; } void query( int nod , int li , int lf ) { if( st <=li && lf <= dr) { if( Lev[arb[nod]] < lsol ) sol = Eul[arb[nod]] , lsol = Lev[arb[nod]]; return; } int mid = ( li + lf ) >> 1; if( st <= mid ) query( ( nod << 1 ) , li , mid ); if( mid < dr ) query( ( nod << 1 ) + 1 , mid + 1 , lf ); } int lca( int x , int y ) { st = First[x]; dr = First[y]; if( st > dr ) swap(st,dr); sol = lsol = INF; query(1,1,K); return sol; }