rt,MLE 90pts on #10。
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define N 200006
using namespace std;
namespace IO
{
int read()
{
int ret=0,bas=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')bas=-1,ch=getchar();
while(isdigit(ch))ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();
return bas*ret;
}
void write(int k)
{
if(!k)return;
write(k/10);
putchar(k%10^48);
}
void print(int k)
{
if(k==0)putchar('0');
else if(k<0)putchar('-'),write(-k);
else write(k);
}
}
using namespace IO;
struct Node{int to,next;}edge[N<<1];
struct Tree{priority_queue<int> q1,q2;}tree[N<<2];
struct Link{int l,r;}link0[N];
struct Ask{int x,y,z;}ask[N];
int head[N],cnt,n,m;
int dep[N],fa[N],son[N],siz[N],top[N],id[N],tmp_id[N],dfn;
void init()
{
for(int i=0;i<(N<<1);i++)edge[i].next=-1;
for(int i=0;i<N;i++)head[i]=-1;
cnt=0;
}
void addedge(int u,int v)
{
edge[cnt]={v,head[u]};
head[u]=cnt++;
}
void dfs1(int u,int fath)
{
dep[u]=dep[fath]+1,siz[u]=1,fa[u]=fath;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fath)continue;
dfs1(v,u);
if(!son[u]||siz[son[u]]<siz[v])son[u]=v;
siz[u]+=siz[v];
}
}
void dfs2(int u,int fath,int p)
{
top[u]=p,id[u]=++dfn,tmp_id[dfn]=u;
if(!son[u])return;
dfs2(son[u],u,p);
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fath)continue;
if(v==son[u])continue;
dfs2(v,u,v);
}
}
void add(int p,int x){tree[p].q1.push(x);}
void del(int p,int x){tree[p].q2.push(x);}
int find(int p)
{
while(!tree[p].q2.empty()&&tree[p].q1.top()==tree[p].q2.top())
tree[p].q1.pop(),tree[p].q2.pop();
if(tree[p].q1.empty())return -1;
return tree[p].q1.top();
}
void update1(int p,int l,int r,int L,int R,int k)
{
if(L==l&&r==R){add(p,k);return;}
int mid=l+r>>1;
if(R<=mid)update1(p<<1,l,mid,L,R,k);
else if(L>mid)update1(p<<1|1,mid+1,r,L,R,k);
else update1(p<<1,l,mid,L,mid,k),update1(p<<1|1,mid+1,r,mid+1,R,k);
}
void update2(int p,int l,int r,int L,int R,int k)
{
if(L==l&&r==R){del(p,k);return;}
int mid=l+r>>1;
if(R<=mid)update2(p<<1,l,mid,L,R,k);
else if(L>mid)update2(p<<1|1,mid+1,r,L,R,k);
else update2(p<<1,l,mid,L,mid,k),update2(p<<1|1,mid+1,r,mid+1,R,k);
}
int query(int p,int l,int r,int k)
{
if(l==r)return find(p);
int mid=l+r>>1,ret=find(p);
if(k<=mid)ret=max(ret,query(p<<1,l,mid,k));
else ret=max(ret,query(p<<1|1,mid+1,r,k));
return ret;
}
bool cmp(Link x,Link y)
{
if(x.l!=y.l)return x.l<y.l;
return x.r<y.r;
}
void update_range1(int u,int v,int w)
{
int num=0,L=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
link0[++num]={id[top[u]],id[u]};
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
link0[++num]={id[v],id[u]};
sort(link0+1,link0+1+num,cmp);
for(int i=1;i<=num;i++)
{
if(L+1<link0[i].l)update1(1,1,n,L+1,link0[i].l-1,w);
L=max(L,link0[i].r);
}
if(L+1<=n)update1(1,1,n,L+1,n,w);
}
void update_range2(int u,int v,int w)
{
int num=0,L=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
link0[++num]={id[top[u]],id[u]};
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
link0[++num]={id[v],id[u]};
sort(link0+1,link0+1+num,cmp);
for(int i=1;i<=num;i++)
{
if(L+1<link0[i].l)update2(1,1,n,L+1,link0[i].l-1,w);
L=max(L,link0[i].r);
}
if(L+1<=n)update2(1,1,n,L+1,n,w);
}
main()
{
init();
n=read(),m=read();
for(int i=1,u,v;i<n;i++)
{
u=read(),v=read();
addedge(u,v),addedge(v,u);
}
dfs1(1,0),dfs2(1,0,1);
for(int i=1;i<=m;i++)
{
int opt=read();
if(opt==0)
{
int u=read(),v=read(),w=read();
ask[i]={u,v,w};
update_range1(u,v,w);
}
if(opt==1)
{
int now=read();
update_range2(ask[now].x,ask[now].y,ask[now].z);
}
if(opt==2)
{
int x=read();
print(query(1,1,n,id[x]));
putchar('\n');
}
}
return 0;
}