#include <fstream>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cstring>
#include <iostream>

#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<n ; i++)
    {

        int x , y ;
        cin >> 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;

}