#include<bits/stdc++.h>
#define int long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
int n,m,rt,p,r,e,s,a[100005],dep[100005],fa[100005],id[100005],wei[100005];
int sum[400005],tag[400005],x,y,cnt,wson[100005],siz[100005],top[100005],op;
vector<int> t[100005];bool vis[100005];
void dfs1(int now,int f,int dept){
vis[now]=1;dep[now]=dept;fa[now]=f;siz[now]=1;
int big=-1;
for(int i=0;i<t[now].size();i++){
if(vis[t[now][i]]) continue;
dfs1(t[now][i],now,dept+1);
if(siz[t[now][i]]>big){
big=siz[t[now][i]];
wson[now]=t[now][i];
}
siz[now]=(siz[now]+siz[t[now][i]])%p;
}return;
}
void dfs2(int now,int rt){
vis[now]=1;
id[now]=++cnt;
wei[cnt]=a[now];
top[now]=rt;
if(wson[now]!=0){
dfs2(wson[now],rt);
}else return;
for(int i=0;i<t[now].size();i++){
if(vis[t[now][i]]) continue;
dfs2(t[now][i],t[now][i]);
}return;
}
void update(int rt){
sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
return;
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=wei[l];
sum[rt]%=p;
return;
}
int mid=(l+r)>>1;
build(lson);build(rson);
update(rt);
return;
}
void color(int l,int r,int rt,int k){
sum[rt]=(sum[rt]+(r-l+1)*k)%p;
tag[rt]=(tag[rt]+k)%p;return;
return;
}
void ph_tg(int l,int r,int rt){
if(tag[rt]!=0){
int mid=(l+r)>>1;
color(lson,tag[rt]);
color(rson,tag[rt]);
tag[rt]=0;
}return;
}
void modify(int l,int r,int rt,int k){
if(x<=l&&r<=y){
color(l,r,rt,k);
return;
}
ph_tg(l,r,rt);
int mid=(l+r)>>1;
if(x<=mid) modify(lson,k);
if(y>mid) modify(rson,k);
update(rt);
return;
}
int query(int l,int r,int rt){
if(x<=l&&r<=y){
return sum[rt]%p;
}
ph_tg(l,r,rt);
int mid=(l+r)>>1,ans=0;
if(x<=mid) ans+=query(lson),ans%=p;
if(y>mid) ans+=query(rson),ans%=p;
return ans;
}
int query_path(int xx,int yy){
int res=0;
while(top[xx]!=top[yy]){
if(dep[top[xx]]<dep[top[yy]]) swap(xx,yy);
x=id[top[xx]];y=id[xx];
res+=query(1,n,1);res%=p;
xx=fa[top[xx]];
//cout<<xx<<' '<<yy<<endl;
}
if(dep[xx]>dep[yy]) swap(xx,yy);
x=id[xx];y=id[yy];
res+=query(1,n,1);
return res%p;
}
int query_son(int xx){
x=id[xx];y=id[xx]+siz[xx]-1;
return query(1,n,1)%p;
}
void modify_path(int xx,int yy,int k){
while(top[xx]!=top[yy]){
if(dep[top[xx]]<dep[top[yy]]) swap(xx,yy);
x=id[top[xx]];y=id[xx];
modify(1,n,1,k);
xx=fa[top[xx]];
}
if(dep[xx]>dep[yy]) swap(xx,yy);
x=id[xx];y=id[yy];
modify(1,n,1,k);
return;
}
void modify_son(int xx,int k){
x=id[xx];y=id[xx]+siz[xx]-1;
modify(1,n,1,k);
return;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m>>rt>>p;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
t[v].push_back(u);
t[u].push_back(v);
}
dfs1(rt,0,1);memset(vis,0,sizeof(vis));
dfs2(rt,rt);
build(1,n,1);
while(m--){
cin>>op>>r;
if(op==1){
cin>>e>>s;s%=p;
modify_path(r,e,s);
}else if(op==2){
cin>>e;
cout<<query_path(r,e)<<endl;
}else if(op==3){
cin>>s;s%=p;
modify_son(r,s);
}else{
cout<<query_son(r)<<endl;
}
}
return 0;
}