Buggy python submission (verdict: Runtime Error):
import sys

sys.setrecursionlimit(100000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):
    deep[D[i]] += 1

# 深さ0の頂点が1以外なら、木ができないため0を返す
if deep[0] != 1:
    print(0)
# それ以外なら各深さの辺のつけ方を計算して返す
else:
    print(dfs(1, len(deep), 1) % JOSU)



Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):
    deep[D[i]] += 1

# 深さ0の頂点が1以外なら、木ができないため0を返す
if deep[0] != 1:
    print(0)
# それ以外なら各深さの辺のつけ方を計算して返す
else:
    print(dfs(1, len(deep), 1) % JOSU)



Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（現在の深さ ^ その深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (now ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):
    deep[D[i]] += 1

# 深さ0の頂点が1以外なら、木ができないため0を返す
if deep[0] != 1:
    print(0)
# 深さ0の頂点のみなら、1を返す
elif len(deep) == 1:
    print(1)
# それ以外なら各深さの辺のつけ方を計算して返す
else:
    print(dfs(1, len(deep), 1) % JOSU)



Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（現在の深さ ^ その深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (now ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):
    deep[D[i]] += 1

# 深さ0の頂点が1以外なら、木ができないため0を返す
if deep[D[0]] != 1:
    print(0)
# 深さ0の頂点のみなら、1を返す
elif len(deep) == 1:
    print(1)
# それ以外なら各深さの辺のつけ方を計算して返す
else:
    print(dfs(1, len(deep), 1) % JOSU)



Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（現在の深さ ^ その深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (now ** deep[now]))
# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):
    deep[D[i]] += 1

# 深さ0の頂点が1以外なら、木ができないため0を返す
if deep[D[0]] != 1:
    print(0)
# 深さ0の頂点のみなら、1を返す
elif len(deep) == 1:
    print(1)
# それ以外なら各深さの辺のつけ方を計算して返す
else:
    print(dfs(1, len(deep), 1) % JOSU)



Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# メモ
# 連結無効グラフ　＝　全部が繋がっている

# N = int(input())
# D = list(map(int, input()))

N = int(input())
D = list(map(int, input().split()))

JOSU = 998244353

anser = 0

deep = [-1] * (N + 1)
memo = [0] * N

# 各深さの数を求める
for i in range(N):
    if deep[D[i]] == -1:
        deep[D[i]] = 0
    deep[D[i]] += 1

def dfs(n, end, sum):
    if n == end:
        return sum
    elif deep[n + 1] == -1:
        return dfs(n + 1, end, sum)
    else:
        return dfs(n + 1, end, sum * deep[n] ** deep[n + 1])

if deep[0] != 1:
    print(0)
else:
    print(dfs(0, N, 1) % JOSU)

Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# メモ
# 連結無効グラフ　＝　全部が繋がっている

# N = int(input())
# D = list(map(int, input()))

N = int(input())
D = list(map(int, input().split()))

JOSU = 998244353

anser = 0

deep = [-1] * (N + 1)
deep[0] = 0
memo = [0] * N

# 各深さの数を求める
for i in range(N):
    if deep[D[i]] == -1:
        deep[D[i]] = 0
    deep[D[i]] += 1

def dfs(n, end, sum):
    if n == end:
        return sum
    elif deep[n + 1] == -1:
        return dfs(n + 1, end, sum)
    else:
        return dfs(n + 1, end, sum * deep[n] ** deep[n + 1])

print(dfs(0, N, 1) % JOSU)

Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)

Buggy python submission (verdict: Runtime Error):
# メモ
# 連結無効グラフ　＝　全部が繋がっている

# N = int(input())
# D = list(map(int, input()))

N = int(input())
D = list(map(int, input().split()))

JOSU = 998244353

anser = 0

deep = [-1] * (N + 1)
deep[0] = 0
memo = [0] * N

# 各深さの数を求める
for i in range(N):
    if deep[D[i]] == -1:
        deep[D[i]] = 0
    deep[D[i]] += 1

def dfs(n, end, sum):
    if n == end:
        return sum
    elif deep[n] == -1 or deep[n + 1] == -1:
        return dfs(n + 1, end, sum)
    else:
        return dfs(n + 1, end, sum * deep[n] ** deep[n + 1])

print(dfs(0, N, 1) % JOSU)

Fixed submission:
# 再帰関数の最大再帰回数を変更
import sys
sys.setrecursionlimit(1000000)

# 再帰関数で作る木の個数を返す
def dfs(now, end, summary):
    # 終了条件
    if now == end:
        return summary
    # 1つ前の頂点時点で作ることのできる木の個数 *（１つ前の深さの頂点の数 ^ 現在の深さの頂点の数）で再帰関数
    else:
        return dfs(now + 1, end, summary * (deep[now - 1] ** deep[now]))

# 最後に割る数の定数
JOSU = 998244353

# 入力
N = int(input())
D = list(map(int, input().split()))

# 深さをメモするため、Dの最大値 + 1の数の配列を用意
# 例：深さの最大が2なら、0, 1, 2の3つが必要
deep = [0] * (max(D) + 1)

# 各深さの頂点の数を記録
for i in range(N):

    # 頂点1が深さ0以外なら制約違反
    if i == 0 and D[i] != 0:
        print(0)
        exit()
    # 頂点1以外が深さ0なら制約違反
    elif i > 0 and D[i] == 0:
        print(0)
        exit()

    deep[D[i]] += 1

# 再帰関数で計算
print(dfs(1, len(deep), 1) % JOSU)