class
LcaDoubling:
def
__init__(
self
, n, links, root
=
0
):
self
.depths
=
[
-
1
]
*
n
prev_ancestors
=
self
._init_dfs(n, links, root)
self
.ancestors
=
[prev_ancestors]
max_depth
=
max
(
self
.depths)
d
=
1
while
d < max_depth:
next_ancestors
=
[prev_ancestors[p]
for
p
in
prev_ancestors]
self
.ancestors.append(next_ancestors)
d <<
=
1
prev_ancestors
=
next_ancestors
def
_init_dfs(
self
, n, links, root):
q
=
[(root,
-
1
,
0
)]
direct_ancestors
=
[
-
1
]
*
(n
+
1
)
while
q:
v, p, dep
=
q.pop()
direct_ancestors[v]
=
p
self
.depths[v]
=
dep
q.extend((u, v, dep
+
1
)
for
u
in
links[v])
return
direct_ancestors
def
get_lca(
self
, u, v):
du, dv
=
self
.depths[u],
self
.depths[v]
if
du > dv:
u, v
=
v, u
du, dv
=
dv, du
tu
=
u
tv
=
self
.upstream(v, dv
-
du)
if
u
=
=
tv:
return
u
for
k
in
range
(du.bit_length()
-
1
,
-
1
,
-
1
):
mu
=
self
.ancestors[k][tu]
mv
=
self
.ancestors[k][tv]
if
mu !
=
mv:
tu
=
mu
tv
=
mv
lca
=
self
.ancestors[
0
][tu]
assert
lca
=
=
self
.ancestors[
0
][tv]
return
lca
def
upstream(
self
, v, k):
i
=
0
while
k:
if
k &
1
:
v
=
self
.ancestors[i][v]
k >>
=
1
i
+
=
1
return
v
def
solve(n, m, k, ppp):
parents
=
[
-
1
]
children
=
[[]
for
_
in
range
(n)]
for
i, p
in
enumerate
(ppp, start
=
1
):
p
-
=
1
parents.append(p)
children[p].append(i)
lca
=
LcaDoubling(n, links
=
children)
order_limit
=
[
-
1
]
*
n
p_load
=
[
0
]
*
n
p_drop
=
[
0
]
*
n
l_load
=
[
0
]
*
n
l_drop
=
[
0
]
*
n
r_load
=
[
0
]
*
n
r_drop
=
[
0
]
*
n
diff
=
[
0
]
*
n
for
_
in
range
(m):
s, t
=
map
(
int
,
input
().split())
s
-
=
1
t
-
=
1
c
=
lca.get_lca(s, t)
diff[s]
+
=
1
diff[t]
-
=
1
if
s
=
=
c:
if
len
(children[s])
=
=
1
:
l_load[s]
+
=
1
else
:
v
=
children[c][
0
]
d
=
lca.get_lca(t, v)
if
d
=
=
v:
l_load[s]
+
=
1
else
:
r_load[s]
+
=
1
p_drop[t]
+
=
1
elif
t
=
=
c:
if
len
(children[t])
=
=
1
:
l_drop[t]
+
=
1
else
:
v
=
children[c][
0
]
d
=
lca.get_lca(s, v)
if
d
=
=
v:
l_drop[t]
+
=
1
else
:
r_drop[t]
+
=
1
p_load[s]
+
=
1
else
:
p_load[s]
+
=
1
p_drop[t]
+
=
1
v
=
children[c][
0
]
d
=
lca.get_lca(s, v)
if
d
=
=
v:
ol
=
0
else
:
ol
=
1
if
order_limit[c]
=
=
-
1
:
order_limit[c]
=
ol
elif
order_limit[c] !
=
ol:
return
0
MOD
=
998244353
q
=
[
0
]
status
=
[
0
]
*
n
dp
=
[[
0
]
*
(k
+
1
)
for
_
in
range
(n)]
while
q:
v
=
q[
-
1
]
if
status[v]
=
=
0
:
status[v]
=
1
q.extend(children[v])
continue
q.pop()
dpv
=
dp[v]
if
len
(children[v])
=
=
0
:
pl
=
p_load[v]
pd
=
p_drop[v]
x_max
=
min
(k, k
+
pd
-
pl)
for
x
in
range
(pd, x_max
+
1
):
dpv[x]
=
1
elif
len
(children[v])
=
=
1
:
c
=
children[v][
0
]
d
=
diff[c]
dpc
=
dp[c]
pl
=
p_load[v]
pd
=
p_drop[v]
ll
=
l_load[v]
ld
=
l_drop[v]
x_min
=
max
(
0
, pd, pd
-
ll
-
d, pd
-
ll
-
d
+
ld)
x_max
=
min
(k, k
+
pd
-
ll, k
+
pd
-
ll
-
d, k
+
pd
-
ll
-
d
+
ld
-
pl)
for
x
in
range
(x_min, x_max
+
1
):
dpv[x]
=
dpc[x
-
pd
+
ll]
else
:
c0, c1
=
children[v]
pl
=
p_load[v]
pd
=
p_drop[v]
ll
=
l_load[v]
ld
=
l_drop[v]
rl
=
r_load[v]
rd
=
r_drop[v]
if
order_limit[v]
=
=
0
:
two_children_update(dpv, dp[c0], dp[c1], diff[c0], diff[c1], pl, pd, ll, ld, rl, rd, MOD)
elif
order_limit[v]
=
=
1
:
two_children_update(dpv, dp[c1], dp[c0], diff[c1], diff[c0], pl, pd, rl, rd, ll, ld, MOD)
else
:
two_children_update(dpv, dp[c0], dp[c1], diff[c0], diff[c1], pl, pd, ll, ld, rl, rd, MOD)
two_children_update(dpv, dp[c1], dp[c0], diff[c1], diff[c0], pl, pd, rl, rd, ll, ld, MOD)
if
v >
0
:
p
=
parents[v]
diff[p]
+
=
diff[v]
return
dp[
0
][
0
]
def
two_children_update(dpv, dp0, dp1, d0, d1, pl, pd, ll, ld, rl, rd, MOD):
x_min
=
max
(
0
, pd, pd
-
ll
-
d0, pd
-
ll
-
d0
+
ld, pd
-
ll
-
d0
+
ld
-
rl
-
d1,
pd
-
ll
-
d0
+
ld
-
rl
-
d1
+
rd)
x_max
=
min
(k, k
+
pd
-
ll, k
+
pd
-
ll
-
d0, k
+
pd
-
ll
-
d0
+
ld
-
rl,
k
+
pd
-
ll
-
d0
+
ld
-
rl
-
d1, k
+
pd
-
ll
-
d0
+
ld
-
rl
-
d1
+
rd
-
pl)
for
x
in
range
(x_min, x_max
+
1
):
dpv[x]
+
=
dp0[x
-
pd
+
ll]
*
dp1[x
-
pd
+
ll
+
d0
-
ld
+
rl]
dpv[x]
%
=
MOD
n, m, k
=
map
(
int
,
input
().split())
ppp
=
list
(
map
(
int
,
input
().split()))
ans
=
solve(n, m, k, ppp)
print
(ans)