#include<bits/stdc++.h>
#define ls u*2
#define rs u*2+1
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=1e5+10,mod=998244353;
vector<int> e[N];
int dfn[N],sz[N],ts;
int dep[N],fa[N],top[N],son[N],seq[N];
struct node
{
int l,r;
int w;
int sum,add;
}tr[N*4];
int n,m,K;
vector<PII> q[N];
int ans[N];
void add(int u,int c)
{
tr[u].sum=(tr[u].sum+(tr[u].w*c)%mod)%mod;
tr[u].add+=c;
}
int qmi(int a,int k,int p)
{
int res=1;
while(k)
{
if(k&1) res=(res*a)%p;
a=(a*a)%p;
k>>=1;
}
return res;
}
void pushup(int u)
{
tr[u].sum=(tr[ls].sum+tr[rs].sum)%mod;
}
void pushdown(int u)
{
if(tr[u].add)
{
add(ls,tr[u].add),add(rs,tr[u].add);
tr[u].add=0;
}
}
void build(int u,int l,int r)
{
tr[u]={l,r,0,0,0};
if(l==r)
{
tr[u].w=(qmi(dep[seq[l]],K,mod)-qmi(dep[seq[l]]-1,K,mod)+mod)%mod;
return;
}
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
tr[u].w=(tr[ls].w+tr[rs].w)%mod;
}
void modify(int u,int l,int r,int c)
{
if(tr[u].l>=l&&tr[u].r<=r) add(u,c);
else
{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) modify(ls,l,r,c);
if(r>mid) modify(rs,l,r,c);
pushup(u);
}
}
int query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;
else
{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
int res=0;
if(l<=mid) res=(res+query(ls,l,r))%mod;
if(r>mid) res=(res+query(rs,l,r))%mod;
return res;
}
}
void dfs1(int u,int p,int d)
{
dep[u]=d,fa[u]=p,sz[u]=1;
for(auto v:e[u])
{
if(v==p) continue;
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int t)
{
dfn[u]=++ts,top[u]=t,seq[dfn[u]]=u;
if(!son[u]) return;
dfs2(son[u],t);
for(auto v:e[u])
{
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void modify_path(int u,int v)
{
if(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
modify(1,dfn[top[u]],dfn[u],1);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
modify(1,dfn[v],dfn[u],1);
}
int query_path(int u,int v)
{
int res=0;
if(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res=(res+query(1,dfn[top[u]],dfn[u]))%mod;
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res=(res+query(1,dfn[v],dfn[u]))%mod;
return res;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m>>K;
for(int i=2,x;i<=n;i++)
{
cin>>x;
e[x].push_back(i),e[i].push_back(x);
}
dfs1(1,0,1);
dfs2(1,1);
build(1,1,n);
for(int i=1,x,z;i<=m;i++)
{
cin>>x>>z;
q[x].push_back({z,i});
}
for(int i=1;i<=n;i++)
{
modify_path(1,i);
for(auto qus:q[i])
{
int z=qus.first,id=qus.second;
ans[id]=query_path(1,z);
}
}
for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";
return 0;
}