#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
inline int Read(){
int aa=0,w=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') w=-w; c=getchar();}
while(c>='0'&&c<='9'){aa=(aa<<3)+(aa<<1)+(c^48);c=getchar();}return aa*w;
}const int maxn=200010;
int v[maxn],siz[maxn],dfn[maxn],dep[maxn],rnk[maxn],fa[maxn],head[maxn],top[maxn],son[maxn],S[maxn*5],fl[maxn*5];
struct node{
int to,nxt;
}a[maxn<<2];int tot,cnt,n,M,R,P;
void DFS1(int now){
siz[now]=1; for(int i=head[now];i;i=a[i].nxt){
int to=a[i].to; if(to==fa[now]) continue;fa[to]=now;dep[to]=dep[now]+1;DFS1(to); siz[now]+=siz[to];
if(siz[to]>siz[son[now]]) son[now]=to;
}return;
}
void DFS2(int now){
dfn[now]=++cnt; rnk[cnt]=now;
if(!son[now]) return ;
top[son[now]]=top[now]; DFS2(son[now]);
for(int i=head[now];i;i=a[i].nxt){
int to=a[i].to; if(to==son[now]||to==fa[now]) continue;
top[to]=to; DFS2(to);
}return;
}
void U(int now){
S[now]=(S[now<<1]+S[now<<1|1])%P;return ;
}
void B(int now,int l,int r){
if(l==r){S[now]=v[rnk[l]];return ;}
int mid=(l+r)>>1; B(now<<1,l,mid); B(now<<1|1,mid+1,r);U(now); return ;
}
void PP(int now,int l,int r){
if(fl[now]==0) return ;
int mid=(l+r)>>1;
(fl[now<<1]+=fl[now])%P; (fl[now<<1|1]+=fl[now])%P;
S[now<<1]+=fl[now]*(mid-l+1); S[now<<1]=(S[now<<1])%P;
S[now<<1|1]+=fl[now]*(r-mid); S[now<<1|1]=(S[now<<1|1])%P;
fl[now]=0;
return ;
}
void TA(int now,int l,int r,int L,int R,int z){
if(L<=l&&r<=R){(S[now]+=z*(r-l+1))%=P;(fl[now]+=z)%=P;return ;}
int mid=(l+r)>>1; PP(now,l,r);if(L<=mid) TA(now<<1,l,mid,L,R,z);if(R>mid) TA(now<<1|1,mid+1,r,L,R,z);U(now);return ;
}
int TQ(int now,int l,int r,int L,int R){
if(L<=l&&r<=R){return S[now]%P;} int ans=0;
int mid=(l+r)>>1; PP(now,l,r);if(L<=mid) (ans+=TQ(now<<1,l,mid,L,R))%=P;if(R>mid) (ans+=TQ(now<<1|1,mid+1,r,L,R))%=P;return ans;
}
void Add(int x,int y){a[++tot].to=y;a[tot].nxt=head[x];head[x]=tot;}
void A1(int x,int y,int z){
z%=P;
while(top[x]!=top[y]){
if(dep[x]<dep[y]) swap(x,y);
TA(1,1,n,dfn[top[x]],dfn[x],z); x=fa[top[x]];
}if(dep[x]>dep[y]) swap(x,y);
TA(1,1,n,dfn[x],dfn[y],z);
}
int Q1(int x,int y){
int ans=0; while(top[x]!=top[y]){
if(dep[x]<dep[y]) swap(x,y);
(ans+=TQ(1,1,n,dfn[top[x]],dfn[x]))%=P; x=fa[top[x]];
}if(dep[x]>dep[y]) swap(x,y);
(ans+=TQ(1,1,n,dfn[x],dfn[y]))%=P;
return ans;
}
void A2(int x,int z){
z%=P; TA(1,1,n,dfn[x],dfn[x]+siz[x]-1,z);
}
int Q2(int x){
int ans=0; (ans+=TQ(1,1,n,dfn[x],dfn[x]+siz[x]-1))%=P;return ans;
}
signed main(){
// freopen("in.in","r",stdin);
// freopen("T1.out","w",stdout);
n=Read(),M=Read(),R=Read(),P=Read();
for(int i=1;i<=n;i++) v[i]=Read();
for(int i=1;i<n;i++){int x=Read();int y=Read();Add(x,y);Add(y,x);}
dep[R]=1; fa[R]=R; DFS1(R); top[R]=R; DFS2(R); B(1,1,n);
for(int i=1;i<=M;i++){int ops=Read();
if(ops==1){int x=Read();int y=Read();int z=Read();A1(x,y,z);}
if(ops==2){int x=Read();int y=Read();printf("%lld\n",Q1(x,y));}
if(ops==3){int x=Read();int z=Read();A2(x,z);}
if(ops==4){int x=Read();printf("%lld\n",Q2(x));}
}return 0;
}