#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <map>
#include <stack>
#include <queue>
#include <iomanip>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;

#include <vector>

template <long long Modulus = 1000000007>
struct MInt
{
    long long x;
    static const long long mod = Modulus;
    
    MInt(long long a = 0) : x((a % mod + mod) % mod) {}

    // operator
    MInt& operator = (const MInt& a)
    {
        x = a.x;
        return *this;
    }
    MInt& operator = (const long long& a)
    {
        *this = MInt(a);
        return *this;
    }

    MInt operator -() const
    { 
        return MInt(-x);
    };

    MInt& operator +=(const MInt& a)
    {
        if ((x += a.x) >= mod)
            x -= mod;
        return *this;
    }

    MInt& operator -=(const MInt& a)
    {
        if ((x += mod - a.x) > mod)
            x -= mod;
        return *this;
    }

    MInt& operator *=(const MInt& a)
    {
        x *= a.x;
        x = x % mod;
        return *this;
    }

    MInt operator+(const MInt& a) const
    {
        MInt res(*this);
        return res += a;
    }

    MInt operator-(const MInt& a) const
    {
        MInt res(*this);
        return res -= a;
    }

    MInt operator*(const MInt& a) const
    {
        MInt res(*this);
        return res *= a;
    }

    MInt pow(long long t) const
    {
        if (t == 0)
            return 1;
        MInt a = pow(t >> 1);
        a *= a;
        if (t & 1)
            a *= *this;
        return a;
    }

    // only for prime mod
    MInt Inv() const
    {
        return pow(mod - 2);
    }
    // only for prime mod
    MInt& operator/=(const MInt& a)
    {
        return (*this) *= a.Inv();
    }
    MInt operator/(const MInt& a) const
    {
        MInt res(*this);
        return res /= a;
    }
};

template <class TMInt = MInt<>>
struct Comb
{
    std::vector<TMInt> fact, invfact, inv;
    long long mod;
    Comb(int n) : fact(n+1), invfact(n+1), inv(n+1)
    {
        fact[0] = fact[1] = 1;
        mod = fact[0].mod;
        invfact[0] = invfact[1] = 1;
        inv[1] = 1;
        for (int i = 2; i < n; ++i)
        {
            fact[i] = fact[i - 1] * TMInt(i);
            long long invx = inv[mod % i].x * (mod - mod / i) % mod;
            inv[i] = TMInt(invx);
            invfact[i] = invfact[i - 1] * inv[i];
        }
    }

    TMInt operator()(int n, int k)
    {
        if (k < 0 || n < k)
            return 0;
        return fact[n] * invfact[k] * invfact[n - k];
    }
};


int main()
{
    static const ll mod = 998244353;
    static const int nmax = 100100;
    using Modll = MInt<mod>;
    ll n;
    scanf("%lld", &n);
    vector<ll> d(n);
    for (int i = 0; i < n; ++i) scanf("%lld", &d[i]);
    if (d[0] != 0)
    {
        printf("%d\n", 0);
        return 0;
    }
    if (n == 1)
    {
        if (d[0] != 0)
        {
            printf("%d\n", 0);
            return 0;
        }
        else
        {
            printf("%d\n", 1);
            return 0;
        }
    }

    vector<vector<ll>> dmap(n, vector<ll>());  // dmap[d] : 根との距離が d である頂点のリスト
    for (int i = 0; i < n; ++i)
    {
        dmap[d[i]].push_back(i);
    }
    if (dmap[0].size() > 1)
    {
        printf("%d\n", 0);
        return 0;
    }

    Modll ans(1);
    for (int k = 1; k < n; ++k)
    {
        if (dmap[k-1].size() == 0 && dmap[k].size() != 0)
        {
            printf("%d\n", 0);
            return 0;
        }

        if (dmap[k-1].size() == 0 && dmap[k].size() == 0) continue;
        ans *= Modll(dmap[k-1].size()).pow(dmap[k].size());
    }
    printf("%lld\n", ans.x);
    return 0;
}


Measured memory_bytes: 9436