Problem:
Score : 300 points

Problem Statement

Given is an integer sequence D_1,...,D_N of N elements. Find the number, modulo 998244353, of trees with N vertices numbered 1 to N that satisfy the following condition:

For every integer i from 1 to N, the distance between Vertex 1 and Vertex i is D_i.

Notes

A tree of N vertices is a connected undirected graph with N vertices and N-1 edges, and the distance between two vertices are the number of edges in the shortest path between them.

Two trees are considered different if and only if there are two vertices x and y such that there is an edge between x and y in one of those trees and not in the other.

Constraints

1 \leq N \leq 10^5

0 \leq D_i \leq N-1

Input

Input is given from Standard Input in the following format:

N
D_1 D_2 ... D_N

Output

Print the answer.

Sample Input 1

4
0 1 1 2

Sample Output 1

2

For example, a tree with edges (1,2), (1,3), and (2,4) satisfies the condition.

Sample Input 2

4
1 1 1 1

Sample Output 2

0

Sample Input 3

7
0 3 2 1 2 2 1

Sample Output 3

24

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;


class Program {

	//static long mod = 1000000007;
	static long mod =998244353; 
	static void Main(string[] args) {

		char[] cs = new char[] { ' ' };
		//char[] cs = new char[] { ' ', ',' };

		//int n = int.Parse(Console.ReadLine());
		//int val = int.Parse(Console.ReadLine());
		//int[] vals = parseAry(Console.ReadLine().Split(cs));
		//string str = Console.ReadLine();
		//string[] strs = Console.ReadLine().Split(cs);

		//string res = "";


		long res = 0;


		int n = int.Parse(Console.ReadLine());
		//int[] vals = new int[n];
		int[] vals = parseAry(Console.ReadLine().Split(cs));

		/*

		for ( int i = 1; i < n/2; i++ ) {
			vals[i] = i;
			vals[i+(n/2)] = i;
		}*/

			if ( vals[0] != 0 ) { Console.WriteLine(0); return; }
		long[] num = new long[n];
		for ( int i = 1; i < n; i++ ) {
			if ( vals[i] == 0 ) { res = 0; Console.WriteLine(res); break; }
			num[vals[i]]++;
		}
		res=1;
		for ( int i = 2; i < n; i++ ) {
			if ( num[i] == 0 ) {
				for ( int k = i; i < n; i++ ) {
					if ( num[i] != 0 ) { res = 0; break; }
				}
				break;
			}
			long p=(long)mod_pow(num[i-1],num[i])%mod;
			res = ( res * p) % mod;
		}


			Console.WriteLine(res);

		return;

	}
	static public long mod_pow(long x, long n) {
		long res = 1;
		while ( n > 0 ) {
			if ( ( n & 1 ) == 1 ) { res = res * x % mod; }
			x = (x * x) % mod;
			n >>= 1;
		}
		return res;
	}

	//	int配列をスペース区切りの文字列に変換
	static string stringBuilderArrayInt(int[] a) {
		StringBuilder sb = new StringBuilder();

		for ( int i = 0; i < a.Length; i++ ) {
			sb.Append(a[i] + " "); 
		}
		if ( sb.Length > 1 ) {
			sb = sb.Remove(sb.Length - 1, 1);
		}
		return sb.ToString(); ;
	}


	//	文字列strをindex番目からdで上書き
	static string strOverWrite(string str, int i, string s) {
		return str.Remove(i, s.Length).Insert(i, s);
	}

	//　String[]  ----->  int[]
	static int[] parseAry(string[] str) {
		int[] nums = new int[str.Length];
		for ( int i = 0; i < str.Length; i++ ) { nums[i] = int.Parse(str[i]); }
		return nums;
	}
	//　String[]  ----->  long[]
	static long[] parseAryL(string[] str) {
		long[] nums = new long[str.Length];
		for ( int i = 0; i < str.Length; i++ ) { nums[i] = long.Parse(str[i]); }
		return nums;
	}

	//文字列を1文字ずつString[]に入れる
	static string[] strAry(String str) {
		string[] re = new string[str.Length];
		for ( int i = 0; i < str.Length; i++ ) { re[i] = str[i].ToString(); }
		return re;
	}



}