#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
int const MXN=100005;
int n,m,R,MOD,cnt,a[MXN],hd[MXN],fa[MXN],dep[MXN],siz[MXN],b[MXN],son[MXN],id[MXN],T[MXN],tp[MXN];
int x,y;
struct Edge{
int to,nxt;
}edge[MXN<<1];
void add(int u,int v)
{
cnt++;
edge[cnt].to=v;
edge[cnt].nxt=hd[u];
hd[u]=cnt;
}
//求深度,父节点 ,重儿子,size[]
void dfs1(int u,int d,int f)
{
dep[u]=d;
siz[u]=1;
int mx=0;
for(int i=hd[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v!=f)
{
fa[v]=u;
dfs1(v,d+1,u);
if(siz[v]>mx)
{
mx=siz[v];
son[u]=v;
}
siz[u]+=siz[v];
}
}
}
int tot=0;
//将树映射到线性的线段树上 ,并求出top[]
void dfs2(int u,int top)
{
id[u]=++tot;//原树上的点在线段树上的排名
a[tot]=b[u];//线段树上 的权值
T[tot]=u;//线段树的点在原树上的编号
tp[u]=top;//
if(son[u]!=0)
dfs2(son[u],top);
for(int i=hd[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v!=fa[u] && v!=son[u])
{
// id[v]=++tot;//少这句话
// a[tot]=b[v];
// T[tot]=v;
// tp[v]=v;//轻儿子的top就是自己
dfs2(v,v);
}
}
}
struct Tree{
int l,r,sum,ad;
}tre[MXN<<2];
void pushup(int rt)
{
tre[rt].sum=(tre[rt<<1].sum+tre[rt<<1|1].sum+MOD)%MOD;
}
void build(int rt,int L,int R)
{
tre[rt].l=L;
tre[rt].r=R;
if(L==R)
{
tre[rt].sum=a[L];
return ;
}
int mid=(L+R)>>1;
build(rt<<1,L,mid);
build(rt<<1|1,mid+1,R);
pushup(rt);
}
void pushdown(int rt)
{
if(tre[rt].ad)
{
tre[rt<<1].ad+=tre[rt].ad;
tre[rt<<1|1].ad+=tre[rt].ad;
tre[rt<<1].sum+=tre[rt].ad*(tre[rt<<1].r-tre[rt<<1].l+1);
tre[rt<<1|1].sum+=tre[rt].ad*(tre[rt<<1|1].r-tre[rt<<1|1].l+1);
tre[rt].ad=0;
}
}
void update(int rt,int L,int R,int v)
{
if(L<=tre[rt].l && R>=tre[rt].r)//少一个等于号
{
tre[rt].ad+=v;
tre[rt].sum +=v*(tre[rt].r-tre[rt].l+1);
return;
}
pushdown(rt);
int mid=(tre[rt].l+tre[rt].r)>>1;
if(L<=mid)
update(rt<<1,L,R,v);
if(R>mid)
update(rt<<1|1,L,R,v);
pushup(rt);
}
int query(int rt,int L,int R)
{
if(L<=tre[rt].l && R>=tre[rt].r)
return tre[rt].sum;
pushdown(rt);少写
int mid=(tre[rt].l+tre[rt].r)>>1;
int tmp=0;
if(L<=mid)
tmp=(tmp+query(rt<<1,L,R))%MOD;
if(R>mid)
tmp=(tmp+query(rt<<1|1,L,R))%MOD;
return tmp;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&R,&MOD);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs1(R,1,-1);
// for(int i=1;i<=n;i++)
// cout<dep[r]) swap(l,r);
update(1,id[l],id[r],v);
// cout<dep[r])swap(l,r);
tmp=(tmp+query(1,id[l],id[r]))%MOD;
printf("%d\n",tmp);
}
else if(q==3)
{
scanf("%d%d",&rt,&v);
update(1,id[rt],id[rt]+siz[rt]-1,v);
// cout<