#include <bits/stdc++.h>
#define int long long
using namespace std;
int read()
{
int res = 0,f = 1;
char ch = getchar();
while (ch<'0'||ch>'9') f = (ch=='-'?-f:f),ch = getchar();
while (ch>='0'&&ch<='9') res = (res<<3)+(res<<1)+(ch^48),ch = getchar();
return res*f;
}
void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
}
void writech(int x,char ch){write(x),putchar(ch);}
const int N = 1e5+5;
int n,m,R,MOD;
int ww[N],w[N],id[N],cnt;
vector<int> a[N];
int deep[N],top[N],f[N],sz[N],son[N];
int sum[4*N],tag[4*N];
void dfs(int x,int p,int dep)
{
deep[x]=dep;
sz[x]=1;
f[x]=p;
for (int i = 0; i < a[x].size(); i++)
{
int y = a[x][i];
if (y==p) continue;
dfs(y,x,dep+1);
sz[x]+=sz[y];
if (sz[y]>sz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int p,int topf)
{
w[++cnt]=ww[x]%MOD;
id[x]=cnt;
top[x]=topf;
if (son[x]==0) return ;
dfs2(son[x],x,topf);
for (int i = 0; i < a[x].size(); i++)
{
int y = a[x][i];
if (y!=p&&y!=son[x]) dfs2(y,x,y);
}
}
void bt(int x,int l,int r)
{
if (l==r)
{
sum[x]=w[l];
return ;
}
int mid = (l+r)/2;
bt(2*x,l,mid);
bt(2*x+1,mid+1,r);
sum[x]=(sum[2*x]+sum[2*x+1])%MOD;
}
void pushdown(int x,int l,int r)
{
int mid = (l+r)/2;
tag[2*x]=(tag[2*x]+tag[x])%MOD;
sum[2*x]=(sum[2*x]+tag[x]*(mid-l+1)%MOD)%MOD;
tag[2*x+1]=(tag[2*x+1]+tag[x])%MOD;
sum[2*x+1]=(sum[2*x+1]+tag[x]*(r-mid)%MOD)%MOD;
tag[x]=0;
}
void mod(int x,int l,int r,int ql,int qr,int v)
{
if (ql<=l&&r<=qr)
{
tag[x]=(tag[x]+v)%MOD;
sum[x]=(sum[x]+v*(r-l+1)%MOD)%MOD;
return ;
}
int mid = (l+r)/2;
pushdown(x,l,r);
if (ql<=mid) mod(2*x,l,mid,ql,qr,v);
if (qr>mid) mod(2*x+1,mid+1,r,ql,qr,v);
sum[x]=(sum[2*x]+sum[2*x+1])%MOD;
}
int query(int x,int l,int r,int ql,int qr)
{
if (ql<=l&&r<=qr) return sum[x]%MOD;
int mid = (l+r)/2;
pushdown(x,l,r);
int res = 0;
if (ql<=mid) res+=query(2*x,l,mid,ql,qr);
if (qr>mid) res+=query(2*x+1,mid+1,r,ql,qr);
return res%MOD;
}
void add1(int x,int y,int z)
{
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
mod(1,1,n,id[top[x]],id[x],z);
x=f[top[x]];
}
if (id[x]>id[y]) swap(x,y);
mod(1,1,n,id[x],id[y],z);
}
void add2(int x,int z)
{
mod(1,1,n,id[x],id[x]+sz[x]-1,z);
}
int query1(int x,int y)
{
int res = 0;
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
res = (res+query(1,1,n,id[top[x]],id[x]))%MOD;
x=f[top[x]];
}
if (id[x]>id[y]) swap(x,y);
res+=query(1,1,n,id[x],id[y]);
return res%MOD;
}
int query2(int x)
{
return query(1,1,n,id[x],id[x]+sz[x]-1);
}
signed main()
{
n=read(),m=read(),R=read(),MOD=read();
for (int i = 1; i <= n; i++) ww[i]=read();
for (int i = 1; i < m; i++)
{
int x=read(),y=read();
a[x].push_back(y);
a[y].push_back(x);
}
dfs(R,0,1);
dfs2(R,0,R);
bt(1,1,n);
while (m--)
{
int op=read();
if (op==1)
{
int x=read(),y=read(),z=read();
add1(x,y,z);
}
if (op==2)
{
int x=read(),y=read();
writech(query1(x,y),'\n');
}
if (op==3)
{
int x=read(),z=read();
add2(x,z);
}
if (op==4)
{
int x=read();
writech(query2(x)%MOD,'\n');
}
}
return 0;
}