#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct sgt{
ll s[400010],t[400010],p;
void m(ll &x){
x=(x%p+p)%p;
}
void f(ll u,ll le,ll ri,ll v){
s[u]+=v*(ri-le+1);
t[u]+=v;
m(s[u]),m(t[u]);
}
void push_down(ll u,ll le,ll ri){
ll mid=(le+ri)/2;
f(2*u,le,mid,t[u]);
f(2*u+1,mid+1,ri,t[u]);
t[u]=0;
}
void push_up(ll u){
s[u]=s[2*u]+s[2*u+1];
m(s[u]);
}
void add(ll u,ll le,ll ri,ll x,ll y,ll v){
if(x<=le&&ri<=y){
f(u,le,ri,v);
return ;
}
push_down(u,le,ri);
ll mid=(le+ri)/2;
if(x<=mid) add(2*u,le,mid,x,y,v);
if(y>mid) add(2*u+1,mid+1,ri,x,y,v);
push_up(u);
}
ll que(ll u,ll le,ll ri,ll x,ll y){
push_down(u,le,ri);
if(x<=le&&ri<=y){
return s[u];
}
ll mid=(le+ri)/2;
ll res=0;
if(x<=mid) res+=que(2*u,le,mid,x,y);
if(y>mid) res+=que(2*u+1,mid+1,ri,x,y);
m(res);
return res;
}
}t;
ll n,m,r,p,op,a,b,c,s[100010];
ll d[100010],f[100010],id[100010],h[100010],top[100010],sz[100010],cnt;
vector<ll> e[100010];
void dfs1(ll u,ll fa){
sz[u]=1;
d[u]=d[fa]+1;
f[u]=fa;
id[u]=++cnt;
for(ll i=0;i<ll(e[u].size());i++){
ll v=e[u][i];
if(v==fa) continue;
dfs1(v,u);
sz[u]+=sz[v];
}
}
void dfs2(ll u,ll fi){
top[u]=fi;
ll hs=0;
for(ll i=0;i<ll(e[u].size());i++){
ll v=e[u][i];
if(v!=f[u]&&sz[hs]<sz[v]){
hs=v;
}
}
if(!hs) return ;
dfs2(hs,fi);
for(ll i=0;i<ll(e[u].size());i++){
ll v=e[u][i];
if(v!=f[u]&&v!=hs){
dfs2(v,v);
}
}
h[u]=hs;
}
void add_p(ll u,ll v,ll w){
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
t.add(1,1,n,id[top[u]],id[u],w);
u=f[top[u]];
}
if(d[u]>d[v]) swap(u,v);
t.add(1,1,n,id[u],id[v],w);
}
ll que_p(ll u,ll v){
ll res=0;
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
res+=t.que(1,1,n,id[top[u]],id[u]);
res%=p;
u=f[top[u]];
}
if(d[u]>d[v]) swap(u,v);
res+=t.que(1,1,n,id[u],id[v]);
return res;
}
void add_s(ll u,ll w){
t.add(1,1,n,id[u],id[u]+sz[u]-1,w);
}
ll que_s(ll u){
return t.que(1,1,n,id[u],id[u]+sz[u]-1);
}
int main(){
scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
t.p=p;
for(int i=1;i<=n;i++){
scanf("%lld",&s[i]);
}
for(int i=1;i<n;i++){
scanf("%lld%lld",&a,&b);
e[a].push_back(b);
e[b].push_back(a);
}
dfs1(r,0);
dfs2(r,r);
for(int i=1;i<=n;i++){
t.add(1,1,n,id[i],id[i],s[i]);
}
while(m--){
scanf("%lld%lld",&op,&a);
if(op==1){
scanf("%lld%lld",&b,&c);
add_p(a,b,c);
}
if(op==2){
scanf("%lld",&b);
printf("%lld\n",que_p(a,b)%p);
}
if(op==3){
scanf("%lld",&b);
add_s(a,b);
}
if(op==4){
printf("%lld\n",que_s(a)%p);
}
}
}