#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
inline int read(){
int x;
char c;
int f=1;
while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
if(c==‘-‘) c=getchar(),f=-1;
x=c^‘0‘;
while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1)+(x<<3)+(c^‘0‘);
return x*f;
}
inline ll readll(){
ll x;
char c;
ll f=1;
while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
if(c==‘-‘) c=getchar(),f=-1;
x=c^‘0‘;
while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1ll)+(x<<3ll)+(c^‘0‘);
return x*f;
}
const int maxn=3e5+10;
#define ls(x) (ch[x][0])
#define rs(x) (ch[x][1])
#define isr(x) (rs(fa[x])==x)
int stk[maxn],Top;
struct Link_cut_tree{
int sum[maxn],ch[maxn][2],fa[maxn],rev[maxn],val[maxn];
inline bool isroot(int x){
return rs(fa[x])!=x && ls(fa[x])!=x;
}
inline void push_up(int x){
sum[x]=sum[ls(x)]^sum[rs(x)]^val[x];
}
inline void push_down(int x){
if(rev[x]){
int l=ls(x),r=rs(x);
if(l) swap(ch[l][0],ch[l][1]),rev[l]^=1;
if(r) swap(ch[r][0],ch[r][1]),rev[r]^=1;
rev[x]=0;
}
}
inline void rotate(int x){
int f=fa[x],ff=fa[f],u=isr(x);
ch[fa[ch[x][u^1]]=f][u]=ch[x][u^1];
fa[x]=ff;if(!isroot(f)) ch[ff][isr(f)]=x;
ch[fa[f]=x][u^1]=f;
push_up(f);
}
inline void splay(int x){
stk[Top=1]=x;
for(int i=x;!isroot(i);i=fa[i]) stk[++Top]=fa[i];
DREP(i,Top,1) push_down(stk[i]);
for(;!isroot(x);rotate(x))
if(!isroot(fa[x])) rotate((isr(fa[x])^isr(x))?x:fa[x]);
push_up(x);
}
inline void access(int x){
for(int i=0;x;x=fa[i=x]) splay(x),ch[x][1]=i,push_up(x);
}
inline void makeroot(int x){
access(x),splay(x),rev[x]^=1,swap(ch[x][0],ch[x][1]);
}
inline int findroot(int x){
access(x),splay(x);
while(ch[x][0]) push_down(x),x=ch[x][0];
splay(x);return x;
}
inline void split(int x,int y){
makeroot(x),access(y),splay(y);
}
inline bool link(int x,int y){
makeroot(x);
if(findroot(y)==x) return 0;
fa[x]=y;return 1;
}
inline void cut(int x,int y){
split(x,y);
if(ch[y][0]==x) fa[x]=ch[y][0]=0;
}
}lct;
int main(){
#ifndef ONLINE_JUDGE
freopen("lct.in","r",stdin);
freopen("lct.out","w",stdout);
#endif
int n=read(),q=read();
REP(i,1,n) lct.val[i]=lct.sum[i]=read();
while(q--){
int ty=read(),x=read(),y=read();
if(ty==0) lct.split(x,y),printf("%d\n",lct.sum[y]);
else if(ty==1) lct.link(x,y);
else if(ty==2) lct.cut(x,y);
else lct.access(x),lct.splay(x),lct.val[x]=y,lct.push_up(x);
}
return 0;
}