调了很久,不知道错在哪里qwq
#include<bits/stdc++.h>
#define ll long long
#define x first
#define y second
#define il inline
#define debug() puts("-----")
using namespace std;
typedef pair<int,int> pii;
il int read(){
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
const int N=1e5+10,M=22;
int n,m;
int mp[N];
int top[N];
int h[N],idx=0;
int id[N],cnt=0;
int siz[N],son[N];
int f[N][M],dep[N];
struct Edge{
int to,ne;
}e[N<<1];
struct Node{
int l,r;
int w,col,tag;
}tr[N<<2];
il void add(int u,int v){
e[idx].to=v,e[idx].ne=h[u],h[u]=idx++;
}
il void dfs1(int u,int fa){
siz[u]=1; f[u][0]=fa,dep[u]=dep[fa]+1;
for(int j=1;j<M;j++) f[u][j]=f[f[u][j-1]][j-1];
for(int i=h[u];i!=-1;i=e[i].ne){
int to=e[i].to;
if(to==fa) continue;
dfs1(to,u); siz[u]+=siz[to];
if(siz[to]>siz[son[u]]) son[u]=to;
}
}
il void dfs2(int u,int Top){
top[u]=Top;
id[u]=++cnt,mp[cnt]=u;
if(son[u]) dfs2(son[u],Top);
for(int i=h[u];i!=-1;i=e[i].ne){
int to=e[i].to;
if(to==f[u][0]||to==son[u]) continue;
dfs2(to,to);
}
}
il int plc(int x,int k){
int p=0;
while(k){
if(k&1) x=f[x][k];
p++; k>>=1;
} return x;
}
il int LCA(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
x=plc(x,dep[x]-dep[y]);
if(x==y) return x;
for(int j=M-1;j>=0;j--) if(f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
return f[x][0];
}
il void pushup(int u){
tr[u].w=max(tr[u<<1].w,tr[u<<1|1].w);
}
il void pushdown(int u){
if(!tr[u].tag) return ;
tr[u<<1].w+=tr[u].tag,tr[u<<1|1].w+=tr[u].tag;
tr[u<<1].tag+=tr[u].tag,tr[u<<1|1].tag+=tr[u].tag;
tr[u].tag=0;
}
il void build(int u,int l,int r){
tr[u]={l,r};
if(l==r){
tr[u].col=mp[l];
tr[u].w=dep[mp[l]];
return ;
} int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
il void modify_col(int u,int l,int r,int col){
if(l<=tr[u].l&&tr[u].r<=r){
tr[u].col=col;
return ;
} int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) modify_col(u<<1,l,r,col);
if(r>mid) modify_col(u<<1|1,l,r,col);
}
il int query_col(int u,int x){
if(tr[u].l==tr[u].r) return tr[u].col;
int mid=tr[u].l+tr[u].r>>1;
if(x<=mid) return max(tr[u].col,query_col(u<<1,x));
return max(tr[u].col,query_col(u<<1|1,x));
}
il void modify(int u,int l,int r,int w){
if(l<=tr[u].l&&tr[u].r<=r){
tr[u].w+=w,tr[u].tag+=w;
return ;
} pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) modify(u<<1,l,r,w);
if(r>mid) modify(u<<1|1,l,r,w);
pushup(u);
}
il int query(int u,int l,int r){
if(l<=tr[u].l&&tr[u].r<=r) return tr[u].w;
pushdown(u); int w=0,mid=tr[u].l+tr[u].r>>1;
if(l<=mid) w=max(w,query(u<<1,l,r));
if(r>mid) w=max(w,query(u<<1|1,l,r));
return w;
}
int colbot[N<<1],coltop[N<<1];
il int kim(int x,int y){
for(int j=M-1;j>=0;j--) if(dep[f[x][j]]>dep[y]) x=f[x][j];
return x;
}
il void Modify(int x,int col){
int lst=0,Top;
colbot[col]=x,coltop[col]=1;
while(x){
int c=query_col(1,id[x]);
int w=query(1,id[x],id[x]);
int id1=top[x],id2=coltop[c];
if(dep[id1]<dep[id2]){
modify_col(1,id[id2],id[x],col);
modify(1,id[id2],id[id2]+siz[id2]-1,1-w);
if(lst) modify(1,id[lst],id[lst]+siz[lst]-1,w-1);
} else{
modify_col(1,id[id1],id[x],col);
modify(1,id[id1],id[id1]+siz[id1]-1,1-w);
if(lst) modify(1,id[lst],id[lst]+siz[lst]-1,w-1);
} if(x!=colbot[c]){
int y=kim(colbot[c],x);
if(y!=lst) modify(1,id[y],id[y]+siz[y]-1,1),Top=y;
} if(dep[id2]<dep[id1]) x=f[id1][0],lst=id1;
else x=f[id2][0],lst=id2,coltop[c]=Top;
}
}
signed main(){
memset(h,-1,sizeof h);
n=read(),m=read(); int col=n;
for(int i=1,u,v;i<n;i++) u=read(),v=read(),add(u,v),add(v,u);
dfs1(1,0),dfs2(1,1); build(1,1,n);
for(int i=1;i<=n;i++) colbot[i]=coltop[i]=i;
while(m--){
int opt=read(),x=read();
if(opt==1) Modify(x,++col);
else if(opt==2){
int y=read(),rt=LCA(x,y);
printf("%d\n",query(1,id[x],id[x])+query(1,id[y],id[y])-2*query(1,id[rt],id[rt])+1);
} else printf("%d\n",query(1,id[x],id[x]+siz[x]-1));
} return 0;
}