#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7,maxm=2e5+7;
typedef long long ll;
inline ll read(){
ll s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
int head[maxn],to[maxm],Next[maxm],tot;
int dep[maxn],f[maxn],size[maxn],son[maxn];
int top[maxn],id[maxn],rk[maxn],dfn;
int n,m,qi,mod,a[maxn];
void add(int x,int y) {
to[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void dfs1(int x) {
size[x]=1,dep[x]=dep[f[x]]+1;
for(int i=head[x],v;i;i=Next[i]) {
v=to[i];
if(v==f[x]) continue;
f[v]=x;
dfs1(v);
size[x]+=size[v];
if(size[son[x]]<size[v]) son[x]=v;
}
}
void dfs2(int x,int tp) {
top[x]=tp,id[x]=++dfn,rk[dfn]=x;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x],v;i;i=Next[i]) {
v=to[i];
if(v==f[x]||v==son[x]) continue;
dfs2(v,v);
}
}
ll sum[maxn<<2],lazy[maxn<<2];
void push_down(int rt,int m) {
if(lazy[rt]) {
(lazy[rt<<1]+=lazy[rt])%=mod;
(lazy[rt<<1|1]+=lazy[rt])%=mod;
(sum[rt<<1]+=(m-(m>>1))*lazy[rt])%=mod;
(sum[rt<<1|1]+=(m>>1)*lazy[rt])%mod;
lazy[rt]=0;
}
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void build(int l,int r,int rt) {
lazy[rt]=0;
if(l==r) {
sum[rt]=a[rk[l]];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
(sum[rt]=sum[rt<<1]+sum[rt<<1|1])%=mod;
}
void update(int a,int b,ll c,int l,int r,int rt){
if(a<=l&&b>=r) {
(sum[rt]+=(r-l+1)*c)%mod;
(lazy[rt]+=c)%=mod;
return;
}
push_down(rt,r-l+1);
int mid=(l+r)>>1;
if(a<=mid) update(a,b,c,lson);
if(b>mid) update(a,b,c,rson);
(sum[rt]=sum[rt<<1]+sum[rt<<1|1])%=mod;
}
ll query(int a,int b,int l,int r,int rt) {
if(a<=l&&b>=r) return sum[rt];
push_down(rt,r-l+1);
int mid=(l+r)>>1;
ll ans=0;
if(a<=mid) ans+=query(a,b,lson);
if(b>mid) ans+=query(a,b,rson);
return ans%mod;
}
void Subupdate(int x,int y,ll c) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(id[top[x]],id[x],c,1,n,1);
x=f[top[x]];
}
if(id[x]>id[y]) swap(x,y);
update(id[x],id[y],c,1,n,1);
}
ll Subquery(int x,int y) {
ll res=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
(res+=query(id[top[x]],id[x],1,n,1))%=mod;
x=f[top[x]];
}
if(id[x]>id[y]) swap(x,y);
return (res+query(id[x],id[y],1,n,1))%mod;
}
int main() {
n=read(),m=read(),qi=read(),mod=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=2,u,v;i<=n;++i) {
u=read(),v=read();
add(u,v),add(v,u);
}
dfs1(qi),dfs2(qi,qi);
build(1,n,1);
for(int i=1,op,x,y,z;i<=m;++i) {
op=read(),x=read();
if(op==1) {
y=read(),z=read();
Subupdate(x,y,z);
}
else if(op==2) {
y=read();
printf("%lld\n",Subquery(x,y));
}
else if(op==3) {
z=read();
update(id[x],id[x]+size[x]-1,z,1,n,1);
}
else printf("%lld\n",query(id[x],id[x]+size[x]-1,1,n,1));
}
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7,maxm=1e5+7;
typedef long long ll;
inline ll read(){
ll s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
int head[maxn],to[maxm],Next[maxm],tot;
int dep[maxn],f[maxn],size[maxn],son[maxn];
int top[maxn],id[maxn],rk[maxn],dfn;
int n;
void add(int x,int y) {
to[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void dfs1(int x) {
size[x]=1,dep[x]=dep[f[x]]+1;
for(int i=head[x],v;i;i=Next[i]) {
v=to[i];
f[v]=x;
dfs1(v);
size[x]+=size[v];
if(son[x]==-1||size[son[x]]<size[v]) son[x]=v;
}
}
void dfs2(int x,int tp) {
top[x]=tp,id[x]=++dfn,rk[dfn]=x;
if(~son[x]) dfs2(son[x],tp);
for(int i=head[x],v;i;i=Next[i]) {
v=to[i];
if(v==son[x]) continue;
dfs2(v,v);
}
}
ll sum[maxn<<2],lazy[maxn<<2];
void push_down(int rt,int m) {
if(lazy[rt]!=-1) {
lazy[rt<<1]=lazy[rt];
lazy[rt<<1|1]=lazy[rt];
sum[rt<<1]=(m-(m>>1))*lazy[rt];
sum[rt<<1|1]=(m>>1)*lazy[rt];
lazy[rt]=-1;
}
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void update(int a,int b,ll c,int l,int r,int rt){
if(a<=l&&b>=r) {
sum[rt]=(r-l+1)*c;
lazy[rt]=c;
return;
}
push_down(rt,r-l+1);
int mid=(l+r)>>1;
if(a<=mid) update(a,b,c,lson);
if(b>mid) update(a,b,c,rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
ll query(int a,int b,int l,int r,int rt) {
if(a<=l&&b>=r) return sum[rt];
push_down(rt,r-l+1);
int mid=(l+r)>>1;
ll ans=0;
if(a<=mid) ans+=query(a,b,lson);
if(b>mid) ans+=query(a,b,rson);
return ans;
}
ll Subquery(int x,int y) {
ll res=0,tmp;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=id[x]-id[top[x]]+1-query(id[top[x]],id[x],1,n,1);
update(id[top[x]],id[x],1,1,n,1);
x=f[top[x]];
}
if(id[x]>id[y]) swap(x,y);
tmp=query(id[x],id[y],1,n,1);
update(id[x],id[y],1,1,n,1);
return res+id[y]-id[x]+1-tmp;
}
string s;
int main() {
n=read();
for(int i=1,u;i<n;++i) {
u=read();
add(u,i);
}
memset(son,-1,sizeof son);//zhu yi
memset(lazy,-1,sizeof lazy);
dfs1(0),dfs2(0,0);
int q=read();
for(int i=1,x;i<=q;++i) {
cin>>s; x=read();
if(s=="install") {
cout<<Subquery(x,0)<<endl;
}
else {
cout<<query(id[x],id[x]+size[x]-1,1,n,1)<<endl;
update(id[x],id[x]+size[x]-1,0,1,n,1);
}
}
}