#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m,root,cnt,fa[N],depth[N],siz[N],son[N],top[N],dfn[N],rnk[N],R[N];
long long mod,a[N],Bit1[N],Bit2[N];
vector<int>G[N];
inline int lowbit(int x) {return x&-x;}
inline void add(int x,long long d) {
long long tmp=d*x;
while (x<=n) {
Bit1[x]+=d,Bit1[x]%=mod;
Bit2[x]+=tmp,Bit2[x]%=mod;
x+=lowbit(x);
}
return;
}
inline int get1(int x) {
long long res=0;
while (x) {
res+=Bit1[x],res%=mod;
x-=lowbit(x);
}
return res;
}
inline int get2(int x) {
long long res=0;
while (x) {
res+=Bit2[x],res%=mod;
x-=lowbit(x);
}
return res;
}
void dfs1(int p,int lst) {
int Siz=G[p].size();
fa[p]=lst,depth[p]=depth[lst]+1,siz[p]=1;
for (int i=0;i<Siz;i++) {
int x=G[p][i];
if (x!=lst) {
dfs1(x,p);
siz[p]+=siz[x];
if (siz[x]>siz[son[p]]) son[p]=x;
}
}
return;
}
void dfs2(int p,int t) {
top[p]=t,dfn[p]=++cnt,rnk[cnt]=p;
if (!son[p]) {
R[p]=cnt;
return;
}
dfs2(son[p],t);
int Siz=G[p].size();
for (int i=0;i<Siz;i++) {
int x=G[p][i];
if (x!=son[p]&&x!=fa[p]) dfs2(x,x);
}
R[p]=cnt;
return;
}
inline long long get(int l,int r) {
long long res=((r+1ll)*get1(r)-l*get1(l-1)-(get2(r)-get2(l-1)))%mod;
return res<0?res+mod:res;
}
inline void upd1(int x,int y,long long d) {
while (top[x]!=top[y]) {
if (depth[top[x]]<depth[top[y]]) add(dfn[top[y]],d),add(dfn[y]+1,-d),y=fa[top[y]];
else add(dfn[top[x]],d),add(dfn[x]+1,-d),x=fa[top[x]];
}
if (depth[x]<depth[y]) add(dfn[x],d),add(dfn[y]+1,-d);
else add(dfn[y],d),add(dfn[x]+1,-d);
return;
}
inline void upd2(int x,long long d) {
add(dfn[x],d),add(R[x]+1,-d);
return;
}
inline long long ans1(int x,int y) {
long long res=0;
while (top[x]!=top[y]) {
if (depth[top[x]]<depth[top[y]]) res+=get(dfn[top[y]],dfn[y]),y=fa[top[y]];
else res+=get(dfn[top[x]],dfn[x]),x=fa[top[x]];
}
if (depth[x]<depth[y]) res+=get(dfn[x],dfn[y]);
else res+=get(dfn[y],dfn[x]);
return res%mod;
}
inline long long ans2(int x) {
return get(dfn[x],R[x]);
}
int main() {
scanf("%d %d %d %lld",&n,&m,&root,&mod);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
for (int i=1;i<n;i++) {
int x,y;
scanf("%d %d",&x,&y);
G[x].push_back(y),G[y].push_back(x);
}
dfs1(root,0);
dfs2(root,root);
for (int i=1;i<=n;i++) add(i,a[rnk[i]]-a[rnk[i-1]]);
for (int i=1;i<=m;i++) {
int opt,x,y;
long long z;
scanf("%d %d",&opt,&x);
if (opt==1) {
scanf("%d %lld",&y,&z);
upd1(x,y,z);
} else if (opt==2) {
scanf("%d",&y);
printf("%lld\n",ans1(x,y));
} else if (opt==3) {
scanf("%lld",&z);
upd2(x,z);
} else printf("%lld\n",ans2(x));
}
return 0;
}