#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=200006;
struct bian{
int bef,to;
}edge[maxn+1];
long long p;
int w[maxn+1],wn[maxn+1],size[maxn+1];
int n,num,m,r,tp[maxn+1],idnum,head[maxn+1],deep[maxn+1],zson[maxn+1],father[maxn+1],id[maxn+1];
void dfs1(int x,int fa,int d){
deep[x]=d;
size[x]=1;
int zon=-1;
father[x]=fa;
for(int i=head[x];i!=0;i=edge[i].bef){
int qwq=edge[i].to;
if(qwq==fa)continue;
dfs1(qwq,x,d+1);
size[x]+=size[qwq];
if(size[qwq]>zon){
zson[x]=qwq;
zon=size[qwq];
}
}
}
void dfs2(int x,int topp){
id[x]=++idnum;
tp[x]=topp;
wn[idnum]=w[x];
if(zson[x]){
dfs2(zson[x],topp);
for(int i=head[x];i!=0;i=edge[i].bef){
int u=edge[i].to;
if(!id[u])
dfs2(u,u);
}
}
}
void addedge(int u,int v){
edge[++num].to=v;
edge[num].bef=head[u];
head[u]=num;
}
struct tre{
int l,r,w,siz,tag;
}shu[2*maxn+1];
void build(int k,int l,int r){
shu[k].l=l;
shu[k].r=r;
shu[k].siz=r-l+1;
if(l==r){
shu[k].w=wn[l];
return;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
shu[k].w=(shu[k*2].w+shu[k*2+1].w+p)%p;
}
void push(int k){
if(!shu[k].tag)return;
shu[k*2].w=(shu[k*2].w+shu[k*2].siz*shu[k].tag)%p;
shu[k*2+1].w=(shu[k*2+1].w+shu[k*2+1].siz*shu[k].tag)%p;
shu[k*2].tag=(shu[k*2].tag+shu[k].tag)%p;
shu[k*2+1].tag=(shu[k*2+1].tag+shu[k].tag)%p;
shu[k].tag=0;
}
void jia(int k,int l,int r,int v){
if(l<=shu[k].l&&r>=shu[k].r){
shu[k].w+=shu[k].siz*v;
shu[k].tag+=v;
return;
}
push(k);
int mid=(shu[k].l+shu[k].r)/2;
if(l<=mid)jia(k*2,l,r,v);
if(r>mid)jia(k*2+1,l,r,v);
shu[k].w=(shu[k*2].w+shu[k*2+1].w+p)%p;
}
int sum(int k,int l,int r){
int ans=0;
if(shu[k].l>=l&&shu[k].r<=r){
return shu[k].w;
}
push(k);
int mid=(shu[k].l+shu[k].r)/2;
if(l<=mid)ans=(ans+sum(k*2,l,r))%p;
if(r>mid)ans=(ans+sum(k*2+1,l,r))%p;
return ans;
}
int tsum(int a,int b){
int ans=0;
while(tp[a]!=tp[b]){
if(deep[a]<deep[b])swap(a,b);
ans=(ans+sum(1,id[tp[a]],id[a]))%p;
a=father[tp[a]];
}
if(deep[a]>deep[b])swap(a,b);
ans=(ans+sum(1,id[a],id[b]))%p;
return ans;
}
void tjia(int a,int b,int v){
while(tp[a]!=tp[b]){
if(deep[tp[a]]<deep[tp[b]])swap(a,b);
jia(1,id[tp[a]],id[a],v);
a=father[tp[a]];
}
if(deep[a]>deep[b])swap(b,a);
jia(1,id[a],id[b],v);
}
#undef int
int main(){
#define int long long
#ifndef ONLINE_JUDGE
freopen("P3384_2.in","r",stdin);
#endif
scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
for(int i=1;i<n;i++){
int x,y;
scanf("%lld%lld",&x,&y);
addedge(x,y);
addedge(y,x);
}
dfs1(r,0,1);
dfs2(r,r);
build(1,1,n);
for(int i=1;i<=m;i++){
int op;
scanf("%lld",&op);
int a,b,c;
switch(op){
case 1:
scanf("%lld%lld%lld",&a,&b,&c);
c%=p;
tjia(a,b,c);
break;
case 2:
scanf("%lld%lld",&a,&b);
printf("%lld\n",tsum(a,b));
break;
case 3:
scanf("%lld%lld",&a,&b);
jia(1,id[a],id[a]+size[a]-1,b%p);
break;
case 4:
scanf("%lld",&a);
printf("%lld\n",sum(1,id[a],id[a]+size[a]-1));
break;
}
}
return 0;
}