#include <fstream>
#include <cmath>
#include <bitset>
#include <random>
using namespace std;
const int MAX_N = 100000 + 50;
const int MAX_BUCKET = 450 + 100;
const int MAX_S = 1e6 + 50;
const int MAGIK = 64;
const int NIL = -1;
struct Edge
{
int v;
int next;
};
Edge l[2 * MAX_N - 2];
int adj[MAX_N];
int E[MAX_N][2];
int nodeInEuler[2 * MAX_N];
int eulerPtr;
int sum[MAX_N + 1];
bitset <MAX_S + 2> D[MAX_BUCKET];
int lazy[MAX_BUCKET];
int BUCKET_SIZE;
int N;
void addEdge( int u, int v, int pos )
{
l[pos].v = v;
l[pos].next = adj[u];
adj[u] = pos;
}
void DFS( int u, int par )
{
E[u][0] = eulerPtr;
nodeInEuler[eulerPtr] = u;
eulerPtr++;
for ( int i = adj[u]; i != NIL; i = l[i].next )
if ( l[i].v != par )
DFS( l[i].v, u );
E[u][1] = eulerPtr;
nodeInEuler[eulerPtr] = N;
eulerPtr++;
}
inline int getRandom( void )
{
static mt19937 gen( time(0) );
int x = gen();
return x < 0 ? -x : x;
}
inline int randomSearch( const int &sum )
{
int bucket;
for ( int i = 0; i < MAGIK; i++ )
{
bucket = getRandom() % BUCKET_SIZE;
if ( sum >= lazy[bucket] && D[bucket][sum - lazy[bucket]] )
return bucket;
}
return BUCKET_SIZE;
}
int main(void)
{
ifstream in("arbore.in");
ofstream out("arbore.out");
in.tie( 0 );
ios_base::sync_with_stdio( 0 );
int M;
in >> N >> M;
for ( int i = 0; i < N; i++ )
adj[i] = NIL;
for ( int i = 1; i < N; i++ )
{
int u, v;
in >> u >> v;
addEdge( u - 1, v - 1, 2 * i - 2 );
addEdge( v - 1, u - 1, 2 * i - 1 );
}
DFS( 0, -1 );
BUCKET_SIZE = sqrt( eulerPtr - 1 ) + 1;
sum[N] = MAX_S + 1;
for ( int i = 0; i < BUCKET_SIZE; i++ )
D[i][0] = 1;
while ( M-- )
{
int opType;
in >> opType;
if ( opType == 1 )
{
int node, s, ptr, where, nextBucket;
in >> node >> s;
node--;
ptr = E[node][0];
where = ptr / BUCKET_SIZE;
nextBucket = ( where + 1 ) * BUCKET_SIZE;
for ( int i = where * BUCKET_SIZE; i < nextBucket; i++ )
D[where][ sum[ nodeInEuler[i] ] ] = 0;
for ( int i = where * BUCKET_SIZE; i < nextBucket; i++ )
sum[ nodeInEuler[i] ] += ( s & -( i <= E[node][1] ) );
for ( int i = where * BUCKET_SIZE; i < nextBucket; i++ )
D[where][ sum[ nodeInEuler[i] ] ] = 1;
if ( E[node][0] / BUCKET_SIZE == E[node][1] / BUCKET_SIZE )
continue;
ptr = ( ptr / BUCKET_SIZE + 1 ) * BUCKET_SIZE;
while ( ptr + BUCKET_SIZE <= E[node][1] )
{
lazy[ ptr / BUCKET_SIZE ] += s;
ptr += BUCKET_SIZE;
}
if ( ptr <= E[node][1] )
{
where = ptr / BUCKET_SIZE;
nextBucket = ( where + 1 ) * BUCKET_SIZE;
for ( int i = where * BUCKET_SIZE; i < nextBucket; i++ )
D[where][ sum[ nodeInEuler[i] ] ] = 0;
for ( int i = where * BUCKET_SIZE; i <= E[node][1]; i++ )
sum[ nodeInEuler[i] ] += s;
for ( int i = where * BUCKET_SIZE; i < nextBucket; i++ )
D[where][ sum[ nodeInEuler[i] ] ] = 1;
}
}
else
{
int s, tmp;
in >> s;
tmp = randomSearch( s );
if ( tmp == BUCKET_SIZE )
{
tmp = 0;
while ( (tmp < BUCKET_SIZE) && !D[tmp][s - lazy[tmp]] )
tmp++;
}
if ( tmp != BUCKET_SIZE )
{
int eulerPos = tmp * BUCKET_SIZE;
while ( eulerPos < ( tmp + 1 ) * BUCKET_SIZE && sum[ nodeInEuler[eulerPos] ] + lazy[tmp] != s )
eulerPos++;
out << 1 + nodeInEuler[eulerPos] << '\n';
}
else
out << "-1\n";
}
}
in.close();
out.close();
return 0;
}