Problem:
Score : 900 points

Problem Statement

You are given a sequence of N integers: A_1,A_2,...,A_N.

Find the number of permutations p_1,p_2,...,p_N of 1,2,...,N that can be changed to A_1,A_2,...,A_N by performing the following operation some number of times (possibly zero), modulo 998244353:

For each 1\leq i\leq N, let q_i=min(p_{i-1},p_{i}), where p_0=p_N. Replace the sequence p with the sequence q.

Constraints

1 \leq N \leq 3 × 10^5

1 \leq A_i \leq N

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1
:
A_N

Output

Print the number of the sequences that satisfy the condition, modulo 998244353.

Sample Input 1

3
1
2
1

Sample Output 1

2

(2,3,1) and (3,2,1) satisfy the condition.

Sample Input 2

5
3
1
4
1
5

Sample Output 2

0

Sample Input 3

8
4
4
4
1
1
1
2
2

Sample Output 3

24

Sample Input 4

6
1
1
6
2
2
2

Sample Output 4

0

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
	ost<<"{"<<p.first<<","<<p.second<<"}";
	return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
	ost<<"{";
	for(int i=0;i<v.size();i++){
		if(i)ost<<",";
		ost<<v[i];
	}
	ost<<"}";
	return ost;
}


template<uint32_t mod>
struct ModInt{
	uint32_t a;
	ModInt& s(uint32_t vv){
		a=vv<mod?vv:vv-mod;
		return *this;
	}

    ModInt(int64_t x=0){s(x%mod+mod);}

	ModInt& operator+=(const ModInt &x){return s(a+x.a);}
	ModInt& operator-=(const ModInt &x){return s(a+mod-x.a);}
	ModInt& operator*=(const ModInt &x){
		a=uint64_t(a)*x.a%mod;
		return *this;
	}
	ModInt& operator/=(const ModInt &x){
		*this*=x.inv();
		return *this;
	}

	ModInt operator+(const ModInt &x)const{return ModInt(*this)+=x;}
	ModInt operator-(const ModInt &x)const{return ModInt(*this)-=x;}
	ModInt operator*(const ModInt &x)const{return ModInt(*this)*=x;}
	ModInt operator/(const ModInt &x)const{return ModInt(*this)/=x;}
	bool operator==(const ModInt &x)const{return a==x.a;}
	bool operator!=(const ModInt &x)const{return a!=x.a;}
	bool operator<(const ModInt &x)const{return a<x.a;}

	ModInt operator-()const{return ModInt()-*this;}
	ModInt pow(int64_t n)const{
		ModInt res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}

    ModInt inv()const{return pow(mod-2);}
};

template<uint32_t mod>
istream& operator>>(istream& in,const ModInt<mod>& a){
	return (in>>a.a);
}
template<uint32_t mod>
ostream& operator<<(ostream& out,const ModInt<mod>& a){
	return (out<<a.a);
}
using mint=ModInt<998244353>;

template<class T>
struct BinaryIndexedTree{
	int n;
	vector<T>dat;
	BinaryIndexedTree(int n=0):n(n){
		dat.resize(n+1);
	}
	void add(int k,T x){
		for(k++;k<=n;k+=k&-k)dat[k]+=x;
	}
	T sum(int k){
		T ret=0;
		for(k++;k;k-=k&-k)ret+=dat[k];
		return ret;
	}
};


int N;
int A[666666];

signed main(){
    cin>>N;
    rep(i,N)cin>>A[i];
    
    rep(i,N){
        if(A[i]==1&&A[i]!=A[(i+N-1)%N]){
            rotate(A,A+i,A+N);
            break;
        }
    }
    
    for(int i=0;i<N;i++)A[i+N]=A[i];
    
    if(A[0]!=1){
        cout<<0<<endl;
        return 0;
    }
    
    int K=0;
    while(K<N&&A[K]==1)K++;
    
    if(K==N){
        mint ans=1;
        rep(i,N)ans*=i+1;
        cout<<ans<<endl;
        return 0;
    }
    
    
    
    vector<pint>lis(N+1,pint(-1,-1));
    
    int cur=0;
    while(cur<N){
        int nex=cur;
        while(nex<N&&A[cur]==A[nex])nex++;
        if(lis[A[cur]].fi!=-1){
            cout<<0<<endl;
            return 0;
        }
        if(nex-cur>K){
            cout<<0<<endl;
            return 0;
        }
        lis[A[cur]]=pint(cur,nex);
        
        cur=nex;
    }
    
    deque<pint>deq;
    
    vector<vint>add(N+114);
    for(int i=0;i<N+K-1;i++){
        while(deq.size()&&deq.back().fi<=A[i])deq.pop_back();
        if(deq.size()&&deq.front().se+K<=i)deq.pop_front();
        deq.eb(A[i],i);
        if(i-K+1>=0){
            add[deq.front().fi+1].pb(i-K+1);
        }
    }
    
    set<int>used;
    set<int>cand;
    mint ans=1;
    
    vint arr(2*N);
    for(int i=1;i<=N;i++){
        for(auto a:add[i])if(used.find(a)==used.end())cand.insert(a);
        if(lis[i].fi==-1){
            if(cand.size()==0){
                cout<<0<<endl;
                return 0;
            }
            ans*=cand.size();
            arr[*cand.begin()]=i;
            cand.erase(*cand.begin());
            continue;
        }
        
        
        int l,r;
        tie(l,r)=lis[i];
        if(A[r%N]>i){
            if(used.find(r-K)!=used.end()){
                cout<<0<<endl;
                return 0;
            }
            used.insert(r-K);
            arr[r-K]=i;
            continue;
        }
        if(A[(l-1+N)%N]>i){
            if(used.find(l)!=used.end()){
                cout<<0<<endl;
                return 0;
            }
            arr[l]=i;
            used.insert(l);
            continue;
        }
        int al=r-K;
        int ar=l+1;
        if(used.lower_bound(al)!=used.lower_bound(ar)){
            cout<<0<<endl;
            return 0;
        }
        ans*=ar-al;
        arr[l]=i;
        used.insert(l);
    }
    
    
    for(int i=0;i<N;i++)arr[i+N]=arr[i];
    deq=deque<pint>();
    for(int i=0;i<2*N;i++){
        while(deq.size()&&deq.back().fi>=arr[i])deq.pop_back();
        if(deq.size()&&deq.front().se+K<=i)deq.pop_front();
        deq.eb(arr[i],i);
        if(A[i]!=deq.front().fi){
            cout<<0<<endl;
            return 0;
        }
    }
    
    cout<<ans<<endl;
}