#include <bits/stdc++.h>   using namespace std;   template <int MOD, int RT>   struct Mint {     static const int mod = MOD;     static constexpr Mint rt() { return RT; }     int v;     explicit operator int() const { return v; }     Mint() { v = 0; }     Mint(long long _v) {       v = int((-MOD < _v && _v < MOD) ? _v : _v % MOD);       if (v < 0) v += MOD;     }     friend bool operator==(const Mint& a, const Mint& b) { return a.v == b.v; }     friend bool operator!=(const Mint& a, const Mint& b) { return !(a == b); }     friend bool operator<(const Mint& a, const Mint& b) { return a.v < b.v; }     friend bool operator>(const Mint& a, const Mint& b) { return a.v > b.v; }     friend bool operator<=(const Mint& a, const Mint& b) { return a.v <= b.v; }     friend bool operator>=(const Mint& a, const Mint& b) { return a.v >= b.v; }     friend istream& operator>>(istream& in, Mint& a) {       long long x;       cin >> x;       a = Mint(x);       return in;     }     friend ostream& operator<<(ostream& os, const Mint& a) { return os << a.v; }     Mint& operator+=(const Mint& m) {       if ((v += m.v) >= MOD) v -= MOD;       return *this;     }     Mint& operator-=(const Mint& m) {       if ((v -= m.v) < 0) v += MOD;       return *this;     }     Mint& operator*=(const Mint& m) {       v = (long long)v * m.v % MOD;       return *this;     }     Mint& operator/=(const Mint& m) { return (*this) *= inv(m); }     friend Mint pow(Mint a, long long p) {       Mint ans = 1;       assert(p >= 0);       for (; p; p /= 2, a *= a)         if (p & 1) ans *= a;       return ans;     }     friend Mint inv(const Mint& a) {       assert(a.v != 0);       return pow(a, MOD - 2);     }     Mint operator-() const { return Mint(-v); }     Mint& operator++() { return *this += 1; }     Mint& operator--() { return *this -= 1; }     friend Mint operator+(Mint a, const Mint& b) { return a += b; }     friend Mint operator-(Mint a, const Mint& b) { return a -= b; }     friend Mint operator*(Mint a, const Mint& b) { return a *= b; }     friend Mint operator/(Mint a, const Mint& b) { return a /= b; }   };   namespace FFT {   template <class T>   void fft(vector<T>& A, bool inv = 0) {     int n = (int)A.size();     assert((T::mod - 1) % n == 0);     vector<T> B(n);     for (int b = n / 2; b; b /= 2, A.swap(B)) {       T w = pow(T::rt(), (T::mod - 1) / n * b);       T m = 1;       for (int i = 0; i < n; i += b * 2, m *= w)         for (int j = 0; j < b; j++) {           T u = A[i + j];           T v = A[i + j + b] * m;           B[i / 2 + j] = u + v;           B[i / 2 + j + n / 2] = u - v;         }     }     if (inv) {       reverse(1 + A.begin(), A.end());       T z = T(1) / T(n);       for (auto& t : A) t *= z;     }   }   template <class T>   vector<T> multiply(vector<T> A, vector<T> B) {     int sa = (int)A.size();     int sb = (int)B.size();     if (!min(sa, sb)) return {};     int s = sa + sb - 1;     int n = 1;     for (; n < s; n *= 2)       ;     bool eq = A == B;     A.resize(n);     fft(A);     if (eq)       B = A;     else       B.resize(n), fft(B);     for (int i = 0; i < n; i++) A[i] *= B[i];     fft(A, 1);     A.resize(s);     return A;   }   template <class T>   vector<T> operator*(const vector<T>& a, const vector<T>& b) {     auto c = multiply(a, b);     return c;   }   template <class T>   vector<T> operator+(const vector<T>& a, const vector<T>& b) {     vector<T> c = a;     c.resize(max(a.size(), b.size()));     for (int i = 0; i < b.size(); ++i) {       c[i] += b[i];     }     return c;   }   template <class M, class T>   vector<M> multiply_mod(vector<T> x, vector<T> y) {     auto convert = [](const vector<T>& v) {       vector<M> w((int)v.size());       for (int i = 0; i < (int)v.size(); i++) w[i] = (int)v[i];       return w;     };     return multiply(convert(x), convert(y));   }   template <class T>   vector<T> general_multiply(const vector<T>& A, const vector<T>& B) {     using m0 = Mint<(119 << 23) + 1, 62>;     using m1 = Mint<(5 << 25) + 1, 62>;     using m2 = Mint<(7 << 26) + 1, 62>;     auto c0 = multiply_mod<m0>(A, B);     auto c1 = multiply_mod<m1>(A, B);     auto c2 = multiply_mod<m2>(A, B);     int n = (int)c0.size();     vector<T> res(n);     m1 r01 = 1 / m1(m0::mod);     m2 r02 = 1 / m2(m0::mod);     m2 r12 = 1 / m2(m1::mod);     for (int i = 0; i < n; i++) {       int a = c0[i].v;       int b = ((c1[i] - a) * r01).v;       int c = (((c2[i] - a) * r02 - b) * r12).v;       res[i] = (T(c) * m1::mod + b) * m0::mod + a;     }     return res;   }   }  // namespace FFT   using namespace FFT;   using mi = Mint<998244353, 5>;   int main() {     ios::sync_with_stdio(false);     cin.tie(nullptr);     auto fail = []() {       cout << 0 <<   n ;       exit(0);     };     int n;     cin >> n;     vector<int> a(n);     for (int i = 0; i < n; ++i) {       cin >> a[i];     }     vector<int> blocks;     while (!a.empty()) {       int x = a.back();       if (a.size() < x) {         fail();       }       blocks.push_back(x == 1);       for (int i = 0; i < x; ++i) {         if (a.back() != x) {           fail();         }         a.pop_back();       }     }     reverse(blocks.begin(), blocks.end());     int sz = blocks.size();     const mi HALF = 1 / mi(2);     function<vector<vector<mi>>(int, int)> solve = [&](int l, int r) {       vector<vector<mi>> res(4);       if (r - l + 1 == 1) {         res[0] = vector<mi>{1};         res[1] = vector<mi>{0, 2};         res[2] = vector<mi>{1};         if (blocks[l]) {           res[3] = vector<mi>{0, 1};         } else {           res[3] = vector<mi>{0, 2};         }         return res;       }       int m = (l + r) >> 1;       auto x = solve(l, m);       auto y = solve(m + 1, r);       res[0] = x[0] * y[0] + x[1] * y[2];       res[1] = x[0] * y[1] + x[1] * y[3];       res[2] = x[2] * y[0] + x[3] * y[2];       res[3] = x[3] * y[3] + x[2] * y[1];       return res;     };     auto res = solve(0, sz - 1)[3];     vector<mi> fact(n + 1);     fact[0] = 1;     for (int i = 1; i <= n; ++i) {       fact[i] = fact[i - 1] * i;     }     mi ans = 0;     for (int i = 1; i < res.size(); ++i) {       ans += res[i] * fact[i] * (i % 2 == res.size() % 2 ? -1 : 1);     }     cout << ans <<   n ;     return 0;   }