#include<bits/stdc++.h>
using namespace std;
int Size[100011],dep[100010],fa[100011],son[100011],tid[100011],top[100011],footmark[400011],n,m,r,p;
int cin1,cin2,cin3,cin4,t=0,st[400001],lazy[400001],num[100001]; 
vector<int>T[100001];
void pushdown(int rt,int l,int r)
{
	if(lazy[rt]&&l!=r)
	{
		int mid=l+r>>1;
		lazy[rt<<1]+=lazy[rt];
		lazy[rt<<1|1]+=lazy[rt];
		st[rt<<1]=(st[rt<<1]+(mid-l+1)*lazy[rt])%p; 
		st[rt<<1|1]=(st[rt<<1|1]+(r-mid)*lazy[rt])%p;
		lazy[rt]=0;
	}
}
void dfs(int x,int pre)
{
	dep[x]=dep[pre]+1;Size[x]=1,fa[x]=pre;
	for(int i=0;i<T[x].size();i++)
	if(T[x][i]!=pre)
		{
			int v=T[x][i];
			if(v!=pre)dfs(v,x);
			Size[x]+=Size[v];
	
			if(Size[son[x]]<Size[v])son[x]=v;
		}
}
void dfs2(int u,int pre,int tp)
{
	tid[u]=++t;
	footmark[t]=u;
	top[u]=tp;
	if(son[u])dfs2(son[u],u,tp);
	for(int i=0;i<T[u].size();i++)
	{
		int v=T[u][i];
		if(v!=son[u]&&v!=pre)dfs2(v,u,v);
	}
}
int creat(int rt,int l,int r)
{
	int mid=(l+r)/2;
	if(l==r)return st[rt]=num[footmark[l]];
	st[rt]=(creat(rt*2,l,mid)+creat(rt*2+1,mid+1,r))%p;
	return st[rt];
}
void add(int rt,int l,int r,int s,int e,int x)
{
	
	if(s<=l&&r<=e) {
		lazy[rt]+=x;
		st[rt]=(st[rt]+(r-l+1)*x)%p; 
		return;
	}
	pushdown(rt,l,r);
	int mid=(l+r)/2;
	if(s<=mid)add(rt*2,l,mid,s,e,x);	
	if(e>mid)add(rt*2+1,mid+1,r,s,e,x);
	st[rt]=(st[rt<<1]+st[rt<<1|1])%p;
}
int query(int rt,int l,int r,int s,int e)
{
	if(s<=l&&r<=e)return st[rt];
	pushdown(rt,l,r);
	int ans=0,mid=(l+r)/2;	
	if(s<=mid)ans=(query(rt<<1,l,mid,s,e))%p;
	if(e>mid)ans=(ans+query(rt*2+1,mid+1,r,s,e))%p;
	return ans%p;
}
int query2(int u,int v)
{
	int l,r,ans=0;
	while(1)
	{
		if(top[u]==top[v])
		{
			l=min(tid[u],tid[v]);
			r=max(tid[v],tid[u]);
			int tmp=query(1,1,n,l,r)%p;
			return ans=(ans+tmp)%p;
		}
		else
		{
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			l=tid[top[u]];
			r=tid[u];
			int tmp=query(1,1,n,l,r);
			ans=(ans+tmp)%p;
			u=fa[top[u]];
		}
	}
}
void add2(int u,int v,int x)
{
	int l,r;
	while(1)
	{
		if(top[u]==top[v])
		{
			l=min(tid[u],tid[v]);
			r=max(tid[v],tid[u]);
			add(1,1,n,l,r,x);
			return;
		}
		else
		{
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			l=tid[top[u]];
			r=tid[u];
			add(1,l,n,1,r,x);
			u=fa[top[u]];			
		}
	}
}
int main(){
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++)
	{	
		cin>>num[i];
	}
	for(int i=1;i<n;i++)
	{
		cin>>cin1>>cin2;
		T[cin1].push_back(cin2);
		T[cin2].push_back(cin1);
	}
	dfs(r,r);
	dfs2(r,r,r);
	creat(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>cin1;	
			
		if(cin1==1)
		{
			cin>>cin2>>cin3>>cin4;
			add2(cin2,cin3,cin4); 
				
		}
		else if(cin1==2)
		{
			cin>>cin2>>cin3;
			cout<<query2(cin2,cin3)%p<<endl;
	
			
		}
		else if(cin1==3)
		{
			cin>>cin2>>cin3;
			add(1,1,n,tid[cin2],tid[cin2]+Size[cin2]-1,cin3);
	
		}
		else
		{
			cin>>cin2;
			cout<<query(1,1,n,tid[cin2],tid[cin2]+Size[cin2]-1)%p<<endl;
				
		}
	}	
	return 0;
}