#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int k=0;char c;
while(!isdigit(c=getchar()));
while(isdigit(c)) k=k*10+c-48,c=getchar();
return k;
}
const int mod=99991,N=1e6+10;
int n,m,x,y,z,fa[N],top[N],son[N],siz[N],dep[N],val[N][2],cnt,topval[N][2];
bool op[N],key[N];
vector<int> E[N];
int ny(int x){
int k=mod-2,res=1;
while(k){
if(k&1) res=(res*x)%mod;
k=k>>1,x=(x*x)%mod;
}return res;
}
void dfs_pre(int u){
dep[u]=dep[fa[u]]+1,siz[u]=1;
for(int v:E[u]){
dfs_pre(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
else if(siz[v]==siz[son[u]]) son[u]=min(son[u],v);
}
}
void dfs_path(int u,int tp){
top[u]=tp;
if(son[u]) dfs_path(son[u],tp);
if(son[u]==0) key[u]=1;
if(fa[top[u]]) key[fa[top[u]]]=1;
for(int v:E[u])
if(v!=son[u])
dfs_path(v,v);
if(!key[u]) return;
if(fa[top[u]]){
val[fa[top[u]]][1]=(val[fa[top[u]]][1]*val[u][op[u]])%mod;
val[fa[top[u]]][0]=(val[fa[top[u]]][0]+val[u][op[u]])%mod;
}topval[top[u]][0]=(topval[top[u]][0]+val[u][op[u]])%mod;
topval[top[u]][1]=(topval[top[u]][1]*val[u][op[u]])%mod;
}
void update(int u,int kval,int lstval){
if(!key[u]) return;
topval[top[u]][0]=(topval[top[u]][0]+kval-lstval+mod)%mod;
topval[top[u]][1]=(topval[top[u]][1]*kval)%mod;
topval[top[u]][1]=(topval[top[u]][1]*ny(lstval))%mod;
if(fa[top[u]]){
int g=val[fa[top[u]]][op[fa[top[u]]]];
val[fa[top[u]]][0]=(val[fa[top[u]]][0]+kval-lstval+mod)%mod;
val[fa[top[u]]][1]=(val[fa[top[u]]][1]*kval)%mod;
val[fa[top[u]]][1]=(val[fa[top[u]]][1]*ny(lstval))%mod;
update(fa[top[u]],val[fa[top[u]]][op[fa[top[u]]]],g);
}
}
signed main(){
n=read(),m=read();
for(int i=2;i<=n;++i){
x=read();fa[i]=x;
E[x].push_back(i);
}dfs_pre(1);
for(int i=1;i<=n;++i){
x=read(); topval[i][1]=1;
op[i]=(x==1); val[i][1]=1;
if(x!=1&&x!=0) val[i][0]=x;
}dfs_path(1,1);
while(m--){
x=read(),y=read();
if(x==2) {
op[y]^=1;
update(y,val[y][op[y]],val[y][op[y]^1]);
}
if(x==3){
cout<<topval[top[y]][0]<<' '<<topval[top[y]][1]<<'\n';
continue;
}
if(x==1){
z=read();
swap(val[y][0],z);
update(y,val[y][0],z);
}
}
return 0;
}