rt
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e5 + 10;
const int MAXH = 22;
inline int read()
{
int x = 0; char ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
return x;
}
inline void write (int x)
{
if (x > 9) write(x / 10);
putchar (x % 10 + 48);
}
int n, m;
struct Edge { int to, nxt; }e[(MAXN - 1) << 1]; int head[MAXN], cnt;
int fa[MAXN], V[MAXN], tag[MAXN];
int tot, rt[MAXN], ch[MAXN * 25][2], num[MAXN * 25], xorv[MAXN * 25];
inline void add (int u, int v) { e[++ cnt] = (Edge){v, head[u]}, head[u] = cnt; }
void dfs (int u, int f)
{
fa[u] = f;
for (register int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == f) continue;
dfs (v, u);
}
}
inline int getv (int x) { return ((fa[x] == -1 ? 0 : tag[fa[x]]) + V[x]); }
inline int _new() { ++ tot; ch[tot][0] = ch[tot][1] = num[tot] = xorv[tot] = 0; return tot; }
inline void push_up (int cur)
{
num[cur] = xorv[cur] = 0;
if (ch[cur][0]) num[cur] += num[ch[cur][0]], xorv[cur] ^= (xorv[ch[cur][0]] << 1);
if (ch[cur][1]) num[cur] += num[ch[cur][1]], xorv[cur] ^= ((xorv[ch[cur][1]] << 1) | (num[ch[cur][1]] & 1));
}
void insert (int &cur, int x, int h)
{
if (!cur) cur = _new();
if (h > 21) return (void)(++ num[cur]);
insert (ch[cur][x & 1], x >> 1, h + 1);
push_up (cur);
}
void erase (int cur, int x, int h)
{
if (h > 21) return (void)(-- num[cur]);
erase (ch[cur][x & 1], x >> 1, h + 1);
push_up (cur);
}
void all_add (int cur)
{
swap (ch[cur][0], ch[cur][1]);
if (ch[cur][0]) all_add(ch[cur][0]);
push_up (cur);
}
inline void work()
{
n = read(), m = read();
for (register int i = 1, u, v; i < n; ++ i)
u = read(), v = read(), add(u, v), add(v, u);
dfs (1, -1);
for (register int i = 1; i <= n; ++ i)
{
V[i] = read();
if (fa[i] != -1) insert(rt[fa[i]], V[i], 1);
}
while (m --)
{
int opt = read(), x = read();
if (opt == 1)
{
++ tag[x];
if (x != 1)
{
if (fa[fa[x]] != -1) erase(rt[fa[fa[x]]], getv(fa[x]), 1);
++ V[fa[x]];
if (fa[fa[x]] != -1) insert(rt[fa[fa[x]]], getv(fa[x]), 1);
}
all_add (rt[x]);
}
else if (opt == 2)
{
int v = read();
if (x != 1) erase(rt[fa[x]], getv(x), 1);
V[x] -= v;
if (x != 1) insert(rt[fa[x]], getv(x), 1);
}
else
{
int ans = 0;
ans = (xorv[rt[x]] ^ getv(fa[x]));
write(ans), putchar('\n');
}
}
}
signed main()
{
work();
return 0;
}