#include <bits/stdc++.h>
using namespace std;
struct node {
int l, r, root, ch[2], tag, fa, ans;
}t[1000005];
int w[1000005];
bool Get (int x) { return t[t[x].fa].ch[1] == x; }
bool isRoot (int x) {
return t[t[x].fa].ch[0] != x and t[t[x].fa].ch[1] != x;
}
void pushup (int x) { t[x].ans = t[t[x].ch[0]].ans ^ t[t[x].ch[1]].ans ^ w[x]; }
void reverse (int x) {
t[x].tag ^= 1; swap (t[x].ch[0], t[x].ch[1]);
}
void pushdown (int x) {
if (t[x].tag == 0) return;
if (t[x].ch[0]) reverse (t[x].ch[0]);
if (t[x].ch[1]) reverse (t[x].ch[1]);
t[x].tag = 0;
}
void update (int x) {
if (!isRoot (x)) update (t[x].fa);
pushdown (x);
}
void rotate (int x) {
int fa = t[x].fa, ffa = t[fa].fa, _ = Get (x);
if (!isRoot (x)) t[ffa].ch[Get (fa)] = x; t[x].fa = ffa;
t[fa].ch[_] = t[x].ch[_ ^ 1]; t[t[x].ch[_ ^ 1]].fa = fa;
t[x].ch[_ ^ 1] = fa; t[fa].fa = x;
pushup (fa), pushup (x);
}
void splay (int x) {
update (x);
for (int fa = t[x].fa; fa = t[x].fa, !isRoot (x); rotate (x))
if (!isRoot (fa)) rotate (Get (fa) == Get (x) ? fa : x);
}
void Access (int x) {
int p = 0;
for (p = 0; x; p = x, x = t[x].fa) {
splay (x); t[x].ch[1] = p; pushup (x);
}
}
void Make_Root (int x) { Access (x); splay (x); reverse (x); }
int Find_Root (int x) {
Access (x); splay (x);
while (t[x].ch[0]) pushdown (x), x = t[x].ch[0];
splay (x); return x;
}
void Link (int x, int y) {
Make_Root (x);
if (Find_Root (y) != x) t[x].fa = y;
}
void Cut (int x, int y) {
Make_Root (x);
if (Find_Root (y) == x and t[y].fa == x and t[y].ch[0] == 0) {
t[y].fa = t[x].ch[1] = 0;
pushup (x);
}
}
void split (int x, int y) {
Make_Root (x);
Access (y); splay (y);
}
int main () {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> w[i];
while (m --) {
int opt, x, y; cin >> opt >> x >> y;
if (opt == 0) split (x, y), cout << t[y].ans << "\n";
else if (opt == 1) Link (x, y);
else if (opt == 2) Cut (x, y);
else { splay (x); w[x] = y; pushup (x); }
cout << "cnm\n";
}
}