#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;
}