[题解]:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=1e5+;
struct edge{int v,next;}e[N<<];int tot,head[N],cur[N];
int n,m,top,st[N<<];
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void add(int x,int y){
e[++tot].v=y;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].next=head[y];head[y]=tot;
}
int dfs_cnt,dfn[N],end[N],pos[N];
int fa[N],fat[N][],dep[N];
void dfs(){
memcpy(cur,head,sizeof head);
int x;st[++top]=;dep[]=;
while(top){
con:
x=st[top];
if(!dfn[x]) dfn[x]=++dfs_cnt;
for(int &i=cur[x];i;){
if(e[i].v==fa[x]){i=e[i].next;continue;}
fa[e[i].v]=x;
fat[e[i].v][]=x;
dep[e[i].v]=dep[x]+;
st[++top]=e[i].v;
i=e[i].next;
goto con;
}
end[x]=dfs_cnt; top--;
}
for(int i=;i<=n;i++) pos[dfn[i]]=i;
}
const int M=N<<;
int mx[M],tag[M];
#define lch k<<1
#define rch k<<1|1
void build(int k,int l,int r){
if(l==r){
mx[k]=dep[pos[l]];return ;
}
int mid=l+r>>;
build(lch,l,mid);
build(rch,mid+,r);
mx[k]=max(mx[lch],mx[rch]);
}
void pushdown(int k){
if(!tag[k]) return ;
mx[lch]+=tag[k];
mx[rch]+=tag[k];
tag[lch]+=tag[k];
tag[rch]+=tag[k];
tag[k]=;
}
void plusx(int k,int l,int r,int x,int y,int val){
if(l==x&&r==y){
mx[k]+=val;
tag[k]+=val;
return ;
}
pushdown(k);
int mid=l+r>>;
if(y<=mid) plusx(lch,l,mid,x,y,val);
else if(x>mid) plusx(rch,mid+,r,x,y,val);
else plusx(lch,l,mid,x,mid,val),plusx(rch,mid+,r,mid+,y,val);
mx[k]=max(mx[lch],mx[rch]);
}
int ask(int k,int l,int r,int p){
if(l==r) return mx[k];
pushdown(k);
int mid=l+r>>;
if(p<=mid) return ask(lch,l,mid,p);
else return ask(rch,mid+,r,p);
}
int query(int k,int l,int r,int x,int y){
if(l==x&&r==y) return mx[k];
pushdown(k);
int mid=l+r>>;
if(y<=mid) return query(lch,l,mid,x,y);
else if(x>mid) return query(rch,mid+,r,x,y);
else return max(query(lch,l,mid,x,mid),query(rch,mid+,r,mid+,y));
}
int siz[N],ch[N][];
bool isroot(int x){
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(ch[y][]==x);r=l^;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
}
void splay(int x){
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if((ch[y][]==x)^(ch[z][]==y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
int findmin(int x){
if(!x) return ;
for(;ch[x][];x=ch[x][]);
return x;
}
void access(int x){
for(int y=,z;x;y=x,x=fa[x]){
splay(x);
z=findmin(ch[x][]);
if(z) plusx(,,n,dfn[z],end[z],);
if(fa[x]){
z=findmin(x);
plusx(,,n,dfn[z],end[z],-);
}
ch[x][]=y;
}
}
int lca(int a,int b){
if(dep[a]<dep[b]) swap(a,b);
int t=dep[a]-dep[b];
for(int i=;i<=;i++){
if((<<i)&t){
a=fat[a][i];
}
}
if(a==b) return a;
for(int i=;~i;i--){
if(fat[a][i]!=fat[b][i]){
a=fat[a][i];
b=fat[b][i];
}
}
return fat[a][];
}
int main(){
n=read();m=read();
for(int i=,x,y;i<n;i++) x=read(),y=read(),add(x,y);
dfs();
build(,,n);
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
fat[i][j]=fat[fat[i][j-]][j-];
}
}
for(int i=,opt,x,y,anc,ans;i<=m;i++){
opt=read();x=read();
if(opt==) access(x);
if(opt==){
y=read();
anc=lca(x,y);
ans=ask(,,n,dfn[x])+ask(,,n,dfn[y])-*ask(,,n,dfn[anc])+;
printf("%d\n",ans);
}
if(opt==) printf("%d\n",query(,,n,dfn[x],end[x]));
}
return ;
}