#include<bits/stdc++.h>
using namespace std;
int n,m;
namespace LCT {
const int MAXN=3e5+233;
int top,ch[MAXN][2],fa[MAXN],rev[MAXN],st[MAXN],val[MAXN],xr[MAXN];
int isroot(int x) {
return ch[fa[x]][ch[fa[x]][1]==x]!=x;
}
void push_down(int x) {
if (rev[x]) {
rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
}
void update(int x){
xr[x]=val[x]^xr[ch[x][0]]^xr[ch[x][1]];
}
void rotate(int x) {
int y=fa[x],z=fa[y],d=(ch[y][1]==x);
if (!isroot(y)) ch[z][ch[z][1]==y]=x;
fa[x]=z;
ch[y][d]=ch[x][d^1],fa[ch[x][d^1]]=y;
ch[x][d^1]=y,fa[y]=x;
update(y),update(x);
}
void splay(int x) {
int y;
st[top=1]=x;
for (y=x; !isroot(y); y=fa[y]) st[++top]=fa[y];
for (y=top; y; y--) push_down(st[y]);
for (; (y=fa[x])&&!isroot(x); rotate(x))
if (!isroot(y))
rotate((x==ch[y][0])^(y==ch[fa[y]][0]) ? x:y);
}
void access(int x){
for (int pre=0;x;pre=x,x=fa[x]) splay(x),ch[x][1]=pre,update(x);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=1;
}
void link(int x,int y){
makeroot(x),fa[x]=y;
}
void cut(int x,int y){
makeroot(x);
access(y);
splay(y);
if (ch[y][0]==x)
ch[y][0]=fa[x]=0;
}
int find(int x){
access(x),splay(x);
while (ch[x][0])
x=ch[x][0];
return x;
}
} using namespace LCT;
int read(){
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) x=x*10+ch-48,ch=getchar();
return x*f;
}
int main() {
n=read(),m=read();
for (int i=1;i<=n;i++)
xr[i]=val[i]=read();
int opt,x,y;
while (m--){
opt=read(),x=read(),y=read();
switch(opt){
case 0: makeroot(x);access(y);splay(y);printf("%d\n",xr[y]);break;
case 1: if (find(x)!=find(y)) link(x,y);break;
case 2: if (find(x)==find(y)) cut(x,y);break;
case 3: access(x);splay(x);val[x]=y;update(x);break;
}
}
return 0;
}