rt 人麻了
#include<bits/stdc++.h>
#define ls son[x][0]
#define rs son[x][1]
using namespace std;
const int N=2e5+10;
int son[N][2],fa[N],sum[N],v[N];
int lzy[N],sk[N],n,m,o;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
bool chk(int x){return x==son[fa[x]][1];}
bool rot(int x){return x==son[fa[x]][0]||x==son[fa[x]][1];}//true代表不是根
void psu(int x){sum[x]=sum[ls]^sum[rs]^v[x];}
void psr(int x){int t=ls;ls=rs,rs=t,lzy[x]^=1;}
void psd(int x){if(lzy[x])psr(ls),psr(rs),lzy[x]=0;}
void trn(int x)
{
int y=fa[x],z=fa[y],q=chk(x);
if(rot(y)&&z)
son[z][y==son[z][1]]=x;
son[y][q]=son[x][q^1];
if(son[x][q^1])
fa[son[x][q^1]]=y;
son[x][q^1]=y;
fa[x]=z,fa[y]=x;
psu(y);
}
void spl(int x)
{
int y=x,z=0;
sk[++z]=y;
while(rot(y))
sk[++z]=y=fa[y];
while(z)
psd(sk[z--]);
while(rot(x))
{
y=fa[x],z=fa[y];
if(rot(y))
{
if(chk(x)==chk(y))
trn(x);
else trn(y);
}
trn(x);
}
psu(x);
}
void acc(int x)
{
int y=0;
while(x)
spl(x),rs=y,psu(x),y=x,x=fa[x];
}
void mrt(int x){acc(x),spl(x),psr(x);}
int fid(int x)
{
acc(x),spl(x);
while(ls)
psd(x),x=ls;
spl(x);
return x;
}
void way(int x,int y){mrt(x),acc(y),spl(y);}
void cut(int x,int y)
{
mrt(x);
if(x!=fid(y)||fa[y]!=x||son[y][0])
return;
fa[y]=rs=0,psu(x);
}
void add(int x,int y)
{
mrt(x);
if(fid(y)!=x)//原树上不连通
fa[x]=y;
}
int main()
{
freopen("qqq.in","r",stdin);
freopen("ppp.txt","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
v[i]=read();
while(m--)
{
int op=read(),x=read(),y=read();
if(op==0)
way(x,y),printf("%d\n",sum[y]);
else if(op==1)
add(x,y);
else if(op==2)
cut(x,y);
else if(op==3)
spl(x),v[x]=y;
}
return 0;
}