#include <bits/stdc++.h>
using namespace std;
template <class S, class T>
pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first + t.first, s.second + t.second);
}
template <class S, class T>
pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first - t.first, s.second - t.second);
}
template <class S, class T>
ostream &operator<<(ostream &os, pair<S, T> p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const long long inf = 1000000001;
const long long INF = 1e18;
const long long MOD = 998244353;
const double pi = 3.14159265358979323846;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx2[8] = {1, 1, 0, -1, -1, -1, 0, 1}, dy2[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int MAXN = 300010;
vector<long long> fact(MAXN);
void set_fact(long long n, long long M = MOD) {
  fact[0] = fact[1] = 1;
  for (long long i = 2; i <= n; i++) {
    fact[i] = i * fact[i - 1] % M;
  }
}
class UnionFind {
 public:
  int n;
  vector<int> par;
  vector<int> ran;
  vector<int> num;
  UnionFind(int _n) {
    n = _n;
    par.resize(n);
    ran.resize(n);
    num.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      ran[i] = 0;
      num[i] = 1;
    }
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    int numsum = num[x] + num[y];
    if (x == y) {
      return;
    }
    if (ran[x] < ran[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (ran[x] == ran[y]) {
        ran[x]++;
      }
    }
    num[x] = num[y] = numsum;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
int main() {
  int n;
  cin >> n;
  vector<int> a(n);
  long long t = 0;
  for (int i = 0; i < (n); i++) {
    cin >> a[i];
    a[i]--;
    if (a[i] == 0) {
      t++;
    }
  }
  if (t == n) {
    cout << fact[n] << endl;
    return 0;
  }
  vector<int> b;
  int f = a[0];
  int i = 0;
  while (a[i] == f) {
    i++;
  }
  for (int j = i; j < n; j++) {
    b.push_back(a[j]);
  }
  for (int j = 0; j < i; j++) {
    b.push_back(a[j]);
  }
  vector<int> start(n, -1);
  int pre = -1;
  i = 0;
  while (i < n) {
    if (b[i] != pre) {
      if (start[b[i]] != -1) {
        cout << 0 << endl;
        return 0;
      } else {
        start[b[i]] = i;
        pre = b[i];
      }
    }
    i++;
  }
  UnionFind uf(n);
  pre = -1;
  i = 0;
  for (int j = 0; j < (n); j++) {
    if (start[j] != -1) {
      continue;
    }
    while (b[i] != pre) {
      pre = b[i];
      i++;
    }
    uf.unite(b[i], j);
    i++;
  }
  long long ans = 1;
  long long kouho = 0;
  for (int i = 0; i < (n); i++) {
    if (start[i] == -1) {
      ans *= (kouho - i);
      ans %= MOD;
      continue;
    }
    int s = start[i];
    long long cnt = 0;
    while (s < n && b[s] == i) {
      cnt++;
      s++;
    }
    if (cnt > t) {
      cout << 0 << endl;
      return 0;
    }
    if (b[(start[i] - 1 + n) % n] > i && b[s % n] > i) {
      if (cnt != t) {
        cout << 0 << endl;
        return 0;
      }
      kouho += uf.num[i] - (t - 1);
    } else if (b[(start[i] - 1 + n) % n] > i && b[s % n] < i) {
      kouho += cnt;
      uf.unite(i, b[s % n]);
    } else if (b[(start[i] - 1 + n) % n] < i && b[s % n] > i) {
      kouho += cnt;
      uf.unite(i, b[(start[i] - 1 + n) % n]);
    } else if (b[(start[i] - 1 + n) % n] < i && b[s % n] < i) {
      int sz1 = uf.num[b[s % n]], sz2 = b[(start[i] - 1 + n) % n];
      ans *= t - (cnt - 1);
      ans %= MOD;
      kouho -= sz1 - (t - 1);
      kouho -= sz2 - (t - 1);
      int sz = sz1 + sz2 + cnt;
      kouho += sz - (t - 1);
      uf.unite(i, b[s % n]);
      uf.unite(i, b[(start[i] - 1 + n) % n]);
    }
  }
  while (ans < 0) {
    ans += MOD;
  }
  cout << ans << endl;
}
