#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, r, p;
const int N = 2e5 + 5;
int w[N];
vector<int> g[N];
int dep[N], fa[N], size[N], top[N], son[N], id[N], a[N];
int cnt;
struct Segment_Tree
{
struct node
{
int l, r, sum, lazy;
}tr[N << 2];
void push_up(int u)
{
tr[u].sum = tr[u << 1].sum ^ tr[u << 1 | 1].sum;
}
void build(int u, int l, int r)
{
tr[u].l = l, tr[u].r = r;
if(l == r){
tr[u].sum = a[l];
return ;
}
int mid = (l + r) / 2;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
push_up(u);
}
void update(int u, int l, int r, int x, int k)
{
if(l == x && r == x){
tr[u].sum = k;
return ;
}
int mid = (l + r) >> 1;
if(l <= mid) update(u << 1, l, mid, x, k);
else update(u << 1 | 1, mid + 1, r, x, k);
push_up(u);
}
int query(int u, int l, int r)
{
if(l <= tr[u].l && tr[u].r <= r) {
return tr[u].sum;
}
int res = 0;
int mid = (tr[u].l + tr[u].r) >> 1;
if(l <= mid) res ^= query(u << 1, l, r);
if(r > mid) res ^= query(u << 1 | 1, l, r);
return res;
}
}seg;
struct TreePou
{
int query(int x, int y)
{
int ans = 0;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ans ^= seg.query(1, id[top[x]], id[x]);
ans %= p;
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
ans ^= seg.query(1, id[x], id[y]);
return ans;
}
}tp;
void dfs1(int u, int f, int deep)
{
dep[u] = deep;
fa[u] = f;
size[u] = 1;
int maxn = -1;
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == f) continue;
dfs1(v, u, deep + 1);
size[u] += size[v];
if(size[v] > maxn){
maxn = size[v];
son[u] = v;
}
}
}
void dfs2(int u, int topfa)
{
id[u] = ++cnt;
a[cnt] = w[u];
top[u] = topfa;
if(!son[u]) return ;
dfs2(son[u], topfa);
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
signed main()
{
cin >> n >> m ;
r = 1, p = INT_MAX;
for(int i = 1;i <= n;i ++ ) cin >> w[i];
for(int i = 1;i < n;i ++ ){
int x, y; cin >> x >> y;
g[x].push_back(y), g[y].push_back(x);
}
dfs1(r, 0, 1);
dfs2(r, r);
seg.build(1, 1, n);
while(m -- )
{
int op, i, v;
cin >> op >> i >> v;
if(op == 1)
{
seg.update(1, 1, n, id[i], v);
}
else cout << tp.query(i, v) << endl;
}
return 0;
}