#include #define rep(i,s,n) for (int i = (int)(s); i < (int)(n); i++) #define reb(i,s,n) for (int i = (int)(n)-1; i >= (int)(s); i--) #define all(v) begin(v), end(v) using namespace std; using ll = long long; bool chmin(auto &a, auto b) { return a > b ? a = b, 1 : 0; } bool chmax(auto &a, auto b) { return a < b ? a = b, 1 : 0; } template ostream &operator<<(ostream &os, const vector &a){ if (a.empty()) return os; os << a.front(); for (auto e : a | views::drop(1)){ os << ' ' << e; } return os; } void dump(auto ...vs){ ((cout << vs << ' '), ...) << endl; } #include using mint = atcoder::modint998244353; void solve(){ int n; cin >> n; vector a(n); rep(i,0,n) cin >> a[i]; vector ord; ord.reserve(n); vector> pars(n); { vector prv(n), nxt(n); rep(i,0,n){ prv[i] = i-1; nxt[i] = i+1; } queue que; rep(i,0,n){ if (a[i] == 0){ que.emplace(i); } } while (!que.empty()){ int v = que.front(); que.pop(); ord.emplace_back(v); int pv = prv[v], nv = nxt[v]; pars[v] = {pv,nv}; if (pv != -1){ if (a[pv] == 0){ break; } if (--a[pv] == 0){ que.emplace(pv); } nxt[pv] = nv; } if (nv != -1){ if (a[nv] == 0){ break; } if (--a[nv] == 0){ que.emplace(nv); } prv[nv] = pv; } } if (ssize(ord) != n){ cout << 0 << '\n'; return ; } } vector inv(n); rep(i,0,n){ inv[ord[i]] = i; } mint ans = 1, div = 1; vector sub(n,1); int root = ord.back(); for (int v : ord){ ans *= v+1; div *= sub[v]; if (v == root) break; auto [l, r] = pars[v]; if (l == -1){ assert(r != n); sub[r] += sub[v]; } else if (r == n){ assert(l != -1); sub[l] += sub[v]; } else { int p = (inv[l] < inv[r] ? l : r); sub[p] += sub[v]; } } dump(sub); dump(ord); ans /= div; cout << ans.val() << '\n'; } int main(){ cin.tie(0)->sync_with_stdio(0); solve(); }