#include<bits/stdc++.h>
using namespace std;
int n,m;
int val[100001];
vector<int> E[100001];
void add(int u,int v){
E[u].push_back(v);
}
int tot;
int dep[100001],siz[100001],f[100001],wson[100001],top[100001],num[100001],r[100001];
void dfs1(int u,int dad){
dep[u]=dep[dad]+1,siz[u]=1,f[u]=dad;
for(int v:E[u]){
if(v==dad)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[wson[u]])wson[u]=v;
}
return ;
}
void dfs2(int u,int to){
top[u]=to,num[u]=++tot,r[tot]=u;
if(wson[u])dfs2(wson[u],to);
for(int v:E[u]){
if(v==f[u]||v==wson[u])continue;
dfs2(v,v);
}
}
int sum[400001],lazy[400001];
void pushup(int u){
sum[u]=sum[u*2]+sum[u*2+1];
}
void pushdown(int u,int l,int r){
if(!lazy[u])return ;
int mid=(l+r)>>1;
lazy[u*2]+=lazy[u];
sum[u*2]+=lazy[u]*(mid-l+1);
lazy[u*2+1]+=lazy[u];
sum[u*2+1]+=lazy[u]*(r-mid);
lazy[u]=0;
return;
}
void build(int u,int l,int r){
if(l==r){
sum[u]=val[l];
return;
}
int mid=(l+r)>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
pushup(u);
}
void change(int u,int l,int r,int x,int y,int v){
if(x<=l&&r<=y){
sum[u]+=(r-l+1)*v;
lazy[u]+=v;
return ;
}
pushdown(u,l,r);
int mid=(l+r)>>1;
if(x<=mid)change(u*2,l,mid,x,y,v);
if(y>mid) change(u*2+1,mid+1,r,x,y,v);
pushup(u);
}
int query(int u,int l,int r,int x,int y){
if(x<=l&&r<=y){
return sum[u];
}
pushdown(u,l,r);
int mid=(l+r)>>1,ans=0;
if(x<=mid)ans+=query(u*2,l,mid,x,y);
if(y>mid)ans+=query(u*2+1,mid+1,r,x,y);
return ans;
}
void change1(int u,int v){
change(1,1,n,num[u],num[u],v);
return ;
}
void change2(int u,int v){
change(1,1,n,num[u],num[u]+siz[u]-1,v);
return ;
}
int query1(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans+=query(1,1,n,num[top[u]],num[v]);
u=f[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans+=query(1,1,n,num[u],num[v]);
return ans;
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&val[i]);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(m--){
int opt;
scanf("%d",&opt);
if(opt==1){
int u,v;
scanf("%d%d",&u,&v);
change1(u,v);
}
if(opt==2){
int u,v;
scanf("%d%d",&u,&v);
change2(u,v);
}
if(opt==3){
int u;
scanf("%d",&u);
printf("%d\n",query1(1,u));
}
}
return 0;
}
先不要管没开long long