#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define TSIZE(x) ((n>>(dep[x]-1))+5)
using namespace std;
typedef long long LL;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
return x*f;
}
const int N=1e5+5,INF=0x3f3f3f3f,D=log2(N);
struct Edge{
int to,nxt;
}e[N<<1];
int m,n,last_ans,value[N],head[N],cnt;
int rt,RT,mirt=INF,Size,size[N],father[N],dis[N][D],dep[N];
bool cut[N];
vector<int> sum[2][N];
inline int qrysum(int x,int y,int id)
{
int res=0;
if(y>TSIZE(x)) y=TSIZE(x)-3;
while(y>0)
{
res+=sum[id][x][lowbit(y)];
y-=lowbit(y);
}
return res+sum[id][x][0];
}
inline void changesum (int x,int y,int k,int id)
{
if(!y) {
sum[id][x][0]+=k;
return;
}
int lim=TSIZE(x)-3;
while(y<lim&&y>0) {
sum[id][x][y]+=k;
y+=lowbit(y);
}
}
inline void add_edge(int u,int v) {e[++cnt].nxt=head[u],e[cnt].to=v; head[u]=cnt;}
void getrt(int fa,int u,int id)
{
size[u]=1; dis[u][id]=dis[fa][id]+1;
int temp=0;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].to;
if(v==fa||cut[v]) continue;
getrt(u,v,id); size[u]+=size[v];
temp=max(temp,size[v]);
}
temp=max(temp,Size-size[u]);
if(temp<mirt) {
rt=u; mirt=temp;
}
}
void getsize(int fa,int u)
{
size[u]=1;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].to;
if(v==fa||cut[v]==1) continue;
getsize(u,v);
size[u]+=size[v];
}
}
void build(int fa,int u,int depth)
{
cut[u]=1; dep[u]=depth;
getsize(fa,u);
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].to;
if(cut[v]||v==fa) continue;
mirt=INF; Size=size[v]; getrt(u,v,depth);
father[rt]=u;
build(u,rt,depth+1);
}
}
inline int query(int x,int k)
{
int res=0;
for(int i=x;i;i=father[i]) {
if(k-dis[x][dep[i]]>=0) res+=qrysum(i,k-dis[x][dep[i]],0);
if(!father[i]) continue;
if(k-dis[x][dep[father[i]]]>=0) res-=qrysum(i,k-dis[x][dep[father[i]]],1);
}
return res;
}
inline void change(int x,int y)
{
int d=y-value[x]; value[x]=y;
for(int i=x;i;i=father[i])
{
changesum(i,dis[x][dep[i]],d,0);
if(father[i]) changesum(i,dis[x][dep[father[i]]],d,1);
}
}
inline void init()
{
for(int i=1;i<=n;i++) {
int j=0;
while(++j <=TSIZE(i)) {
sum[0][i].push_back(0);
sum[1][i].push_back(0);
}
}
for(int i=1;i<=n;i++) {
for(int j=i;j;j=father[j]) {
changesum(j,dis[i][dep[j]],value[i],0);
if(father[i]) changesum(j,dis[i][dep[father[j]]],value[i],1);
}
}
}
int main()
{
n=read(); m=read();
for(int i=1;i<=n;i++) value[i]=read();
for(int i=1;i<n;i++) {
int u=read(),v=read();
add_edge(u,v); add_edge(v,u);
}
Size=n; getrt(0,1,0); RT=rt; build(0,rt,1);
init();
while(m--) {
int opt=read(),x=read(),y=read();
x^=last_ans; y^=last_ans;
if(opt) {
change(x,y);
continue;
}
last_ans=query(x,y);
printf("%d\n",last_ans);
}
return 0;
}