rt , AC #3,#11
#include<bits/stdc++.h>
#define int long long
struct st{
int to,next;
}v[200003];
int a[100002],real[500002],lzy[500005],head[100002],tr[100003],id[100003],fa[100002],son[100002],deep[100002],sze[100003],tp[100003],n,m,rt,mod,len,tot,x,y,z,opt;
void add(int x,int y){
v[++len].to=y,v[len].next=head[x],head[x]=len;
}
void pushup(int x){
tr[x]=tr[x*2]+tr[x*2+1];
}
void pushdown(int x,int l,int r){
if(lzy[x])tr[x*2]+=lzy[x]*l,tr[x*2+1]+=lzy[x]*r,lzy[x*2]+=lzy[x],lzy[x*2+1]+=lzy[x],lzy[x]=0;
}
void build(int x,int l,int r){
if(l==r){
tr[x]=a[real[l]];
return;
}
int mid=l+r>>1;
build(x*2,l,mid),build(x*2+1,mid+1,r),pushup(x);
}
void update(int x,int l,int r,int L,int R,int val){
if(l>=L&&r<=R){
tr[x]+=val*(r-l+1),lzy[x]+=val;
return;
}
int mid=l+r>>1;
pushdown(x,mid-l+1,r-mid);
if(mid>=L)update(x*2,l,mid,L,R,val);
if(mid<R)update(x*2+1,mid+1,r,L,R,val);
}
int query(int x,int l,int r,int L,int R){
// std::cout<<l<<' '<<r<<' '<<L<<' '<<R<<'\n';
if(l>=L&&r<=R)return tr[x]%mod;
// puts("222");
int ans=0,mid=l+r>>1;
pushdown(x,mid-l+1,r-mid);
// puts("333");
if(mid>=L)ans+=query(x*2,l,mid,L,R),ans%=mod;
if(mid+1<=R)ans+=query(x*2+1,mid+1,r,L,R),ans%=mod;
pushup(x);
return ans;
}
void dfs(int u,int fath){
fa[u]=fath,sze[u]=1;
for(int i=head[u],w;i;i=v[i].next){
w=v[i].to;
if(fath^w){
deep[w]=deep[u]+1,dfs(w,u);
if(sze[son[u]]<sze[w]||!son[u])son[u]=w;
sze[u]+=sze[w];
}
}
}
void DFS(int u,int val){
tp[u]=val,id[u]=++tot,real[tot]=u;
if(!son[u])return;
else DFS(son[u],val);
for(int i=head[u],w;i;i=v[i].next){
w=v[i].to;
if(fa[u]^w&&w^son[u])DFS(w,w);
}
}
void sol1(){
scanf("%lld%lld%lld",&x,&y,&z);
int A=tp[x],B=tp[y];
while(A^B){
if(deep[A]<deep[B])std::swap(A,B),std::swap(x,y);
update(1,1,n,id[A],id[x],z),x=fa[A],A=tp[x];
}
if(deep[x]>deep[y])std::swap(x,y);
update(1,1,n,id[x],id[y],z);
}
void sol2(){
scanf("%lld%lld",&x,&y);
int A=tp[x],B=tp[y],ans=0;
while(A^B){
if(deep[A]<deep[B])std::swap(A,B),std::swap(x,y);
ans+=query(1,1,n,id[A],id[x]),ans%=mod,x=fa[A],A=tp[x];
}
if(deep[x]>deep[y])std::swap(x,y);
ans+=query(1,1,n,id[x],id[y]),printf("%lld\n",ans%mod);
}
void sol3(){
scanf("%lld%lld",&x,&y),update(1,1,n,id[x],id[x]+sze[x]-1,y);
}
void sol4(){
scanf("%lld",&x);
// std::cout<<id[x]<<' '<<sze[x];
printf("%lld\n",query(1,1,n,id[x],id[x]+sze[x]-1)%mod);
}
signed main(){
scanf("%lld%lld%lld%lld",&n,&m,&rt,&mod),deep[rt]=1;
for(int i=1;i<=n;i++)scanf("%lld",a+i);
for(int i=1;i<n;i++)scanf("%lld%lld",&x,&y),add(x,y),add(y,x);
dfs(rt,0),DFS(rt,rt),build(1,1,n);
for(;m--;){
scanf("%lld",&opt);
if(opt==1)sol1();
else if(opt==2)sol2();
else if(opt==3)sol3();
else sol4();
}
return 0;
}