#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int N=1e6+10;
struct node{
signed to,nxt;
}edge[2*N];
signed head[N];
signed cnt;
inline void add(signed u,signed v){
edge[++cnt]={v,head[u]};
head[u]=cnt;
}
signed in[N],out[N],dep[N],inv[2*N];
int vv[N];
bool knd[2*N];
int st[N][30];
int t;
void dfs(int x,int last){
st[x][0]=last;
in[x]=++t;
dep[x]=dep[last]+1;
inv[t]=vv[x];
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last) dfs(edge[i].to,x);
}
out[x]=++t;
knd[t]=true;
inv[t]=-vv[x];
}
struct ccf{
signed l,r,pcnt,ncnt;
int sum,laz;
}tree[4*N];
void build(signed pos,signed lft,signed rgt){
tree[pos].l=lft;
tree[pos].r=rgt;
if(lft==rgt){
tree[pos].sum=inv[lft];
if(!knd[lft]){
tree[pos].pcnt=1;
}else{
tree[pos].ncnt=1;
}
return;
}
signed mid=(lft+rgt)/2;
build(pos*2,lft,mid);
build(pos*2+1,mid+1,rgt);
tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
tree[pos].pcnt=tree[pos*2].pcnt+tree[pos*2+1].pcnt;
tree[pos].ncnt=tree[pos*2].ncnt+tree[pos*2+1].ncnt;
}
void push_down(int pos){
tree[pos*2].sum+=tree[pos*2].pcnt*tree[pos].laz-tree[pos*2].ncnt*tree[pos].laz;
tree[pos*2+1].sum+=tree[pos*2+1].pcnt*tree[pos].laz-tree[pos*2+1].ncnt*tree[pos].laz;
tree[pos*2].laz+=tree[pos].laz;
tree[pos*2+1].laz+=tree[pos].laz;
tree[pos].laz=0;
}
void upd(signed pos,signed lft,signed rgt,signed x){
if(lft<=tree[pos].l&&tree[pos].r<=rgt){
tree[pos].sum+=tree[pos].pcnt*x-tree[pos].ncnt*x;
tree[pos].laz+=x;
return;
}
if(rgt<tree[pos].l||tree[pos].r<lft) return;
push_down(pos);
upd(pos*2,lft,rgt,x);
upd(pos*2+1,lft,rgt,x);
tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
}
int ask(signed pos,signed lft,signed rgt){
if(lft<=tree[pos].l&&tree[pos].r<=rgt) return tree[pos].sum;
if(rgt<tree[pos].l||tree[pos].r<lft) return 0;
push_down(pos);
return ask(pos*2,lft,rgt)+ask(pos*2+1,lft,rgt);
}
int lca(signed x,signed y){
if(dep[x]<dep[y]) swap(x,y);
for(signed i=25;i>=0;i--){
if((1<<i)<=dep[x]-dep[y]) x=st[x][i];
}
if(x==y) return x;
for(signed i=25;i>=0;i--){
if((1<<i)<=dep[x]&&st[x][i]!=st[y][i]){
x=st[x][i];
y=st[y][i];
}
}
return st[x][0];
}
int n,m,r;
signed main(){
ios::sync_with_stdio(false);
memset(head,-1,sizeof(head));
cin>>n>>m>>r;
for(signed i=1;i<=n;i++){
cin>>vv[i];
}
for(signed i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(r,0);
for(signed j=1;j<=26;j++){
for(signed i=1;i<=n;i++){
st[i][j]=st[st[i][j-1]][j-1];
}
}
build(1,1,2*n);
while(m--){
signed op,a,b;
cin>>op>>a>>b;
if(op==1){
upd(1,in[a],in[a],b);
upd(1,out[a],out[a],b);
}else if(op==2){
upd(1,in[a],out[a],b);
}else{
signed tmp=lca(a,b);
cout<<ask(1,in[tmp],in[a])+ask(1,in[tmp],in[b])-ask(1,in[tmp],in[tmp])<<'\n';
}
}
return 0;
}