#include<bits/stdc++.h>
#define MAXN 500500
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
using namespace std;
int fa[MAXN],ch[MAXN][2],v[MAXN],s[MAXN],st[MAXN];
bool r[MAXN];
bool isroot(int x){
return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
}
bool get(int x){return rs(x)==x;}
void pushup(int x){s[x]=s[ls(x)]^s[rs(x)]^v[x];}
void pushdown(int x)
{
if(r[x]){
r[ls(x)]^=1,r[rs(x)]^=1,r[x]^=1;
swap(ls(x),rs(x));
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y],k=get(x);
if(!isroot(y))
ch[z][rs(z)==y]=x;
ch[y][k]=ch[x][!k],fa[ch[x][!k]]=y;
ch[x][!k]=y,fa[y]=x,fa[x]=z;
pushup(x),pushup(y);
}
void Update(int x){
if(isroot(x))Update(fa[x]);
pushdown(x);
}
void Splay(int x)
{
int y,z;
Update(x);
while(isroot(x)){
y=fa[x];z=fa[y];
if(isroot(y))
rotate((ls(y)==x)^(ls(z)==y)?x:y);
rotate(x);
}
pushup(x);
}
int access(int x){
for(int y=0;x;x=fa[x],y=x)
Splay(x),rs(x)=y,pushup(x);
}
int makeroot(int x){
access(x);Splay(x);pushup(x);
}
int findroot(int x){
access(x);Splay(x);pushup(x);
}
int split(int x,int y){
makeroot(x);access(y);Splay(y);
}
int link(int x,int y){
makeroot(x);
if(findroot(y)!=x)fa[x]=y;
}
int cut(int x,int y)
{
makeroot(x);
if(findroot(y)==x&&fa[y]==x&&!ls(y))
fa[y]=rs(x)=0,pushup(x);
}
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&v[i]);
while(m--)
{
int opt,x,y;
scanf("%d%d%d",&opt,&x,&y);
if(opt==0){split(x,y);printf("%d\n",s[y]);}
else if(opt==1)link(x,y);
else if(opt==2)cut(x,y);
else Splay(x),v[x]=y;
}
return 0;
}