#include <bits/stdc++.h>
#define N 100005
#define l(x) d[x].c[0]
#define r(x) d[x].c[1]
#define s(x) d[x].s
#define f(x) d[x].f
#define t(x) d[x].t
using namespace std;
inline void read(int &x)
{
x = 0; bool c = 1;
char ch = getchar();
while (ch < 48 || ch > 57)
{
c = !(ch == 45);
ch = getchar();
}
while (ch >= 48 && ch <= 57)
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
x = c ? x : -x;
}
struct node
{
int f, c[2], t, s;
node()
{
f = 0;
c[0] = c[1] = 0;
t = 0;
s = 0;
}
}d[N];
int n, m;
int vl[N];
inline void pu(int u){s(u) = s(l(u)) ^ s(r(u)) ^ vl[u];}
inline bool ntr(int u){return u == l(f(u)) || u == r(f(u));}
inline void pd(int u)
{
if (t(u))
{
swap(l(u), r(u));
if (l(u))
t(l(u)) ^= 1;
if (r(u))
t(r(u)) ^= 1;
t(u) = 0;
}
}
inline void rtt(int u)
{
int fa = f(u);
int g = f(fa);
bool k = (u == r(fa));
int w = d[u].c[k ^ 1];
d[fa].c[k] = w;
if (w)
f(w) = fa;
f(u) = g;
if (ntr(fa))
d[g].c[(fa == r(g))] = u;
f(fa) = u;
d[u].c[k ^ 1] = fa;
pu(fa);
}
int st[N], cnt;
inline void sp(int u)
{
int p = u;
cnt = 0;
while (ntr(p))
{
st[++cnt] = p;
p = f(p);
}
st[++cnt] = p;
while (cnt)
pd(st[cnt--]);
while (ntr(u))
{
int fa = f(u);
int g = f(fa);
if (ntr(fa))
rtt((u == r(fa)) == (fa == (r(g))) ? fa : u);
rtt(u);
}
pu(u);
}
inline void ac(int u)
{
for (register int r = 0; u; r = u, u = f(u))
{
sp(u);
r(u) = r;
pu(u);
}
}
inline void mk(int u)
{
ac(u);
sp(u);
t(u) ^= 1;
}
inline int fd(int u)
{
ac(u);
sp(u);
pd(u);
while (l(u))
{
u = l(u);
pd(u);
}
sp(u);
return u;
}
inline int sl(int u, int v)
{
mk(u);
ac(v);
sp(v);
}
inline void lk(int u, int v)
{
mk(u);
if (fd(v) == u)
return;
f(u) = v;
}
inline void ct(int u, int v)
{
mk(u);
if (fd(v) == u && f(v) == u && !l(v))
{
f(v) = r(u) = 0;
pu(u);
}
}
signed main(void)
{
read(n); read(m);
for (register int i = 1; i <= n; ++i)
read(vl[i]);
while (m--)
{
int op; read(op);
int u, v; read(u); read(v);
switch(op)
{
case 0:sl(u, v); printf("%d\n", s(v)); break;
case 1:lk(u, v); break;
case 2:ct(u, v); break;
case 3:sp(u); vl[u] = v; break;
}
}
return 0;
}