/kk
#include <bits/stdc++.h>
const int N = 5e5 + 10;
int n, m, i, j, k, cen;
int value[N];
bool dbg;
struct Segment_Tree {
int rt[N], lc[N * 32], rc[N * 32], sum[N * 32];
int cntu;
Segment_Tree() {
cntu = 0;
}
void modify(int &u, int l, int r, int pos, int val) {
if (!u) u = ++cntu;
sum[u] += val;
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) {
modify(lc[u], l, mid, pos, val);
} else {
modify(rc[u], mid + 1, r, pos, val);
}
}
int query(int u, int l, int r, int ql, int qr) {
if (!u) return 0;
if (ql <= l && r <= qr) return sum[u];
int mid = (l + r) >> 1, res = 0;
if (ql <= mid) res += query(lc[u], l, mid, ql, qr);
if (mid < qr) res += query(rc[u], mid + 1, r, ql, qr);
return res;
}
} ST[2];
int par[N], anc[N][25], dep[N];
std::vector<int> g[N];
bool vis[N];
void dfs1(int u, int fa) {
anc[u][0] = fa, dep[u] = dep[fa] + 1;
for (int i = 1; i <= 20; i++) {
anc[u][i] = anc[anc[u][i - 1]][i - 1];
}
for (int v : g[u]) {
if (v == fa) continue;
dfs1(v, u);
}
}
inline int get_lca(int u, int v) {
if (dep[u] < dep[v]) std::swap(u, v);
for (int i = 20; i >= 0; i--) if (dep[u] - (1 << i) >= dep[v]) u = anc[u][i];
if (u == v) return u;
for (int i = 20; i >= 0; i--) {
if (anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
}
return anc[u][0];
}
inline int get_dis(int u, int v) {
int lca = get_lca(u, v);
return dep[u] + dep[v] - dep[lca] * 2;
}
int siz[N], maxs[N], all;
int dis[N];
void get_root(int u, int fa) {
siz[u] = 1;
maxs[u] = 0;
for (int v : g[u]) {
//if (u == 4 && dbg) printf("%d -> %d\n", 4, v);
if (v == fa || vis[v]) continue;
//if (u == 4 && dbg) printf("%d -> %d\n", 4, v);
get_root(v, u);
siz[u] += siz[v];
maxs[u] = std::max(maxs[u], siz[v]);
}
maxs[u] = std::max(maxs[u], all - siz[u]);
if (maxs[u] < maxs[cen]) cen = u;
}
void dfs2(int cen, int whi, int u, int fa) {
ST[whi].modify(ST[whi].rt[cen], 0, n, dis[u], value[u]);
for (int v : g[u]) {
if (v == fa || vis[v]) continue;
dis[v] = dis[u] + 1;
dfs2(cen, whi, v, u);
}
}
void solve(int u) {
vis[u] = 1;
dis[u] = 0;
dfs2(u, 0, u, 0);
dbg = u == 9;
for (int v : g[u]) {
if (vis[v]) continue;
all = siz[v];
cen = 0;
dis[v] = 1;
get_root(v, 0);
dfs2(cen, 1, v, u);
par[cen] = u;
solve(cen);
}
}
inline int query(int u, int d) {
int res = ST[0].query(ST[0].rt[u], 0, n, 0, d);
for (int i = u; par[i]; i = par[i]) {
int dis = get_dis(u, par[i]);
//if (d - dis < 0) break;
res += ST[0].query(ST[0].rt[par[i]], 0, n, 0, d - dis);
res -= ST[1].query(ST[1].rt[i], 0, n, 0, d - dis);
}
return res;
}
inline void update(int u, int d) {
int delta = d - ST[0].query(ST[0].rt[u], 0, n, 0, 0);
ST[0].modify(ST[0].rt[u], 0, n, 0, delta);
for (int i = u; par[i]; i = par[i]) {
int dis = get_dis(u, par[i]);
ST[0].modify(ST[0].rt[par[i]], 0, n, dis, delta);
ST[1].modify(ST[1].rt[i], 0, n, dis, delta);
}
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", value + i);
for (int i = 1, u, v; i < n; i++) {
scanf("%d %d", &u, &v);
g[u].emplace_back(v);
g[v].emplace_back(u);
}
dfs1(1, 0);
maxs[cen = 0] = all = n;
get_root(1, 0);
solve(cen);
//for (int i = 1; i <= n; i++) printf("%d ", par[i]); puts("");
int lans = 0;
for (int i = 1, op, u, v; i <= m; i++) {
scanf("%d %d %d", &op, &u, &v);
u ^= lans, v ^= lans;
if (op == 1) {
update(u, v);
} else {
printf("%d\n", lans = query(u, v));
}
}
return 0;
}