#include<bits/stdc++.h>
#define int long long
#define MAX 100005
#define inf 0x7f7f7f7f
using namespace std;
int N,M,a[MAX],cnt,head[MAX],fa[MAX],siz[MAX];
int dep[MAX],son[MAX],top[MAX],tot;
int dfn[MAX],rnk[MAX],tree[MAX*4],lazy[MAX];
struct MRS{
int to,next;
}edge[MAX*2];
void add(int u,int v){
cnt++;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
}
void dfs1(int u,int f){
fa[u]=f;
siz[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==f)continue;
dep[v]=dep[u]+1;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[u]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t;
dfn[u]=++tot;
rnk[tot]=u;
if(son[u])dfs2(son[u],t);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void ADD(int k,int l,int r,int v){
tree[k]+=(r-l+1)*v;
lazy[k]+=v;
}
void pushdown(int k,int l,int r){
if(!lazy[k])return;
int mid=(l+r)>>1;
ADD(k*2,l,mid,lazy[k]);
ADD(k*2+1,mid+1,r,lazy[k]);
lazy[k]=0;
}
void build(int k,int l,int r){
if(l==r){
tree[k]=a[rnk[l]];
return;
}
int mid=(l+r)>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
tree[k]=tree[k*2]+tree[k*2+1];
}
void change(int k,int l,int r,int x,int y,int v){
if(l>=x&&r<=y){
tree[k]+=(r-l+1)*v;
lazy[k]+=v;
return;
}
pushdown(k,l,r);
int mid=(l+r)>>1;
if(x<=mid)change(k*2,l,mid,x,y,v);
if(y>mid)change(k*2+1,mid+1,r,x,y,v);
tree[k]=tree[k*2]+tree[k*2+1];
}
int query(int k,int l,int r,int x,int y){
if(l>=x&&r<=y)return tree[k];
pushdown(k,l,r);
int mid=(l+r)>>1,res=0;
if(x<=mid)res+=query(k*2,l,mid,x,y);
if(y>mid)res+=query(k*2+1,mid+1,r,x,y);
return res;
}
int ask(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,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=query(1,1,N,dfn[x],dfn[y]);
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>N>>M;
for(int i=1;i<=N;i++)cin>>a[i];
for(int i=1,x,y;i<=N-1;i++){
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,N);
for(int i=1,op,x,y;i<=M;i++){
cin>>op;
if(op==1)cin>>x>>y,change(1,1,N,dfn[x],dfn[x],y);
else if(op==2)cin>>x>>y,change(1,1,N,dfn[x],dfn[x]+siz[x]-1,y);
else cin>>x,cout<<ask(1,x)<<'\n';
}
return 0;
}