#include <bits/stdc++.h>
#define lx son[0]
#define rx son[1]
using namespace std;
int read()
{
int x = 0, f = 1;
char ch = 0;
while(!isdigit(ch))
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const int N = 100000;
struct Tr
{
int siz;
int sx, val;
int tg;
int fa, son[2];
Tr()
{
siz = sx = val = tg = fa = lx = rx = 0;
}
Tr(int k)
{
sx = val = k, siz = 1, tg = 0, fa = lx = rx = 0;
}
}tr[N + 5];
int rt, cntn;
void pushup(int x)
{
tr[x].sx = tr[tr[x].lx].sx ^ tr[tr[x].rx].sx ^ tr[x].val;
tr[x].siz = tr[tr[x].lx].siz + tr[tr[x].rx].siz + 1;
}
void pushdown(int x)
{
if(tr[x].tg)
{
swap(tr[x].lx, tr[x].rx);
tr[tr[x].lx].tg ^= 1, tr[tr[x].rx].tg ^= 1;
tr[x].tg = 0;
}
}
void update(int x)
{
if(!x)
{
return;
}
update(tr[x].fa);
pushdown(x);
}
bool isrt(int x)
{
return tr[tr[x].fa].lx != x && tr[tr[x].fa].rx != x;
}
int get(int x)
{
return x == tr[tr[x].fa].son[1];
}
void rtt(int x)
{
int f = tr[x].fa;
int ff = tr[f].fa;
pushdown(f);
pushdown(x);
int tx = get(x);
int tf = get(f);
if(ff)
{
tr[ff].son[tf] = x;
}
tr[x].fa = ff;
tr[f].son[tx] = tr[x].son[tx ^ 1];
tr[tr[x].son[tx ^ 1]].fa = f;
tr[x].son[tx ^ 1] = f;
tr[f].fa = x;
pushup(f);
pushup(x);
}
void splay(int x)
{
while(1)
{
if(isrt(x))
{
break;
}
if(isrt(tr[x].fa))
{
rtt(x);
break;
}
if(get(tr[x].fa) == get(x))
{
rtt(tr[x].fa);
}
else
{
rtt(x);
}
rtt(x);
}
}
int acs(int x)
{
update(x);
int y = 0;
while(x)
{
splay(x);
tr[x].rx = y;
pushup(x);
y = x;
x = tr[x].fa;
}
return y;
}
void mkr(int x)
{
tr[acs(x)].tg ^= 1;
}
int fnd(int x)
{
acs(x);
splay(x);
while(1)
{
if(!tr[x].lx)
{
break;
}
x = tr[x].lx;
}
splay(x);
return x;
}
void lnk(int x, int y)
{
if(fnd(x) == fnd(y))
{
return;
}
mkr(x);
acs(y);
tr[x].fa = y;
}
void spl(int x, int y)
{
mkr(x);
acs(y);
splay(y);
}
void cut(int x, int y)
{
spl(x, y);
if(tr[y].lx == x && !tr[x].rx)
{
tr[x].fa = tr[y].lx = 0;
pushup(y);
}
}
int n, q;
void init()
{
n = read(), q = read();
for(int i = 1; i <= n; i++)
{
tr[i] = Tr(read());
}
}
void solve()
{
while(q--)
{
int op = read();
if(op == 0)
{
int x = read(), y = read();
spl(x, y);
printf("%d\n", tr[y].sx);
}
else if(op == 1)
{
int x = read(), y = read();
lnk(x, y);
}
else if(op == 2)
{
int x = read(), y = read();
cut(x, y);
}
else
{
int x = read();
splay(x);
tr[x].val = read();
pushup(x);
}
}
}
int main()
{
freopen("lct.in", "r", stdin);
freopen("my.out", "w", stdout);
init();
solve();
return 0;
}
不知道哪里写假了……