#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define inf 0x7fffffff
#define N 100010
#define ll long long
#define lson (p<<1)
#define rson (p<<1|1)
#define mid (l+r>>1)
int n,q,a[N],v[N],ord[N],tree[N<<2],laz[N],son[N],top[N],siz[N],fa[N],cnt,dep[N];
vector<int> e[N];
void build(int p,int l,int r){
if(l==r){
tree[p]=v[l];
return;
}
build(lson,l,mid);
build(rson,mid+1,r);
tree[p]=tree[lson]^tree[rson];
}
void update(int p,int l,int r,int pos,int val){
if(l==r){
tree[p]=val;
return;
}
if(pos<=mid) update(lson,l,mid,pos,val);
if(pos>mid) update(rson,mid+1,r,pos,val);
tree[p]=tree[lson]^tree[rson];
}
int query(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
return tree[p];
}
int ans=0;
if(ql<=mid) ans^=query(lson,l,mid,ql,qr);
if(qr>mid) ans^=query(rson,mid+1,r,ql,qr);
return ans;
}
int queryAns(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans^=query(1,1,n,ord[top[x]],ord[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans^=query(1,1,n,ord[x],ord[y]);
return ans;
}
void dfs1(int x,int fx){
fa[x]=fx,siz[x]=1;
dep[x]=dep[fx]+1;
for(auto to:e[x]){
if(to==fx) continue;
dfs1(to,x);
siz[to]+=siz[x];
if(siz[to]>siz[son[x]]){
son[x]=to;
}
}
}
void dfs2(int x,int topf){
top[x]=topf;
ord[x]=++cnt;
v[cnt]=a[x];
if(!son[x]) return;
dfs2(son[x],topf);
for(auto to:e[x]){
if(to==fa[x]||to==son[x]) continue;
dfs2(to,to);
}
}
void solve(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n-1;i++){
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(q--){
int op;cin>>op;
if(op==1){
int u,k;cin>>u>>k;
update(1,1,n,ord[u],k);
}else if(op==2){
int u,v;cin>>u>>v;
cout<<queryAns(u,v)<<'\n';
}
}
}
int main(){
IOS;
double start = clock();
freopen("D:\\Code\\in.txt","r",stdin);
freopen("D:\\Code\\out.txt","w",stdout);
int t=1;
while(t--){
solve();
}
double end = clock();
double tim = (end - start);
cout<<"time: "<<tim<<" ms"<<'\n';
return 0;
}