1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<cstring>
5 #include<algorithm>
6 using namespace std;
7 char ch;
8 bool ok;
9 void read(int &x){
10 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
11 for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
12 if (ok) x=-x;
13 }
14 const int maxn=200005;
15 const int maxm=maxn*2;
16 int n,cnt,m,a,b;
17 struct Graph{
18 int tot,idx,now[maxn],son[maxm],pre[maxm],fa[maxn][18],dep[maxn],dfn[maxn],last[maxn];
19 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
20 void add(int a,int b){put(a,b),put(b,a);}
21 void dfs(int u){
22 dfn[u]=++idx;
23 for (int i=0;fa[u][i];i++) fa[u][i+1]=fa[fa[u][i]][i];
24 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (v!=fa[u][0]) fa[v][0]=u,dep[v]=dep[u]+1,dfs(v);
25 last[u]=idx;
26 }
27 void swim(int &u,int h){for (int i=17;h;i--) if (h>=(1<<i)) h-=(1<<i),u=fa[u][i];}
28 int get_lca(int u,int v){
29 if (dep[u]<dep[v]) swap(u,v);
30 swim(u,dep[u]-dep[v]);
31 if (u==v) return u;
32 for (int i=17;i>=0;i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
33 return fa[u][0];
34 }
35 bool in(int u,int v){return dfn[u]<=dfn[v]&&dfn[v]<=last[u];}
36 }G;
37 struct Chain{
38 int u,v,lca;
39 bool in(int x){
40 if (lca>0) return G.in(lca,x)&&(G.in(x,u)||G.in(x,v));
41 if (lca==0) return 1;
42 return 0;
43 }
44 };
45 Chain merge(Chain a,Chain b){
46 if (a.lca==-1||b.lca==-1) return (Chain){0,0,-1};
47 if (!a.lca) return b;
48 if (!b.lca) return a;
49 if (G.dep[a.lca]<G.dep[b.lca]) swap(a,b);
50 if (!b.in(a.lca)) return (Chain){0,0,-1};
51 int lcau=G.get_lca(a.u,b.u),lcav=G.get_lca(a.v,b.v);
52 return (Chain){G.dep[lcau]<G.dep[a.lca]?a.lca:lcau,G.dep[lcav]<G.dep[a.lca]?a.lca:lcav,a.lca};
53 }
54 struct Querys{
55 int op,u,t,pos;
56 }querys[maxn];
57 struct Data{
58 Chain ch;
59 int val,id;
60 void init(int i){read(ch.u),read(ch.v),ch.lca=G.get_lca(ch.u,ch.v),read(val),id=i;}
61 }list[maxn];
62 bool cmp(const Data &a,const Data &b){return a.val<b.val;}
63 int tot;
64 struct seg{
65 Chain chain[maxn<<2];
66 bool exist[maxn<<2];
67 void modify(int k,int l,int r,int x,Chain ch){
68 if (l==r){chain[k]=ch;return;}
69 int m=(l+r)>>1;
70 if (x<=m) modify(k<<1,l,m,x,ch); else modify((k<<1)+1,m+1,r,x,ch);
71 chain[k]=merge(chain[k<<1],chain[(k<<1)+1]);
72 }
73 Chain query(int k,int l,int r,int x){
74 if (l==x) return chain[k];
75 int m=(l+r)>>1;
76 if (x<=m) return merge(query(k<<1,l,m,x),chain[(k<<1)+1]);
77 else return query((k<<1)+1,m+1,r,x);
78 }
79 void modify(int x,int op){if (op==1) modify(1,1,cnt,x,list[x].ch); else modify(1,1,cnt,x,(Chain){0,0,0});}
80 Chain query(int x){return query(1,1,cnt,x);}
81 int query2(int k,int l,int r,int u){
82 if (l==r) return list[l].val;
83 int m=(l+r)>>1;
84 if (chain[(k<<1)+1].in(u)) return query2(k<<1,l,m,u);
85 else return query2((k<<1)+1,m+1,r,u);
86 }
87 int query2(int u){return query2(1,1,cnt,u);}
88 }T;
89 int query(int u){
90 if (!tot) return -1;
91 Chain ch=T.query(1);
92 if (ch.in(u)) return -1;
93 return T.query2(u);
94 }
95 int main(){
96 read(n),read(m);
97 for (int i=1;i<n;i++) read(a),read(b),G.add(a,b);
98 G.dfs(1);
99 for (int i=1;i<=m;i++){
100 read(querys[i].op);
101 if (querys[i].op==0) list[++cnt].init(i);
102 else if (querys[i].op==1) read(querys[i].t);
103 else read(querys[i].u);
104 }
105 sort(list+1,list+cnt+1,cmp);
106 for (int i=1;i<=cnt;i++) querys[list[i].id].pos=i;
107 for (int i=1;i<=m;i++){
108 if (querys[i].op==0) T.modify(querys[i].pos,1),tot++;
109 else if (querys[i].op==1) T.modify(querys[querys[i].t].pos,-1),tot--;
110 else printf("%d\n",query(querys[i].u));
111 }
112 return 0;
113 }