#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define ll long long
int P;
int a[N];
int last[N], nxt[N * 2], to[N * 2], len = 0;
int si[N], hv[N], fa[N], dp[N], dfn[N], tp[N];
ll f[N * 4], bz[N * 4];
void add(int x, int y) {
to[++len] = y;
nxt[len] = last[x];
last[x] = len;
}
void dfs0(int k) {
si[k] = 1, dp[k] = dp[fa[k]] + 1;
for(int i = last[k]; i; i = nxt[i]) if(to[i] != fa[k]) {
fa[to[i]] = k;
dfs0(to[i]);
si[k] += si[to[i]];
if(si[to[i]] > si[hv[k]]) hv[k] = to[i];
}
}
void dfs(int k, int rt) {
dfn[k] = ++dfn[0];
tp[k] = rt;
if(hv[k]) dfs(hv[k], rt);
for(int i = last[k]; i; i = nxt[i]) if(to[i] != fa[k] && to[i] != hv[k]) dfs(to[i], to[i]);
}
void down(int v, int l, int r, int mid) {
f[v * 2] = (f[v * 2] + bz[v] * (mid - l + 1)) % P;
f[v * 2 + 1] = (f[v * 2 + 1] + bz[v] * (r - mid)) % P;
bz[v * 2] = (bz[v * 2] + bz[v]) % P;
bz[v * 2 + 1] = (bz[v * 2 + 1] + bz[v]) % P;
bz[v] = 0;
}
void ins(int v, int l, int r, int x, int y, ll c) {
if(x <= l && r <= y) {
f[v] = (f[v] + c * (r - l + 1)) % P;
bz[v] = (bz[v] + c) % P;
}
else {
int mid = (l + r) / 2;
down(v, l, r, mid);
if(x <= mid) ins(v * 2, l, mid, x, y, c);
if(y > mid) ins(v * 2 + 1, mid + 1, r, x, y, c);
f[v] = (f[v * 2] + f[v * 2 + 1]) % P;
}
}
ll find(int v, int l, int r, int x, int y) {
if(x <= l && r <= y) return f[v];
int mid = (l + r) / 2;
down(v, l, r, mid);
ll s = 0;
if(x <= mid) s = (s + find(v * 2, l, mid, x, y)) % P;
if(y > mid) s = (s + find(v * 2 + 1, mid + 1, r, x, y)) % P;
f[v] = (f[v * 2] + f[v * 2 + 1]) % P;
return s;
}
int main() {
int n, Q, rt, i, x, y, z, op;
scanf("%d%d%d%d", &n, &Q, &rt, &P);
for(i = 1; i <= n; i++) scanf("%d", &a[i]);
for(i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y), add(y, x);
}
dfs0(rt);
dfs(rt, rt);
for(i = 1; i <= n; i++) ins(1, 1, n, dfn[i], dfn[i], a[i]);
while(Q--) {
scanf("%d", &op);
if(op == 1) {
scanf("%d%d%d", &x, &y, &z);
int f1 = tp[x], f2 = tp[y];
while(f1 != f2) {
if(dp[f1] < dp[f2]) swap(x, y), swap(f1, f2);
ins(1, 1, n, dfn[f1], dfn[x], z);
x = fa[f1], f1 = tp[x];
}
if(dp[x] < dp[y]) swap(x, y);
ins(1, 1, n, dfn[y], dfn[x], z);
}
else if(op == 2) {
scanf("%d%d%", &x, &y);
ll ans = 0;
int f1 = tp[x], f2 = tp[y];
while(f1 != f2) {
if(dp[f1] < dp[f2]) swap(x, y), swap(f1, f2);
ans = (ans + find(1, 1, n, dfn[f1], dfn[x])) % P;
x = fa[f1], f1 = tp[x];
}
if(dp[x] < dp[y]) swap(x, y);
ans = (ans + find(1, 1, n, dfn[y], dfn[x])) % P;
printf("%lld
", ans);
}
else if(op == 3) {
scanf("%d%d", &x, &z);
ins(1, 1, n, dfn[x], dfn[x] + si[x] - 1, z);
}
else {
scanf("%d", &x);
printf("%lld
", find(1, 1, n, dfn[x], dfn[x] + si[x] - 1));
}
}
return 0;
}