#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
#define ls(p) ch[p][0]
#define rs(p) ch[p][1]
int n, m, op, u, v;
struct Splay {
int ch[MAXN][2], fa[MAXN], siz[MAXN], val[MAXN], ans[MAXN], rev[MAXN];
void clear(int x) {
ch[x][0] = ch[x][1] = fa[x] = siz[x] = val[x] = ans[x] = rev[x] = 0;
}
void push_up(int p) {
clear(0);
siz[p] = siz[ls(p)] + siz[rs(p)] + 1;
ans[p] = ans[ls(p)] ^ ans[rs(p)] ^ val[p];
}
void push_down(int p) {
clear(0);
if(val[p]) {
if(ls(p)) val[ls(p)] ^= val[p], ans[ls(p)] ^= val[p];
if(rs(p)) val[rs(p)] ^= val[p], ans[rs(p)] ^= val[p];
val[p] = 0;
}
if(rev[p]) {
if(ls(p)) swap(ls(ls(p)), rs(ls(p))), rev[ls(p)] ^= 1;
if(rs(p)) swap(ls(rs(p)), rs(rs(p))), rev[rs(p)] ^= 1;
rev[p] = 0;
}
}
int getch(int x) {
return rs(fa[x]) == x;
}
int isroot(int x) {
clear(0);
return ls(fa[x]) != x && rs(fa[x]) != x;
}
void update(int x) {
if(!isroot(x)) update(fa[x]);
push_down(x);
}
void rotate(int x) {
int y = fa[x], z = fa[y], chx = getch(x), chy = getch(y);
if(!isroot(y)) ch[z][chy] = x;
ch[y][chx] = ch[x][chx ^ 1];
fa[ch[x][chx ^ 1]] = y;
ch[x][chx ^ 1] = y;
fa[y] = x;
fa[x] = z;
push_up(y);
push_up(x);
push_up(z);
}
void splay(int x) {
for(int f = fa[x]; f = fa[x], !isroot(x); rotate(x))
if(!isroot(f))
rotate(getch(f) == getch(x) ? f : x);
}
int access(int x) {
int f = 0;
for(f = 0; x; f = x, x = fa[x])
splay(x), rs(x) = f, push_up(x);
return f;
}
void makeroot(int x) {
access(x);
splay(x);
swap(ls(x), rs(x));
rev[x] ^= 1;
}
void split(int x, int y) {
makeroot(x);
access(y);
splay(y);
}
void link(int x, int y) {
if(find(x) != find(y)) {
makeroot(x);
fa[x] = y;
}
}
void cut(int x, int y) {
makeroot(x);
access(y);
splay(y);
if(ls(y) == x && !rs(x)) ls(y) = fa[x] = 0;
}
int find(int x) {
access(x);
splay(x);
while(ls(x)) x = ls(x);
splay(x);
return x;
}
} st;
int main() {
ios :: sync_with_stdio(false);
cin >> n >> m;
for(int i = 1; i <= n; ++i) cin >> st.val[i], st.ans[i] = 0, st.push_up(i);
while(m--) {
cin >> op >> u >> v;
if(op == 0) {
st.split(u, v);
printf("%d\n", st.ans[v]);
}
else if(op == 1) {
st.link(u, v);
}
else if(op == 2) {
st.cut(u, v);
}
else if(op == 3) {
st.split(u, u);
st.ans[u] ^= st.val[u] ^ v;
st.val[u] = v;
}
}
return 0;
}