RT
#include<bits/stdc++.h>
#define MAXN 100002
using namespace std;
inline int read()
{
int f=1,w=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
return f*w;
}
struct Link_Cut_Tree{
int ch[MAXN][2],fa[MAXN],val[MAXN],tag[MAXN],laz[MAXN],num[MAXN];
int stk[MAXN],top;
void push_up(int x)
{
num[x]=num[ch[x][0]]^num[ch[x][1]]^val[x];
return;
}
void push_down(int x)
{
int l=ch[x][0],r=ch[x][1];
if(tag[x])
{
tag[l]^=1;tag[r]^=1;tag[x]^=1;
swap(ch[x][0],ch[x][1]);
}
return;
}
bool isroot(int x)
{
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(ch[y][0]==x)l=0;
else l=1;
r=l^1;
if(!isroot(y))
if(ch[z][0]==y)ch[z][0]=x;
else ch[x][1]=x;
fa[x]=z,fa[y]=x,fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
push_up(y);push_up(x);
return;
}
void splay(int x)
{
top=1;stk[top]=x;
for(int i=x;!isroot(i);i=fa[i])stk[++top]=fa[i];
for(int i=top;i;i--)push_down(stk[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
else rotate(y);
}
rotate(x);
}
return;
}
void access(int x)
{
for(int p=0;x;p=x,x=fa[x])
{
splay(x);
ch[x][1]=p;
push_up(x);
}
return;
}
void makeroot(int x)
{
access(x);
splay(x);
tag[x]^=1;
return;
}
int find(int x)
{
access(x);
splay(x);
while(ch[x][0])x=ch[x][0];
return x;
}
void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
return;
}
void link(int x,int y)
{
makeroot(x);
fa[x]=y;
return;
}
void cut(int x,int y)
{
split(x,y);
if(ch[y][0]==x&&ch[x][1]==0)ch[y][0]=0,fa[x]=0;
return;
}
}tree;
int n,m;
int main()
{
// freopen("P3690_1.in","r",stdin);
// freopen("P3690_1.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++)tree.val[i]=read(),tree.num[i]=tree.val[i];
for(int i=1;i<=m;i++)
{
int opt=read(),x=read(),y=read(),xx,yy;
switch(opt)
{
case 0:
tree.split(x,y);
printf("%d\n",tree.num[y]);
break;
case 1:
xx=tree.find(x),yy=tree.find(y);
if(xx!=yy)tree.link(x,y);
break;
case 2:
xx=tree.find(x),yy=tree.find(y);
if(xx==yy)tree.cut(x,y);
break;
case 3:
tree.access(x);
tree.splay(x);
tree.val[x]=y;
tree.push_up(x);
break;
default:
break;
}
}
return 0;
}