#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define len (r-l+1)
#define il inline
#define ri register int
const int mx=200005;
int n,m,r,mod,hd[mx],nxt[mx],to[mx],w[mx],wt[mx],a[mx<<2],
laz[mx<<2],son[mx],id[mx],fa[mx],cnt,dep[mx],siz[mx],top[mx],res;
il void add(int x,int y){to[++cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt;}
il void pushdown(int rt,int ln){
laz[rt<<1]+=laz[rt];
laz[rt<<1|1]+=laz[rt];
(a[rt<<1]+=laz[rt]*(ln-(ln>>1)))%=mod;
(a[rt<<1|1]+=laz[rt]*(ln>>1))%=mod;
laz[rt]=0;
}
il void build(int rt,int l,int r){
if(l==r){a[rt]=wt[l]%mod;return;}
build(lson);build(rson);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
il void query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){(res+=a[rt])%=mod;return;}
if(laz[rt])pushdown(rt,len);
if(L<=mid)query(lson,L,R);
if(R>mid)query(rson,L,R);
}
il void update(int rt,int l,int r,int L,int R,int k){
if(L<=l&&r<=R){laz[rt]+=k;a[rt]+=k*len;return;}
if(laz[rt])pushdown(rt,len);
if(L<=mid)update(lson,L,R,k);
if(R>mid)update(rson,L,R,k);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
il void dfs1(int x,int f){
dep[x]=dep[f]+1;fa[x]=f;siz[x]=1;
for(ri mxs=-1,i=hd[x],y;i;i=nxt[i])
if((y=to[i])!=f){
dfs1(y,x);siz[x]+=siz[y];
if(siz[y]>mxs)son[x]=y,mxs=siz[y];
}
}
il void dfs2(int x,int f){
id[x]=++cnt;wt[cnt]=w[x];top[x]=f;
if(!son[x])return;
dfs2(son[x],f);
for(ri i=hd[x],y;i;i=nxt[i])
if(((y=to[i])!=fa[x])&&(to[i]!=son[x]))dfs2(y,y);
}
int main(){
scanf("%d%d%d%d",&n,&m,&r,&mod);
for(ri i=1;i<=n;++i)scanf("%d",&w[i]);
for(ri i=1,x,y;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs1(r,0);cnt=0;dfs2(r,r);build(1,1,n);
for(ri k,x,y,z;m--;){
scanf("%d%d",&k,&x);
if(k==1){
scanf("%d%d",&y,&z);z%=mod;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,n,id[top[x]],id[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
update(1,1,n,id[x],id[y],k);
}else if(k==2){
scanf("%d",&y);int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res=0;
query(1,1,n,id[top[x]],id[x]);
(ans+=res)%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res=0;
query(1,1,n,id[x],id[y]);
printf("%d\n",(ans+res)%mod);
}else if(k==3){
scanf("%d",&y);
update(1,1,n,id[x],id[x]+siz[x]-1,y%mod);
}else{
res=0;
query(1,1,n,id[x],id[x]+siz[x]-1);
printf("%d\n",res);
}
}
return 0;
}
输出2 19