rt
#include<bits/stdc++.h>
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _antirep(i,a,b) for(int i=(a);i>=(b);i--)
#define lson u<<1
#define rson u<<1|1
using namespace std;
typedef long long LL;
const int N=1e5+5;
int n,m,r,Mod,cnt;
vector<int>e[N];
int w[N],fa[N],sze[N],dep[N],top[N],id[N],rk[N],son[N];
struct node
{
int l,r,sum,lazy;
}t[N<<2];
void pushup(int u)
{
t[u].sum=(t[lson].sum+t[rson].sum)%Mod;
}
void pushdown(int u)
{
t[lson].sum=(t[lson].sum+t[u].lazy*(t[lson].r-t[lson].l+1)%Mod)%Mod;
t[rson].sum=(t[rson].sum+t[u].lazy*(t[rson].r-t[rson].l+1)%Mod)%Mod;
t[lson].lazy=(t[lson].lazy+t[u].lazy)%Mod;
t[rson].lazy=(t[rson].lazy+t[u].lazy)%Mod;
t[u].lazy=0;
}
void build(int u,int l,int r)
{
t[u].l=l,t[u].r=r,t[u].lazy=0;
if(l==r)
{
t[u].sum=w[rk[l]];
return;
}
int mid=l+r>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(u);
}
void dfs1(int u,int f)
{
fa[u]=f,sze[u]=1,dep[u]=dep[f]+1;
for(int v:e[u])
{
if(v==f) continue;
dfs1(v,u);
sze[u]+=sze[v];
if(sze[v]>sze[son[u]]) son[u]=v;
}
}
void dfs2(int u,int f)
{
top[u]=f,id[u]=++cnt,rk[cnt]=u;
if(son[u]==0) return;
dfs2(son[u],f);
for(int v:e[u])
if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
}
void modify(int u,int p,int q,int k)
{
if(p<=t[u].l&&t[u].r<=q)
{
t[u].sum=(t[u].sum+k*(t[u].r-t[u].l+1)%Mod)%Mod;
t[u].lazy=(t[u].lazy+k)%Mod;
return;
}
if(t[u].lazy) pushdown(u);
int mid=t[u].l+t[u].r>>1;
if(p<=mid) modify(lson,p,q,k);
if(q>mid) modify(rson,p,q,k);
pushup(u);
}
int query(int u,int p,int q)
{
if(p<=t[u].l&&t[u].r<=q) return t[u].sum;
if(t[u].lazy) pushdown(u);
int mid=t[u].l+t[u].r>>1,res=0;
if(p<=mid) res=(res+query(lson,p,q))%Mod;
if(q>mid) res=(res+query(rson,p,q))%Mod;
return res%Mod;
}
int sum(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=(res+query(1,id[top[x]],id[x]))%Mod;
x=fa[top[x]];
}
if(id[x]<=id[y]) res=(res+query(1,id[x],id[y]))%Mod;
else res=(res+query(1,id[y],id[x]))%Mod;
return res%Mod;
}
void modifys(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
modify(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(id[x]<=id[y]) modify(1,id[x],id[y],k);
else modify(1,id[y],id[x],k);
}
signed main()
{
cin.tie(0),cout.tie(0)->sync_with_stdio(0);
cin>>n>>m>>r>>Mod;
_rep(i,1,n) cin>>w[i];
_rep(i,1,n-1)
{
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(r,0);
dfs2(r,r);
build(1,1,n);
while(m--)
{
int op,x,y,z;
cin>>op;
if(op==1)
{
cin>>x>>y>>z;
modifys(x,y,z);
}
if(op==2)
{
cin>>x>>y;
cout<<sum(x,y)<<endl;
}
if(op==3)
{
cin>>x>>z;
modify(1,id[x],id[x]+sze[x]-1,z);
}
if(op==4)
{
cin>>x;
cout<<query(1,id[x],id[x]+sze[x]-1)<<endl;
}
}
return 0;
}