#include<bits/stdc++.h>
using namespace std;
int Size[100011],dep[100010],fa[100011],son[100011],tid[100011],top[100011],footmark[400011],n,m,r,p;
int cin1,cin2,cin3,cin4,t=0,st[400001],lazy[400001],num[100001];
vector<int>T[100001];
void pushdown(int rt,int l,int r)
{
if(lazy[rt]&&l!=r)
{
int mid=l+r>>1;
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
st[rt<<1]=(st[rt<<1]+(mid-l+1)*lazy[rt])%p;
st[rt<<1|1]=(st[rt<<1|1]+(r-mid)*lazy[rt])%p;
lazy[rt]=0;
}
}
void dfs(int x,int pre)
{
dep[x]=dep[pre]+1;Size[x]=1,fa[x]=pre;
// cout<<x<<"-"<<pre<<endl;
// cout<<"dep: "<<dep[x]<<"-"<<dep[pre]<<endl;
for(int i=0;i<T[x].size();i++)
if(T[x][i]!=pre)
{
int v=T[x][i];
if(v!=pre)dfs(v,x);
Size[x]+=Size[v];
// cout<<"Size["<<x<<"]="<<Size[x]<<" "<<"Size["<<v<<"]="<<Size[v]<<endl;
if(Size[son[x]]<Size[v])son[x]=v;
}
}
void dfs2(int u,int pre,int tp)
{
tid[u]=++t;
footmark[t]=u;
top[u]=tp;
if(son[u])dfs2(son[u],u,tp);
for(int i=0;i<T[u].size();i++)
{
int v=T[u][i];
if(v!=son[u]&&v!=pre)dfs2(v,u,v);
}
}
int creat(int rt,int l,int r)
{
int mid=(l+r)/2;
if(l==r)return st[rt]=num[footmark[l]];
st[rt]=(creat(rt*2,l,mid)+creat(rt*2+1,mid+1,r))%p;
return st[rt];
}
void add(int rt,int l,int r,int s,int e,int x)
{
// if(rt==2&&x==2)
//cout<<rt<<"-"<<l<<" "<<r<<" "<<s<<" "<<e<<" "<<x<<endl;
if(s<=l&&r<=e) {
lazy[rt]+=x;
st[rt]=(st[rt]+(r-l+1)*x)%p; //******
return;
}
pushdown(rt,l,r);
int mid=(l+r)/2;
if(s<=mid)add(rt*2,l,mid,s,e,x);
if(e>mid)add(rt*2+1,mid+1,r,s,e,x);
// cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
st[rt]=(st[rt<<1]+st[rt<<1|1])%p;
}
int query(int rt,int l,int r,int s,int e)
{
if(s<=l&&r<=e)return st[rt];
pushdown(rt,l,r);
int ans=0,mid=(l+r)/2;
if(s<=mid)ans=(query(rt<<1,l,mid,s,e))%p;
if(e>mid)ans=(ans+query(rt*2+1,mid+1,r,s,e))%p;
return ans%p;
}
int query2(int u,int v)
{
int l,r,ans=0;
while(1)
{
if(top[u]==top[v])
{
l=min(tid[u],tid[v]);
r=max(tid[v],tid[u]);
int tmp=query(1,1,n,l,r)%p;
return ans=(ans+tmp)%p;
}
else
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
l=tid[top[u]];
r=tid[u];
int tmp=query(1,1,n,l,r);
ans=(ans+tmp)%p;
u=fa[top[u]];
}
}
}
void add2(int u,int v,int x)
{
int l,r;
while(1)
{
if(top[u]==top[v])
{
l=min(tid[u],tid[v]);
r=max(tid[v],tid[u]);
add(1,1,n,l,r,x);
return;
}
else
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
l=tid[top[u]];
r=tid[u];
add(1,l,n,1,r,x);
u=fa[top[u]];
}
}
}
int main(){
cin>>n>>m>>r>>p;
for(int i=1;i<=n;i++)
{
cin>>num[i];
// son[i]=i;
}
for(int i=1;i<n;i++)
{
cin>>cin1>>cin2;
T[cin1].push_back(cin2);
T[cin2].push_back(cin1);
}
dfs(r,r);
dfs2(r,r,r);
creat(1,1,n);
// for(int i=1;i<=n;i++)cout<<"dep["<<i<<"]="<<dep[i]<<endl;
// for(int i=1;i<=n;i++)cout<<"Size["<<i<<"]="<<Size[i]<<endl;
// for(int i=1;i<=n;i++)cout<<"son["<<i<<"]="<<son[i]<<endl;
// cout<<t<<endl;
// for(int i=1;i<=n;i++)cout<<"footmark["<<i<<"]="<<footmark[i]<<endl;
// for(int i=1;i<=n;i++)cout<<"top["<<i<<"]="<<top[i]<<endl;
// for(int i=1;i<=n;i++)cout<<fa[i]<<"--"<<endl;
for(int i=1;i<=m;i++)
{
cin>>cin1;
if(cin1==1)
{
cin>>cin2>>cin3>>cin4;
add2(cin2,cin3,cin4); //无循环
}
else if(cin1==2)
{
cin>>cin2>>cin3;
cout<<query2(cin2,cin3)%p<<endl;//死循环
// cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
}
else if(cin1==3)
{
cin>>cin2>>cin3;
add(1,1,n,tid[cin2],tid[cin2]+Size[cin2]-1,cin3);//第二个死循环
//
}
else
{
cin>>cin2;
cout<<query(1,1,n,tid[cin2],tid[cin2]+Size[cin2]-1)%p<<endl;//
}
}
return 0;
}