Problem:
D： 素因数分解の多様性 (The Diversity of Prime Factorization)
Problem
Ebi-chan has the FACTORIZATION MACHINE, which can factorize natural numbers M (greater than 1) in
O(
$\log$
M)
time!  But unfortunately, the machine could display only digits and whitespaces.
In general, we consider the factorization of
M
as
p_1^{e_1} \times p_2^{e_2} \times ... \times p_K^{e_K}
where (1)
i < j
implies
p_i < p_j
and (2)
p_i
is prime.  Now, she gives M to the machine, and the machine displays according to the following rules in ascending order with respect to
i
:
If
e_i = 1
, then displays
p_i
,
otherwise, displays
p_i
e_i
.
For example, if she gives either
22
or
2048
, then
2 11
is displayed.  If either
24
or
54
, then
2 3 3
.
Okay, Ebi-chan has written down the output of the machine, but she notices that she has forgotten to write down the input!  Now, your task is to count how many natural numbers result in a noted output.  Note that Ebi-chan has mistaken writing and no input could result in the output.
The answer could be too large, so, you must output it modulo
10^9+7
(prime number).
Input
N
q_1
q_2
$\cdots$
q_N
In the first line, the number of the output of the machine is given.  In the second line, the output of the machine is given.
Constraints
1 \leq N \leq 10^5
2 \leq q_i \leq 10^6
(
1 \leq i \leq N
)
Output
Print the number of the natural numbers that result in the given output of the machine.
Sample Input 1
3
2 3 3
Sample Output for Input 1
2
24 = 2^3 \times 3
and
54 = 2 \times 3^3
satisfy the condition.
Sample Input 2
3
2 3 4
Sample Output 2 for Input 2
1
Only
162 = 2 \times 3^4
satisfies the condition.  Note that
4
is not prime.
Sample Input 3
3
3 5 2
Sample Output for Input 3
1
Since
2 < 3 < 5
, only
75 = 3 \times 5^2
satisfies the condition.
Sample Input 4
1
4
Sample Output for Input 4
0
Ebi-chan should have written down it more carefully.

Submitted solutions:

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

#define int long long

int pr[1000100];

const int mod = 1e9 + 7;

int32_t main() {
    fill(pr, pr + 1000100, 1);

    for(int i = 2; i <= 1000000; i++) {
        if(!pr[i]) continue;
        for(int j = i * 2; j <= 1000000; j += i)
            pr[j] = 0;
    }

    int n;
    cin >> n;
    vector <int> v(n + 10);
    for(int i = 1; i <= n; i++)
        cin >> v[i];
    vector <vector <int> > dp(n + 10, vector <int> (2));
    dp[0][0] = 1;

    for(int i = 1; i <= n; i++) {
        if(pr[v[i]]) {
            if(pr[v[i - 1]] && v[i - 1] < v[i]) {
                (dp[i][0] += dp[i - 1][0]) %= mod;
                (dp[i + 1][1] += dp[i - 1][0]) %= mod;
            }
            if(i - 2 >= 0 && pr[v[i - 2]] && v[i - 2] < v[i]) {
                (dp[i][0] += dp[i - 1][1]) %= mod;
                (dp[i + 1][1] += dp[i - 1][1]) %= mod;
            }
        }
    }

    int ans = dp[n][0] + dp[n][1];
    ans %= mod;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16868
final_rank: 12

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

#define int long long

int pr[1000100];

const int mod = 1e9 + 7;

int32_t main() {
    fill(pr, pr + 1000100, 1);

    for(int i = 2; i <= 1000000; i++) {
        if(!pr[i]) continue;
        for(int j = i * 2; j <= 1000000; j += i)
            pr[j] = 0;
    }

    int n;
    cin >> n;
    vector <int> v(n + 10);
    for(int i = 1; i <= n; i++)
        cin >> v[i];
    vector <vector <int>> dp(n + 10, vector <int> (2));
    dp[0][0] = 1;

    for(int i = 1; i <= n; i++) {
        if(pr[v[i]]) {
            if(v[i - 1] < v[i]) {
                (dp[i][0] += dp[i - 1][0]) %= mod;
                (dp[i + 1][1] += dp[i - 1][0]) %= mod;
            }
            if(i - 2 >= 0 && v[i - 2] < v[i]) {
                (dp[i][0] += dp[i - 1][1]) %= mod;
                (dp[i + 1][1] += dp[i - 1][1]) %= mod;
            }
        }
    }

    int ans = dp[n][0] + dp[n][1];
    ans %= mod;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 17232
final_rank: 11

code_snippet: //yukicoder@cpp17

#include <iostream>
#include <iomanip>

#include <algorithm>

#include <cmath>
#include <cctype>
#include <climits>
#include <cassert>

#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <map>

#include <random>

#include <bitset>

#include <complex>

#include <utility>

#include <numeric>

#include <functional>


using namespace std;
using ll = long long;
using P = pair<ll,ll>;


const ll MOD = 998244353;
const ll MODx = 1000000007;
const int INF = (1<<30)-1;
const ll LINF = (1LL<<62LL)-1;
const double EPS = (1e-10);


P ar4[4] = {{0,1},{0,-1},{1,0},{-1,0}};
P ar8[8] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};


template <typename T> vector<T> make_vector(size_t a, T b) { return vector<T>(a, b); }
template <typename... Ts> auto make_vector(size_t a, Ts... ts) { return vector<decltype(make_vector(ts...))>(a, make_vector(ts...)); }
 
/*
確認ポイント
cout << fixed << setprecision(n) << 小数計算//n桁の小数表記になる

計算量は変わらないが楽できるシリーズ
min(max)_element(iter,iter)で一番小さい(大きい)値のポインタが帰ってくる
count(iter,iter,int)でintがiterからiterの間にいくつあったかを取得できる
*/

/* comment outed because can cause bugs
__attribute__((constructor))
void initial() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}
*/

struct SieveEratos{
  int N;
  vector<int> minp;
  vector<bool> t;
  vector<int> primes;
  map<int,int> invprimes;
  SieveEratos(){}
  SieveEratos(int n):N(n+1){
    generate();
  }
  void set(int n){
    N = n+1;
    generate();
  }
  void generate(){
    t.assign(N, true);
    t[0] = t[1] = false;
    for(int i = 2; N > i; i++){
      if(t[i]){
        primes.emplace_back(i);
        for(int j = i+i; N > j; j+=i){
          t[j] = false;
        }
      }
    } 
  }
  void generate_invprime(){
    for(size_t i = 0; primes.size() > i; i++){
      invprimes[primes[i]] = i+1;
    }

  }
  void generate_minfactor(){
    minp.assign(N, N+2);
    minp[0] = minp[1] = -1;
    for(int i = 2; N > i; i++){
      if(minp[i] == N+2){
        minp[i] = i;
        for(int j = i+i; N > j; j+=i){
          minp[j] = min(i, minp[j]);
        }
      }
    }
  }
  bool operator[](int x){return t[x];}
};

long long dp[100010][2];

int main(){
  int n;cin>>n;
  vector<long long> A(n);
  SieveEratos P(1000001);
  for(int i = 0; n > i; i++){
    cin>>A[i];
  }
  dp[0][0] = P[A[0]];
  for(int i = 0; n > i; i++){
    if(P[A[i]]){
      if(i >= 2 && A[i-2] < A[i]){
        dp[i][0] = (dp[i][0]+dp[i-2][0])%MODx;
      }
      if(i >= 1 && A[i-1] < A[i]){
        dp[i][0] = (dp[i][0]+dp[i-1][0])%MODx;
      }
    }
    if(i >= 1){
      dp[i][1] = dp[i-1][0];
    }
  }
  cout << (dp[n-1][0]+dp[n-1][1])%MODx << endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6104
final_rank: 6

code_snippet: //yukicoder@cpp17

#include <iostream>
#include <iomanip>

#include <algorithm>

#include <cmath>
#include <cctype>
#include <climits>
#include <cassert>

#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <map>

#include <random>

#include <bitset>

#include <complex>

#include <utility>

#include <numeric>

#include <functional>


using namespace std;
using ll = long long;
using P = pair<ll,ll>;


const ll MOD = 998244353;
const ll MODx = 1000000007;
const int INF = (1<<30)-1;
const ll LINF = (1LL<<62LL)-1;
const double EPS = (1e-10);


P ar4[4] = {{0,1},{0,-1},{1,0},{-1,0}};
P ar8[8] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};


template <typename T> vector<T> make_vector(size_t a, T b) { return vector<T>(a, b); }
template <typename... Ts> auto make_vector(size_t a, Ts... ts) { return vector<decltype(make_vector(ts...))>(a, make_vector(ts...)); }
 
/*
確認ポイント
cout << fixed << setprecision(n) << 小数計算//n桁の小数表記になる

計算量は変わらないが楽できるシリーズ
min(max)_element(iter,iter)で一番小さい(大きい)値のポインタが帰ってくる
count(iter,iter,int)でintがiterからiterの間にいくつあったかを取得できる
*/

/* comment outed because can cause bugs
__attribute__((constructor))
void initial() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}
*/

struct SieveEratos{
  int N;
  vector<int> minp;
  vector<bool> t;
  vector<int> primes;
  map<int,int> invprimes;
  SieveEratos(){}
  SieveEratos(int n):N(n+1){
    generate();
  }
  void set(int n){
    N = n+1;
    generate();
  }
  void generate(){
    t.assign(N, true);
    t[0] = t[1] = false;
    for(int i = 2; N > i; i++){
      if(t[i]){
        primes.emplace_back(i);
        for(int j = i+i; N > j; j+=i){
          t[j] = false;
        }
      }
    } 
  }
  void generate_invprime(){
    for(size_t i = 0; primes.size() > i; i++){
      invprimes[primes[i]] = i+1;
    }

  }
  void generate_minfactor(){
    minp.assign(N, N+2);
    minp[0] = minp[1] = -1;
    for(int i = 2; N > i; i++){
      if(minp[i] == N+2){
        minp[i] = i;
        for(int j = i+i; N > j; j+=i){
          minp[j] = min(i, minp[j]);
        }
      }
    }
  }
  bool operator[](int x){return t[x];}
};

long long dp[100010][2];

int main(){
  int n;cin>>n;
  vector<long long> A(n);
  SieveEratos P(1000001);
  for(int i = 0; n > i; i++){
    cin>>A[i];
  }
  dp[0][0] = P[A[0]];
  for(int i = 0; n > i; i++){
    if(P[A[i]]){
      if(i >= 1 && A[i-2] < A[i]){
        dp[i][0] = (dp[i][0]+dp[i-2][0])%MODx;
      }
      if(i >= 1 && A[i-1] < A[i]){
        dp[i][0] = (dp[i][0]+dp[i-1][0])%MODx;
      }
    }
    if(i >= 1){
      dp[i][1] = dp[i-1][0];
    }
  }
  cout << (dp[n-1][0]+dp[n-1][1])%MODx << endl;
  return 0;
}
accuracy: 0.15555555555555556
time_ms: 20
memory_kb: 5780
final_rank: 15

code_snippet: #include <bits/stdc++.h>

constexpr long long mod{1000000007};

int main() {
    std::vector<bool> P(1000001, true);
    P[0] = P[1] = false;
    for (long long i{2} ; i * i <= (long long)P.size() ; i++) {
        if (!P[i]) continue;
        for (long long j{i * i} ; j <= (long long)P.size() ; j += i) {
            P[j] = false;
        }
    }
    int N;
    std::cin >> N;
    std::vector<int> Q(N);
    for (auto& q : Q) std::cin >> q;
    std::vector<long long> dp(N + 1);
    dp[N] = 1;
    for (int i{N - 1} ; i >= 0 ; i--) {
        if (!P[Q[i]]) continue;
        if (i + 1 == N or (P[Q[i + 1]] and Q[i] < Q[i + 1])) {
            dp[i] += dp[i + 1];
        }
        if (i + 2 <= N and (i + 2 == N or (P[Q[i + 2]] and Q[i] < Q[i + 2]))) {
            dp[i] += dp[i + 2];
        }
        dp[i] %= mod;
    }
    std::cout << dp[0] << '\n';
}
accuracy: 1
time_ms: 20
memory_kb: 4348
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
using namespace std;

const long long MOD = 1000000007;

vector<bool> prime(1000001, true);

void sieve(){
    prime[0] = prime[1] = false;
    for(int i = 2; 1000000 >= i; i++){
        if(prime[i]){
            for(int j = i+i; 1000000 >= j; j+=i){
                prime[j] = false;
            }
        }
    }
}

long long dp[1000010][2];

int main(){
    sieve();
    int n;cin>>n;
    vector<int> A(n);
    for(int i = 0; n > i; i++){
        cin>>A[i];     
    }
    if(!prime[A[0]]){
        cout << 0 << endl;
        return 0;
    }
    dp[0][0] = 1;
    for(int i = 1; n > i; i++){
        if(!prime[A[i]]){
            dp[i][1] = dp[i-1][0];
        }else{

            if(A[i-1] < A[i]){
                dp[i][0] = (dp[i][0]+dp[i-1][0])%MOD;
            }
            if(A[i-2] < A[i]){
                dp[i][0] = (dp[i][0]+dp[i-2][0])%MOD;
            }
            dp[i][1] = dp[i-1][0];
        }
    }
    cout << (dp[n-1][0]+dp[n-1][1])%MOD << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 4944
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

vector<bool> primes(int N){
    vector<bool> res(N + 1, 1);
    res[0] = res[1] = 0;
    for(int i = 2; i <= N; i++){
        if(res[i] != 1) continue;
        for(int j = i + i; j <= N; j += i){
            res[j] = 0;
        }
    }
    return res;
}

using ll = long long;
int main(){
    int N; cin >> N;
    vector<int> Q(N);
    for(int i = 0; i < N; i++) cin >> Q[i];

    auto isp = primes(1000010);
    const int MOD = (int)1e9+7;
    vector<ll> dp(N + 1, 0);
    vector<bool> used(N + 1);
    
    auto rec = [&](auto f, int n) -> ll {
        if(used[n]) return dp[n];
        if(!isp[Q[n]]) return 0;

        ll res = 0;
        // 1
        if(n + 1 == N)if(isp[Q[n]]){
            res = (res + f(f, n + 1)) % MOD;
        }
        if(n + 1 < N)if(isp[Q[n]] && isp[Q[n + 1]] && Q[n] < Q[n + 1]){
            res = (res + f(f, n + 1)) % MOD;
        }
        // 2
        if(n + 2 == N)if(isp[Q[n]]){
            res = (res + f(f, n + 2)) % MOD;
        }
        if(n + 2 < N)if(isp[Q[n]] && isp[Q[n + 2]] && Q[n] < Q[n + 2]){
            res = (res + f(f, n + 2)) % MOD;
        }

        used[n] = 1;
        return dp[n] = res;
    };
    
    used[N] = 1;
    dp[N] = 1;
    for(int i = N - 1; i >= 0; i--){
        rec(rec, i);
    }

    cout << dp[0] << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 4408
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=1e9+7;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}


//a以下の素数を列挙、計算量:Nlog(log(N))
vector<long long> Eratosthenes(long long a){
    if(a<2) return {};
    vector<long long> p(a+1),ans;
    p[0]=1,p[1]=1;
    long long k=2;
    while(k*k<=a){
        if(p[k]==0){
            ans.push_back(k);
            for(long long i=2;i*k<=a;i++){
                p[i*k]=1;
            }
        }
        k++;
    }
    while(k<=a){
        if(p[k]==0) ans.push_back(k);
        k++;
    }
    return p;
}

ll jyo(ll x,ll y,ll z){
  ll H=y; //ここから
       ll a=1,b=(x%z+z)%z,c=1;
       while(H>0){
         a*=2;
         if(H%a!=0){
           H-=a/2;
           c*=b;
           c%=z;
         }
        b*=b;
         b%=z;
      } //ここまで
 return c;
}


void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int N;
	cin>>N;
	vector<ll> p(N+1);
	p[N]=INF;
	rep(i,N) cin>>p[i];
	auto E=Eratosthenes(1e6+10);
	vector<ll> A(N+2);
	A[0]=1;
	rep(i,N){
		if(E[p[i]]) continue;
		A[i]%=mod;
		if(p[i+1]>p[i]) A[i+1]+=(A[i])%mod;
		if(p[i+2]>p[i]) A[i+2]+=(A[i])%mod;
	}
	cout<<A[N]%mod<<"\n";
}
accuracy: 1
time_ms: 10
memory_kb: 12628
final_rank: 10

code_snippet: #line 1 "solve/main.cpp"
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

/* template start */

#line 2 "lib/utility/type_alias.hpp"

#line 4 "lib/utility/type_alias.hpp"

using u64 = std::uint64_t;
using u32 = std::uint32_t;
using u16 = std::uint16_t;
using u8 = std::uint8_t;

using i64 = std::int64_t;
using i32 = std::int32_t;
using i16 = std::int16_t;
using i8 = std::int8_t;

using usize = std::size_t;
using isize = std::ptrdiff_t;

constexpr i64 operator"" _i64(unsigned long long num) { return i64(num); }

constexpr u64 operator"" _u64(unsigned long long num) { return u64(num); }
#line 33 "solve/main.cpp"

#define rep(i, a, b) for (i64 i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...)                                                    \
  std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
      debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0) std::cerr << " :";
  debug_out(t...);
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}

template <typename Num, typename Func = std::multiplies<Num>>
constexpr Num mypow(Num a, u64 b, Num id = 1, Func mul = Func()) {
  if (b == 0) return id;
  Num x = id;
  while (b > 0) {
    if (b & 1) x = mul(x, a);
    a = mul(a, a);
    b >>= 1;
  }
  return x;
}

/* template end */

#line 2 "lib/utility/modint.hpp"

/*
  author:noshi91
  reference:https://noshi91.hatenablog.com/entry/2019/03/31/174006
            https://github.com/noshi91/Library/blob/master/other/modint.cpp

  1つめのmodintにoperator==,!=を追加したものです

  thx @noshi91!!
*/

#line 16 "lib/utility/modint.hpp"

template <u64 Modulus>
class modint {

 public:
  constexpr static u64 mod = Modulus;
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr bool operator==(const modint rhs) const noexcept {
    return a == rhs.a;
  }
  constexpr bool operator!=(const modint rhs) const noexcept {
    return !(*this == rhs);
  }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

template <u64 MOD>
std::ostream& operator<<(std::ostream& os, modint<MOD> a) {
  return os << a.value();
}
#line 91 "solve/main.cpp"

constexpr u64 MOD = 1000000007;
using mint=modint<MOD>;

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  i64 n;
  std::cin>>n;

  std::vector<i64> q(n);
  for(auto&& e:q)std::cin>>e;

  std::vector<bool> is_prime(n,true);

  rep(i,0,n){
    i64 num = q[i];
    for(int j=2;j*j<=num;j++){
      if(num%j==0){
        is_prime[i] = false;
        break;
      }
    }
  }

  if(!is_prime[0]){
    std::cout<<0<<"\n";
    return 0;
  }

  std::vector<mint> dp0(n,0),dp1(n,0);

  dp0[0] = 1;

  rep(i,1,n){
    if(is_prime[i]){
      if(is_prime[i-1] && q[i-1] < q[i]){
        dp0[i] += dp0[i-1];
      }

      if(i >= 2 && is_prime[i-2] && q[i-2] < q[i]){
        dp0[i] += dp1[i-1];
      }
    }

    dp1[i] = dp0[i-1];

  }

  debug(dp0);
  debug(dp1);

  std::cout<<(dp0[n-1] + dp1[n-1]).value()<<"\n";

  return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 5420
final_rank: 13

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};
struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
bool sieve[1010101];
modint dp[1010101];
int main() {  
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(12);

    memset(sieve, true, sizeof(sieve));
    int n; cin >> n;
    vector<int> p(n);
    REP(i,n) cin >> p[i];
    sieve[0] = sieve[1] = false;
    for(int i=2; i<1010101; i++) {
      if(sieve[i]) {
        for(int j=i*2; j<1010101; j+=i) {
          sieve[j] = false;
        }
      }
    }
    dp[0] = 1;
    for(int i=0; i<n; i++) {
      if(sieve[p[i]]) {
        if(i+1==n) dp[i+1] += dp[i];
        else{
          if(p[i] < p[i+1] && sieve[p[i+1]]) dp[i+1] += dp[i];
        }
        if(i+2==n) {
          dp[i+2] += dp[i];
        }else{
          if(p[i] < p[i+2] && sieve[p[i+2]]) dp[i+2] += dp[i];
        }
      }else continue;
    }
    cout << dp[n] << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8548
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using pll = pair<ll, ll>;
using uint = unsigned;
using pii = pair<int, int>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;

const int IINF = 0x1fffffff;
const ll LINF = 0x1fffffffffffffff;
const ll MINF = 0x7fffffffffff;
const ll MOD = 1000000007;
const ll MODD = 998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};

#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each1(i,a) for(auto&&i:a)
#define each2(x,y,a) for(auto&&[x,y]:a)
#define each3(x,y,z,a) for(auto&&[x,y,z]:a)
#define each(...) overload4(__VA_ARGS__,each3,each2,each1)(__VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
// #define sum(...) accumulate(all(__VA_ARGS__),0LL)
// #define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
// #define Msum(...) accumulate(all(__VA_ARGS__),0_M)
#define elif else if
#define unless(a) if(!(a))
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec vector
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }
vector<ll> iota(ll n, ll begin = 0){ vector<ll> a(n); iota(a.begin(), a.end(), begin); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T> a){ Uniq(a); unordered_map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
template<class T> map<T, ll> press_map(vector<T> a){ Uniq(a); map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class... T> void in(T&... a){ (void)initializer_list<int>{ (scan(a), 0)... }; }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull x){ return 63 - __builtin_clzll(x); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int First(bool i = true){ return out(i?"First":"Second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }

#define fi first
#define se second
#define rng(a) a.begin(), a.end()
#define chmax(x, y) (x = max(x, y))
#define chmin(x, y) (x = min(x, y))
#define removeerase(x) x.erase(remove(rng(x), 0), x.end());
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0)
    std::cout << " :";
  debug_out(t...);
}

constexpr uint mod = MOD;
struct Modint {
  uint num = 0;
  constexpr Modint() noexcept {}
  constexpr Modint(const Modint &x) noexcept : num(x.num) {}
  inline constexpr operator ll() const noexcept { return num; }
  inline constexpr Modint& operator+=(Modint x) noexcept {num += x.num; if (num >= mod) num -= mod; return *this; }
  inline constexpr Modint& operator-=(Modint x) noexcept { if (num < x.num) num += mod; num -= x.num; return *this; }
  inline constexpr Modint& operator*=(Modint x) noexcept { num = ull(num) * x.num % mod; return *this; }
  inline constexpr Modint& operator/=(Modint x) noexcept { return operator*=(x.inv()); }
  inline constexpr Modint& operator++() noexcept { if(num == mod - 1) num = 0; else num++; return *this; }
  inline constexpr Modint operator++(int) noexcept { Modint ans(*this); operator++(); return ans; }
  inline constexpr Modint& operator--() noexcept { if(num == 0) num = mod - 1; else num--; return *this; }
  inline constexpr Modint operator--(int) noexcept { Modint ans(*this); operator--(); return ans; }
  inline constexpr Modint operator-() const noexcept { return Modint(0) -= *this; }
  template<class T> constexpr Modint(T x) noexcept {
    using U = typename conditional<sizeof(T) >= 4, T, int>::type;
    U y = x; y %= U(mod); if(y < 0) y += mod; num = uint(y);
  }
  template<class T> inline constexpr Modint operator+(T x) const noexcept { return Modint(*this) += x; }
  template<class T> inline constexpr Modint& operator+=(T x) noexcept { return operator+=(Modint(x)); }
  template<class T> inline constexpr Modint operator-(T x) const noexcept { return Modint(*this) -= x; }
  template<class T> inline constexpr Modint& operator-=(T x) noexcept { return operator-=(Modint(x)); }
  template<class T> inline constexpr Modint operator*(T x) const noexcept { return Modint(*this) *= x; }
  template<class T> inline constexpr Modint& operator*=(T x) noexcept { return operator*=(Modint(x)); }
  template<class T> inline constexpr Modint operator/(T x) const noexcept { return Modint(*this) /= x; }
  template<class T> inline constexpr Modint& operator/=(T x) noexcept { return operator/=(Modint(x)); }
  inline constexpr Modint inv() const noexcept { ll x = 0, y = 0; extgcd(num, mod, x, y); return x; }
  static inline constexpr ll extgcd(ll a, ll b, ll &x, ll &y) noexcept { ll g = a; x = 1; y = 0; if(b){ g = extgcd(b, a % b, y, x); y -= a / b * x; } return g; }
  inline constexpr Modint pow(ull x) const noexcept { Modint ans = 1, cnt = *this; while(x){ if(x & 1) ans *= cnt; cnt *= cnt; x /= 2; } return ans; }
};
std::istream& operator>>(std::istream& is, Modint& x){ ll a; in(a); x = a; return is; }
inline constexpr Modint operator""_M(ull x) noexcept { return Modint(x); }
std::vector<Modint> fac(1, 1), inv(1, 1);
inline void reserve(ll a){
    if(fac.size() >= a) return;
    if(a < fac.size() * 2) a = fac.size() * 2;
    if(a >= mod) a = mod;
    while(fac.size() < a) fac.push_back(fac.back() * Modint(fac.size()));
    inv.resize(fac.size());
    inv.back() = fac.back().inv();
    for(ll i = inv.size() - 1; !inv[i - 1]; i--) inv[i - 1] = inv[i] * i;
}
inline Modint fact(ll n){ if(n < 0) return 0; reserve(n + 1); return fac[n]; }
inline Modint perm(ll n, ll r){
    if(r < 0 || n < r) return 0;
    if(n >> 24){ Modint ans = 1; for(ll i = 0; i < r; i++) ans *= n--; return ans; }
    reserve(n + 1); return fac[n] * inv[n - r];
}
inline Modint comb(ll n, ll r){ if(r < 0 || n < r) return 0; reserve(r + 1); return perm(n, r) * inv[r]; }
inline Modint Mcomb(ll n, ll r){ return comb(n + r - 1, n - 1); } // r balls into n boxes
inline Modint catalan(ll n){ reserve(n * 2 + 1); return fac[n * 2] * inv[n] * inv[n + 1]; }

const ll mx = 1 << 6;
struct Matrix{
    Modint a[mx][mx] = {};
    auto operator[](ll x){ return a[x]; }
    auto operator[](ll x) const { return a[x]; }
    static Matrix E(){
        Matrix a;
        for(ll i = 0; i < mx; i++) a[i][i] = 1;
        return a;
    }
    Matrix operator*(const Matrix& b) const {
        Matrix c;
        for(ll i = 0; i < mx; i++) for(ll j = 0; j < mx; j++) for(ll k = 0; k < mx; k++) c[i][k] += a[i][j] * b[j][k];
        return c;
    }
    void operator*=(const Matrix& b){
        *this = *this * b;
    }
    Matrix pow(ll b) const {
        Matrix a = *this, c = E();
        while(b){
            if(b & 1) c *= a;
            if(b >>= 1) a *= a;
        }
        return c;
    }
};

// vector<ll> facmod;
// vector<ll> facinvmod;
// ll combination(ll n, ll k, ll mod) {
//   // 階乗やその逆元をメモ化すると速い
//   // でかいやつはnCk/2^Nをパスカルの三角形で作る
//   ll res = fac(n, mod);
//   res = (res * invmod(fac(k, mod), mod)) % mod;
//   res = (res * invmod(fac(n - k, mod), mod)) % mod;
//   return res;
// }
// x % m[i] = r[i] % m[i] を満たす正で最小の x を返す
// i!=j に対して gcd(m[i], m[j])=1 であると仮定
// とりあえず解の存在判定は保留
// ll garner(vector<ll> r, vector<ll> m) {
//   int n = r.size();
//   ll m_prod = 1;      // m_prod には m[i] の積を入れていく
//   ll x = r[0] % m[0]; // 最初の条件を満たすような x の初期値
//   for (int i = 1; i < n; i++) {
//     // cout << r[i-1] << " " << m[i-1] << " " << x << endl;
//     m_prod *= m[i - 1]; // m の累積積を更新
//     ll t = ((r[i] - x) * invmod(m_prod, m[i])) % m[i];
//     if (t < 0)
//       t += m[i];
//     x += t * m_prod; // x を更新
//   }
//   return x;
// }
// false: composite, true: probably prime
// bool MillarRabin_sub(ll n, ll random) {
// 	ll d = n-1;
// 	while(d % 2 == 0) {
// // 		d /= 2;
// 		cout << random << " " << powmod(random, d, n) << endl;
// 		if (powmod(random, d, n) == n-1) {
// 			return true;
// 		}
// 	}
// 	if (powmod(random, d, n) == 1) return true;
// 	return false;
// }
// bool MillarRabin(ll n) {
// 	random_device rd{};
// 	vector<uint32_t> vec(20);
// 	generate(vec.begin(), vec.end(), ref(rd));
// 	mt19937 mt(seed_seq(vec.begin(), vec.end()));
// 	bool ret = true;
// 	rep(i,0,20) {
// 		vec[i] %= n; if (vec[i] == 0) continue;
// 		cout << MillarRabin_sub(n, random) << endl;
// 		if (!MillarRabin_sub(n, random)) return false;
// 	}
// 	return true;
// }

// 逆順になる reverse(rng(ans));
// vector<ll> G[100000];
// cout << fixed << setprecision(15) << y << endl;
// cout << bitset<20>(i) << endl;
// fill(distance[0], distance[row], INF);
// __builtin_popcount()
// stoi(S[j], 0, 2)
// for (ll i = 0;i < (ll)s.size() - k;i++)
// ll dp[桁数][未満フラグ][条件を満たしているか]
// stoi stoll
// bit全探索 n進数全探索
// while (t > 0) cc += t % 9, t /= 9;
// priority_queue<ll> que; que.push(3); que.top(); que.pop();
// rep(i,C)rep(j,C) if(i != j) rep(k,C) if(i != k && j != k)
// 始点終点をデータに含ませる
// memory restriction RE -> CE
// forr 逆順ループsnippet
// 座標 上下の回数さえ分かれば組合せ問題
// set 順序付き集合 distance(set.begin(), itr)でオフセットがわかる
// set s : for(int x : s) for(int y : s) for(int z : s)
// const int di[4] = {-1, 0, 1, 0};
// const int dj[4] = {0, -1, 0, 1};
// const string let = "ULDR";
// 逆順ソートsort(cand.rbegin(), cand.rend());
// int ok = 0, ng = 1e9+1;
// auto check = [&](int x) -> bool {
// 	set<int> s;
// 	rep(i,0,N) {
// 		int tmp = 0;
// 		rep(j,0,5) {
// 			if (A[i][j] >= x) tmp |= 1 << j;
// 		}
// 		s.insert(tmp);
// 	}
// 	for (int x : s) for (int y : s) for (int z : s) {
// 		if ((x | y | z) == 31) return true;
// 	}
// 	return false;
// };

// while(abs(ok - ng) > 1) {
// 	int mid = (ok + ng) / 2;
// 	if (check(mid)) ok = mid;
// 	else ng = mid;
// }
// cout << ok << endl;
// dp[500][500] はllではなくintにすること
// chmin/chmaxは型をあわせないといけない
// priority_queue 最上位以外アクセス許可していない
// priority_queue<l_l, vector<l_l>, greater<l_l>>
// multiset イテレータ書き込み出来ない

class FordFulkerson {
	struct edge {
		ll to, cap, rev;
	};
	ll n;
	vector<vector<edge>> G;
	vector<bool> used;

	ll dfs(ll s, ll t, ll f) {
		if (s == t) return f;
		used[s] = true;
		for (edge &e : G[s]) {
			if (!used[e.to] && e.cap > 0) {
				ll d = dfs(e.to, t, min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

public:
	FordFulkerson(ll n) : n(n), G(n), used(n) {}
	void add_edge(ll from, ll to, ll cap) {
		G[from].push_back({to, cap, ll(G[to].size())});
		G[to].push_back({from, 0, ll(G[from].size()) - 1});
	}

	ll max_flow(ll s, ll t) {
		ll flow = 0;
		while (true) {
			used.assign(n, 0);
			ll f = dfs(s, t, LINF);
			if (f == 0) return flow;
			flow += f;
		}
	}
};

ll n, q;
vec<ll> p, v;
vec<char> c;
pll dp[100000];
vec<ll> G[100000];

bool isPrime(ll x) {
	for (ll i = 2;i * i <= x;i++) {
		if (x % i == 0) return false;
	}
	return true;
}

int main() {
	ll N;
	cin >> N;
	ll q[N];
	rep(i,0,N) cin >> q[i];

	Modint dp[N+1][2] = {};
	bool pf[N];
	rep(i,0,N) pf[i] = isPrime(q[i]);
	if (!pf[0]) {
		cout << 0 << endl;
		return 0;
	}
	dp[0][0] = 1;
	rep(i,0,N-1) {
		if (pf[i] && pf[i+1] && q[i] < q[i+1]) {
			dp[i+1][0] += dp[i][0];
		}
		if (i > 0 && pf[i+1] && q[i-1] < q[i+1]) {
			dp[i+1][0] += dp[i][1];
		}
		if (pf[i]) {
			dp[i+1][1] += dp[i][0];
		}
	}
	// rep(i,0,N) cout << dp[i][0] << " ";
	// cout << endl;
	// rep(i,0,N) cout << dp[i][1] << " ";
	// cout << endl;
	cout << dp[N-1][0] + dp[N-1][1] << endl;
	return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 7380
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using pll = pair<ll, ll>;
using uint = unsigned;
using pii = pair<int, int>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;

const int IINF = 0x1fffffff;
const ll LINF = 0x1fffffffffffffff;
const ll MINF = 0x7fffffffffff;
const ll MOD = 1000000007;
const ll MODD = 998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};

#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each1(i,a) for(auto&&i:a)
#define each2(x,y,a) for(auto&&[x,y]:a)
#define each3(x,y,z,a) for(auto&&[x,y,z]:a)
#define each(...) overload4(__VA_ARGS__,each3,each2,each1)(__VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
// #define sum(...) accumulate(all(__VA_ARGS__),0LL)
// #define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
// #define Msum(...) accumulate(all(__VA_ARGS__),0_M)
#define elif else if
#define unless(a) if(!(a))
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec vector
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }
vector<ll> iota(ll n, ll begin = 0){ vector<ll> a(n); iota(a.begin(), a.end(), begin); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T> a){ Uniq(a); unordered_map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
template<class T> map<T, ll> press_map(vector<T> a){ Uniq(a); map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class... T> void in(T&... a){ (void)initializer_list<int>{ (scan(a), 0)... }; }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull x){ return 63 - __builtin_clzll(x); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int First(bool i = true){ return out(i?"First":"Second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }

#define fi first
#define se second
#define rng(a) a.begin(), a.end()
#define chmax(x, y) (x = max(x, y))
#define chmin(x, y) (x = min(x, y))
#define removeerase(x) x.erase(remove(rng(x), 0), x.end());
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0)
    std::cout << " :";
  debug_out(t...);
}

constexpr uint mod = MOD;
struct Modint {
  uint num = 0;
  constexpr Modint() noexcept {}
  constexpr Modint(const Modint &x) noexcept : num(x.num) {}
  inline constexpr operator ll() const noexcept { return num; }
  inline constexpr Modint& operator+=(Modint x) noexcept {num += x.num; if (num >= mod) num -= mod; return *this; }
  inline constexpr Modint& operator-=(Modint x) noexcept { if (num < x.num) num += mod; num -= x.num; return *this; }
  inline constexpr Modint& operator*=(Modint x) noexcept { num = ull(num) * x.num % mod; return *this; }
  inline constexpr Modint& operator/=(Modint x) noexcept { return operator*=(x.inv()); }
  inline constexpr Modint& operator++() noexcept { if(num == mod - 1) num = 0; else num++; return *this; }
  inline constexpr Modint operator++(int) noexcept { Modint ans(*this); operator++(); return ans; }
  inline constexpr Modint& operator--() noexcept { if(num == 0) num = mod - 1; else num--; return *this; }
  inline constexpr Modint operator--(int) noexcept { Modint ans(*this); operator--(); return ans; }
  inline constexpr Modint operator-() const noexcept { return Modint(0) -= *this; }
  template<class T> constexpr Modint(T x) noexcept {
    using U = typename conditional<sizeof(T) >= 4, T, int>::type;
    U y = x; y %= U(mod); if(y < 0) y += mod; num = uint(y);
  }
  template<class T> inline constexpr Modint operator+(T x) const noexcept { return Modint(*this) += x; }
  template<class T> inline constexpr Modint& operator+=(T x) noexcept { return operator+=(Modint(x)); }
  template<class T> inline constexpr Modint operator-(T x) const noexcept { return Modint(*this) -= x; }
  template<class T> inline constexpr Modint& operator-=(T x) noexcept { return operator-=(Modint(x)); }
  template<class T> inline constexpr Modint operator*(T x) const noexcept { return Modint(*this) *= x; }
  template<class T> inline constexpr Modint& operator*=(T x) noexcept { return operator*=(Modint(x)); }
  template<class T> inline constexpr Modint operator/(T x) const noexcept { return Modint(*this) /= x; }
  template<class T> inline constexpr Modint& operator/=(T x) noexcept { return operator/=(Modint(x)); }
  inline constexpr Modint inv() const noexcept { ll x = 0, y = 0; extgcd(num, mod, x, y); return x; }
  static inline constexpr ll extgcd(ll a, ll b, ll &x, ll &y) noexcept { ll g = a; x = 1; y = 0; if(b){ g = extgcd(b, a % b, y, x); y -= a / b * x; } return g; }
  inline constexpr Modint pow(ull x) const noexcept { Modint ans = 1, cnt = *this; while(x){ if(x & 1) ans *= cnt; cnt *= cnt; x /= 2; } return ans; }
};
std::istream& operator>>(std::istream& is, Modint& x){ ll a; in(a); x = a; return is; }
inline constexpr Modint operator""_M(ull x) noexcept { return Modint(x); }
std::vector<Modint> fac(1, 1), inv(1, 1);
inline void reserve(ll a){
    if(fac.size() >= a) return;
    if(a < fac.size() * 2) a = fac.size() * 2;
    if(a >= mod) a = mod;
    while(fac.size() < a) fac.push_back(fac.back() * Modint(fac.size()));
    inv.resize(fac.size());
    inv.back() = fac.back().inv();
    for(ll i = inv.size() - 1; !inv[i - 1]; i--) inv[i - 1] = inv[i] * i;
}
inline Modint fact(ll n){ if(n < 0) return 0; reserve(n + 1); return fac[n]; }
inline Modint perm(ll n, ll r){
    if(r < 0 || n < r) return 0;
    if(n >> 24){ Modint ans = 1; for(ll i = 0; i < r; i++) ans *= n--; return ans; }
    reserve(n + 1); return fac[n] * inv[n - r];
}
inline Modint comb(ll n, ll r){ if(r < 0 || n < r) return 0; reserve(r + 1); return perm(n, r) * inv[r]; }
inline Modint Mcomb(ll n, ll r){ return comb(n + r - 1, n - 1); } // r balls into n boxes
inline Modint catalan(ll n){ reserve(n * 2 + 1); return fac[n * 2] * inv[n] * inv[n + 1]; }

const ll mx = 1 << 6;
struct Matrix{
    Modint a[mx][mx] = {};
    auto operator[](ll x){ return a[x]; }
    auto operator[](ll x) const { return a[x]; }
    static Matrix E(){
        Matrix a;
        for(ll i = 0; i < mx; i++) a[i][i] = 1;
        return a;
    }
    Matrix operator*(const Matrix& b) const {
        Matrix c;
        for(ll i = 0; i < mx; i++) for(ll j = 0; j < mx; j++) for(ll k = 0; k < mx; k++) c[i][k] += a[i][j] * b[j][k];
        return c;
    }
    void operator*=(const Matrix& b){
        *this = *this * b;
    }
    Matrix pow(ll b) const {
        Matrix a = *this, c = E();
        while(b){
            if(b & 1) c *= a;
            if(b >>= 1) a *= a;
        }
        return c;
    }
};

// vector<ll> facmod;
// vector<ll> facinvmod;
// ll combination(ll n, ll k, ll mod) {
//   // 階乗やその逆元をメモ化すると速い
//   // でかいやつはnCk/2^Nをパスカルの三角形で作る
//   ll res = fac(n, mod);
//   res = (res * invmod(fac(k, mod), mod)) % mod;
//   res = (res * invmod(fac(n - k, mod), mod)) % mod;
//   return res;
// }
// x % m[i] = r[i] % m[i] を満たす正で最小の x を返す
// i!=j に対して gcd(m[i], m[j])=1 であると仮定
// とりあえず解の存在判定は保留
// ll garner(vector<ll> r, vector<ll> m) {
//   int n = r.size();
//   ll m_prod = 1;      // m_prod には m[i] の積を入れていく
//   ll x = r[0] % m[0]; // 最初の条件を満たすような x の初期値
//   for (int i = 1; i < n; i++) {
//     // cout << r[i-1] << " " << m[i-1] << " " << x << endl;
//     m_prod *= m[i - 1]; // m の累積積を更新
//     ll t = ((r[i] - x) * invmod(m_prod, m[i])) % m[i];
//     if (t < 0)
//       t += m[i];
//     x += t * m_prod; // x を更新
//   }
//   return x;
// }
// false: composite, true: probably prime
// bool MillarRabin_sub(ll n, ll random) {
// 	ll d = n-1;
// 	while(d % 2 == 0) {
// // 		d /= 2;
// 		cout << random << " " << powmod(random, d, n) << endl;
// 		if (powmod(random, d, n) == n-1) {
// 			return true;
// 		}
// 	}
// 	if (powmod(random, d, n) == 1) return true;
// 	return false;
// }
// bool MillarRabin(ll n) {
// 	random_device rd{};
// 	vector<uint32_t> vec(20);
// 	generate(vec.begin(), vec.end(), ref(rd));
// 	mt19937 mt(seed_seq(vec.begin(), vec.end()));
// 	bool ret = true;
// 	rep(i,0,20) {
// 		vec[i] %= n; if (vec[i] == 0) continue;
// 		cout << MillarRabin_sub(n, random) << endl;
// 		if (!MillarRabin_sub(n, random)) return false;
// 	}
// 	return true;
// }

// 逆順になる reverse(rng(ans));
// vector<ll> G[100000];
// cout << fixed << setprecision(15) << y << endl;
// cout << bitset<20>(i) << endl;
// fill(distance[0], distance[row], INF);
// __builtin_popcount()
// stoi(S[j], 0, 2)
// for (ll i = 0;i < (ll)s.size() - k;i++)
// ll dp[桁数][未満フラグ][条件を満たしているか]
// stoi stoll
// bit全探索 n進数全探索
// while (t > 0) cc += t % 9, t /= 9;
// priority_queue<ll> que; que.push(3); que.top(); que.pop();
// rep(i,C)rep(j,C) if(i != j) rep(k,C) if(i != k && j != k)
// 始点終点をデータに含ませる
// memory restriction RE -> CE
// forr 逆順ループsnippet
// 座標 上下の回数さえ分かれば組合せ問題
// set 順序付き集合 distance(set.begin(), itr)でオフセットがわかる
// set s : for(int x : s) for(int y : s) for(int z : s)
// const int di[4] = {-1, 0, 1, 0};
// const int dj[4] = {0, -1, 0, 1};
// const string let = "ULDR";
// 逆順ソートsort(cand.rbegin(), cand.rend());
// int ok = 0, ng = 1e9+1;
// auto check = [&](int x) -> bool {
// 	set<int> s;
// 	rep(i,0,N) {
// 		int tmp = 0;
// 		rep(j,0,5) {
// 			if (A[i][j] >= x) tmp |= 1 << j;
// 		}
// 		s.insert(tmp);
// 	}
// 	for (int x : s) for (int y : s) for (int z : s) {
// 		if ((x | y | z) == 31) return true;
// 	}
// 	return false;
// };

// while(abs(ok - ng) > 1) {
// 	int mid = (ok + ng) / 2;
// 	if (check(mid)) ok = mid;
// 	else ng = mid;
// }
// cout << ok << endl;
// dp[500][500] はllではなくintにすること
// chmin/chmaxは型をあわせないといけない
// priority_queue 最上位以外アクセス許可していない
// priority_queue<l_l, vector<l_l>, greater<l_l>>
// multiset イテレータ書き込み出来ない

class FordFulkerson {
	struct edge {
		ll to, cap, rev;
	};
	ll n;
	vector<vector<edge>> G;
	vector<bool> used;

	ll dfs(ll s, ll t, ll f) {
		if (s == t) return f;
		used[s] = true;
		for (edge &e : G[s]) {
			if (!used[e.to] && e.cap > 0) {
				ll d = dfs(e.to, t, min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

public:
	FordFulkerson(ll n) : n(n), G(n), used(n) {}
	void add_edge(ll from, ll to, ll cap) {
		G[from].push_back({to, cap, ll(G[to].size())});
		G[to].push_back({from, 0, ll(G[from].size()) - 1});
	}

	ll max_flow(ll s, ll t) {
		ll flow = 0;
		while (true) {
			used.assign(n, 0);
			ll f = dfs(s, t, LINF);
			if (f == 0) return flow;
			flow += f;
		}
	}
};

ll n, q;
vec<ll> p, v;
vec<char> c;
pll dp[100000];
vec<ll> G[100000];

bool isPrime(ll x) {
	for (ll i = 2;i * i <= x;i++) {
		if (x % i == 0) return false;
	}
	return true;
}

int main() {
	ll N;
	cin >> N;
	ll q[N];
	rep(i,0,N) cin >> q[i];

	ll dp[N+1][2] = {};
	bool pf[N];
	rep(i,0,N) pf[i] = isPrime(q[i]);
	if (!pf[0]) {
		cout << 0 << endl;
		return 0;
	}
	dp[0][0] = 1;
	rep(i,0,N-1) {
		if (pf[i] && q[i-1] < q[i+1]) {
			dp[i+1][1] = (dp[i+1][1] + dp[i][0]) % MOD;
		}
		if (pf[i+1]) {
			dp[i+1][0] = (dp[i+1][0] + dp[i][1]) % MOD;
		}
		if (pf[i] && pf[i+1] && q[i] < q[i+1]) {
			dp[i+1][0] = (dp[i+1][0] + dp[i][0]) % MOD;
		}
	}
	// rep(i,0,N) cout << dp[i][0] << " ";
	// cout << endl;
	// rep(i,0,N) cout << dp[i][1] << " ";
	// cout << endl;
	cout << (dp[N-1][0] + dp[N-1][1]) % MOD << endl;
	return 0;
}
accuracy: 0.08888888888888889
time_ms: 230
memory_kb: 7140
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using pll = pair<ll, ll>;
using uint = unsigned;
using pii = pair<int, int>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;

const int IINF = 0x1fffffff;
const ll LINF = 0x1fffffffffffffff;
const ll MINF = 0x7fffffffffff;
const ll MOD = 1000000007;
const ll MODD = 998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};

#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each1(i,a) for(auto&&i:a)
#define each2(x,y,a) for(auto&&[x,y]:a)
#define each3(x,y,z,a) for(auto&&[x,y,z]:a)
#define each(...) overload4(__VA_ARGS__,each3,each2,each1)(__VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
// #define sum(...) accumulate(all(__VA_ARGS__),0LL)
// #define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
// #define Msum(...) accumulate(all(__VA_ARGS__),0_M)
#define elif else if
#define unless(a) if(!(a))
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec vector
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }
vector<ll> iota(ll n, ll begin = 0){ vector<ll> a(n); iota(a.begin(), a.end(), begin); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T> a){ Uniq(a); unordered_map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
template<class T> map<T, ll> press_map(vector<T> a){ Uniq(a); map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class... T> void in(T&... a){ (void)initializer_list<int>{ (scan(a), 0)... }; }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull x){ return 63 - __builtin_clzll(x); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int First(bool i = true){ return out(i?"First":"Second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }

#define fi first
#define se second
#define rng(a) a.begin(), a.end()
#define chmax(x, y) (x = max(x, y))
#define chmin(x, y) (x = min(x, y))
#define removeerase(x) x.erase(remove(rng(x), 0), x.end());
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0)
    std::cout << " :";
  debug_out(t...);
}

constexpr uint mod = MOD;
struct Modint {
  uint num = 0;
  constexpr Modint() noexcept {}
  constexpr Modint(const Modint &x) noexcept : num(x.num) {}
  inline constexpr operator ll() const noexcept { return num; }
  inline constexpr Modint& operator+=(Modint x) noexcept {num += x.num; if (num >= mod) num -= mod; return *this; }
  inline constexpr Modint& operator-=(Modint x) noexcept { if (num < x.num) num += mod; num -= x.num; return *this; }
  inline constexpr Modint& operator*=(Modint x) noexcept { num = ull(num) * x.num % mod; return *this; }
  inline constexpr Modint& operator/=(Modint x) noexcept { return operator*=(x.inv()); }
  inline constexpr Modint& operator++() noexcept { if(num == mod - 1) num = 0; else num++; return *this; }
  inline constexpr Modint operator++(int) noexcept { Modint ans(*this); operator++(); return ans; }
  inline constexpr Modint& operator--() noexcept { if(num == 0) num = mod - 1; else num--; return *this; }
  inline constexpr Modint operator--(int) noexcept { Modint ans(*this); operator--(); return ans; }
  inline constexpr Modint operator-() const noexcept { return Modint(0) -= *this; }
  template<class T> constexpr Modint(T x) noexcept {
    using U = typename conditional<sizeof(T) >= 4, T, int>::type;
    U y = x; y %= U(mod); if(y < 0) y += mod; num = uint(y);
  }
  template<class T> inline constexpr Modint operator+(T x) const noexcept { return Modint(*this) += x; }
  template<class T> inline constexpr Modint& operator+=(T x) noexcept { return operator+=(Modint(x)); }
  template<class T> inline constexpr Modint operator-(T x) const noexcept { return Modint(*this) -= x; }
  template<class T> inline constexpr Modint& operator-=(T x) noexcept { return operator-=(Modint(x)); }
  template<class T> inline constexpr Modint operator*(T x) const noexcept { return Modint(*this) *= x; }
  template<class T> inline constexpr Modint& operator*=(T x) noexcept { return operator*=(Modint(x)); }
  template<class T> inline constexpr Modint operator/(T x) const noexcept { return Modint(*this) /= x; }
  template<class T> inline constexpr Modint& operator/=(T x) noexcept { return operator/=(Modint(x)); }
  inline constexpr Modint inv() const noexcept { ll x = 0, y = 0; extgcd(num, mod, x, y); return x; }
  static inline constexpr ll extgcd(ll a, ll b, ll &x, ll &y) noexcept { ll g = a; x = 1; y = 0; if(b){ g = extgcd(b, a % b, y, x); y -= a / b * x; } return g; }
  inline constexpr Modint pow(ull x) const noexcept { Modint ans = 1, cnt = *this; while(x){ if(x & 1) ans *= cnt; cnt *= cnt; x /= 2; } return ans; }
};
std::istream& operator>>(std::istream& is, Modint& x){ ll a; in(a); x = a; return is; }
inline constexpr Modint operator""_M(ull x) noexcept { return Modint(x); }
std::vector<Modint> fac(1, 1), inv(1, 1);
inline void reserve(ll a){
    if(fac.size() >= a) return;
    if(a < fac.size() * 2) a = fac.size() * 2;
    if(a >= mod) a = mod;
    while(fac.size() < a) fac.push_back(fac.back() * Modint(fac.size()));
    inv.resize(fac.size());
    inv.back() = fac.back().inv();
    for(ll i = inv.size() - 1; !inv[i - 1]; i--) inv[i - 1] = inv[i] * i;
}
inline Modint fact(ll n){ if(n < 0) return 0; reserve(n + 1); return fac[n]; }
inline Modint perm(ll n, ll r){
    if(r < 0 || n < r) return 0;
    if(n >> 24){ Modint ans = 1; for(ll i = 0; i < r; i++) ans *= n--; return ans; }
    reserve(n + 1); return fac[n] * inv[n - r];
}
inline Modint comb(ll n, ll r){ if(r < 0 || n < r) return 0; reserve(r + 1); return perm(n, r) * inv[r]; }
inline Modint Mcomb(ll n, ll r){ return comb(n + r - 1, n - 1); } // r balls into n boxes
inline Modint catalan(ll n){ reserve(n * 2 + 1); return fac[n * 2] * inv[n] * inv[n + 1]; }

const ll mx = 1 << 6;
struct Matrix{
    Modint a[mx][mx] = {};
    auto operator[](ll x){ return a[x]; }
    auto operator[](ll x) const { return a[x]; }
    static Matrix E(){
        Matrix a;
        for(ll i = 0; i < mx; i++) a[i][i] = 1;
        return a;
    }
    Matrix operator*(const Matrix& b) const {
        Matrix c;
        for(ll i = 0; i < mx; i++) for(ll j = 0; j < mx; j++) for(ll k = 0; k < mx; k++) c[i][k] += a[i][j] * b[j][k];
        return c;
    }
    void operator*=(const Matrix& b){
        *this = *this * b;
    }
    Matrix pow(ll b) const {
        Matrix a = *this, c = E();
        while(b){
            if(b & 1) c *= a;
            if(b >>= 1) a *= a;
        }
        return c;
    }
};

// vector<ll> facmod;
// vector<ll> facinvmod;
// ll combination(ll n, ll k, ll mod) {
//   // 階乗やその逆元をメモ化すると速い
//   // でかいやつはnCk/2^Nをパスカルの三角形で作る
//   ll res = fac(n, mod);
//   res = (res * invmod(fac(k, mod), mod)) % mod;
//   res = (res * invmod(fac(n - k, mod), mod)) % mod;
//   return res;
// }
// x % m[i] = r[i] % m[i] を満たす正で最小の x を返す
// i!=j に対して gcd(m[i], m[j])=1 であると仮定
// とりあえず解の存在判定は保留
// ll garner(vector<ll> r, vector<ll> m) {
//   int n = r.size();
//   ll m_prod = 1;      // m_prod には m[i] の積を入れていく
//   ll x = r[0] % m[0]; // 最初の条件を満たすような x の初期値
//   for (int i = 1; i < n; i++) {
//     // cout << r[i-1] << " " << m[i-1] << " " << x << endl;
//     m_prod *= m[i - 1]; // m の累積積を更新
//     ll t = ((r[i] - x) * invmod(m_prod, m[i])) % m[i];
//     if (t < 0)
//       t += m[i];
//     x += t * m_prod; // x を更新
//   }
//   return x;
// }
// false: composite, true: probably prime
// bool MillarRabin_sub(ll n, ll random) {
// 	ll d = n-1;
// 	while(d % 2 == 0) {
// // 		d /= 2;
// 		cout << random << " " << powmod(random, d, n) << endl;
// 		if (powmod(random, d, n) == n-1) {
// 			return true;
// 		}
// 	}
// 	if (powmod(random, d, n) == 1) return true;
// 	return false;
// }
// bool MillarRabin(ll n) {
// 	random_device rd{};
// 	vector<uint32_t> vec(20);
// 	generate(vec.begin(), vec.end(), ref(rd));
// 	mt19937 mt(seed_seq(vec.begin(), vec.end()));
// 	bool ret = true;
// 	rep(i,0,20) {
// 		vec[i] %= n; if (vec[i] == 0) continue;
// 		cout << MillarRabin_sub(n, random) << endl;
// 		if (!MillarRabin_sub(n, random)) return false;
// 	}
// 	return true;
// }

// 逆順になる reverse(rng(ans));
// vector<ll> G[100000];
// cout << fixed << setprecision(15) << y << endl;
// cout << bitset<20>(i) << endl;
// fill(distance[0], distance[row], INF);
// __builtin_popcount()
// stoi(S[j], 0, 2)
// for (ll i = 0;i < (ll)s.size() - k;i++)
// ll dp[桁数][未満フラグ][条件を満たしているか]
// stoi stoll
// bit全探索 n進数全探索
// while (t > 0) cc += t % 9, t /= 9;
// priority_queue<ll> que; que.push(3); que.top(); que.pop();
// rep(i,C)rep(j,C) if(i != j) rep(k,C) if(i != k && j != k)
// 始点終点をデータに含ませる
// memory restriction RE -> CE
// forr 逆順ループsnippet
// 座標 上下の回数さえ分かれば組合せ問題
// set 順序付き集合 distance(set.begin(), itr)でオフセットがわかる
// set s : for(int x : s) for(int y : s) for(int z : s)
// const int di[4] = {-1, 0, 1, 0};
// const int dj[4] = {0, -1, 0, 1};
// const string let = "ULDR";
// 逆順ソートsort(cand.rbegin(), cand.rend());
// int ok = 0, ng = 1e9+1;
// auto check = [&](int x) -> bool {
// 	set<int> s;
// 	rep(i,0,N) {
// 		int tmp = 0;
// 		rep(j,0,5) {
// 			if (A[i][j] >= x) tmp |= 1 << j;
// 		}
// 		s.insert(tmp);
// 	}
// 	for (int x : s) for (int y : s) for (int z : s) {
// 		if ((x | y | z) == 31) return true;
// 	}
// 	return false;
// };

// while(abs(ok - ng) > 1) {
// 	int mid = (ok + ng) / 2;
// 	if (check(mid)) ok = mid;
// 	else ng = mid;
// }
// cout << ok << endl;
// dp[500][500] はllではなくintにすること
// chmin/chmaxは型をあわせないといけない
// priority_queue 最上位以外アクセス許可していない
// priority_queue<l_l, vector<l_l>, greater<l_l>>
// multiset イテレータ書き込み出来ない

class FordFulkerson {
	struct edge {
		ll to, cap, rev;
	};
	ll n;
	vector<vector<edge>> G;
	vector<bool> used;

	ll dfs(ll s, ll t, ll f) {
		if (s == t) return f;
		used[s] = true;
		for (edge &e : G[s]) {
			if (!used[e.to] && e.cap > 0) {
				ll d = dfs(e.to, t, min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

public:
	FordFulkerson(ll n) : n(n), G(n), used(n) {}
	void add_edge(ll from, ll to, ll cap) {
		G[from].push_back({to, cap, ll(G[to].size())});
		G[to].push_back({from, 0, ll(G[from].size()) - 1});
	}

	ll max_flow(ll s, ll t) {
		ll flow = 0;
		while (true) {
			used.assign(n, 0);
			ll f = dfs(s, t, LINF);
			if (f == 0) return flow;
			flow += f;
		}
	}
};

ll n, q;
vec<ll> p, v;
vec<char> c;
pll dp[100000];
vec<ll> G[100000];

bool isPrime(ll x) {
	for (ll i = 2;i * i <= x;i++) {
		if (x % i == 0) return false;
	}
	return true;
}

int main() {
	ll N;
	cin >> N;
	ll q[N];
	rep(i,0,N) cin >> q[i];

	ll dp[N+1][2] = {};
	bool pf[N];
	rep(i,0,N) pf[i] = isPrime(q[i]);
	if (!pf[0]) {
		cout << 0 << endl;
		return 0;
	}
	dp[0][0] = 1;
	rep(i,0,N-1) {
		if (pf[i] && q[i-1] < q[i+1]) {
			dp[i+1][1] += dp[i][0];
		}
		if (pf[i+1]) {
			dp[i+1][0] += dp[i][1];
		}
		if (pf[i] && pf[i+1] && q[i] < q[i+1]) {
			dp[i+1][0] += dp[i][0];
		}
	}
	// rep(i,0,N) cout << dp[i][0] << " ";
	// cout << endl;
	// rep(i,0,N) cout << dp[i][1] << " ";
	// cout << endl;
	cout << dp[N-1][0] + dp[N-1][1] << endl;
	return 0;
}
accuracy: 0.08888888888888889
time_ms: 230
memory_kb: 7332
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 1000000007;
const ll M = 1000000;

int main() {
    ll n;
    cin >> n;
    vector<ll> q(n);
    for (int i = 0; i < n; i++) {
        cin >> q[i];
    }
    vector<bool> furui(M+1, true);
    furui[0] = furui[1] = false;
    for (int i = 2; i <= M; i++) {
        if (!furui[i]) {
            continue;
        }
        ll x = 2 * i;
        while (x <= M) {
            furui[x] = false;
            x += i;
        }
    }

    vector<vector<pair<int, ll>>> dp(n+2, vector<pair<int, ll>>(2,  pair<int, ll>(-1, 0)));
    dp[0][0] = make_pair(0, 1);
    for (int i = 0; i < n; i++) {
        if (!furui[q[i]]) {
            continue;
        }
        if (dp[i][0].first < q[i]) {
            dp[i+1][0] = {q[i], (dp[i+1][0].second + dp[i][0].second) % MOD};
            dp[i+2][1] = {q[i], (dp[i+2][1].second + dp[i][0].second) % MOD};
        }
        if (dp[i][1].first < q[i]) {
            dp[i+1][0] = {q[i], (dp[i+1][0].second + dp[i][1].second) % MOD};
            dp[i+2][1] = {q[i], (dp[i+2][1].second + dp[i][1].second) % MOD};
        }
    }
    cout << (dp[n][0].second + dp[n][1].second) % MOD << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 11032
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const long long MOD = 1000000007;

std::vector<bool> primearray(long long N){
    /*
    Copyright (c) 2021 0214sh7
    https://github.com/0214sh7/library/
    */
    std::vector<long long> R;
    std::vector<bool> prime;
    for(int i=0;i<=N;i++){
        prime.push_back(true);
    }
    if(N<2){
        return {0,0};
    }
    prime[0]=false;
    prime[1]=false;
    for(long long i=2;i*i<=N;i++){
        if(!prime[i])continue;
        for(int j=2*i;j<=N;j+=i){
            prime[j]=false;
        }
    }
    /*
    for(long long i=0;i<prime.size();i++){
        if(prime[i]){
            R.push_back(i);
        }
    }*/
    return prime;
}

int main(void){
    
    ll N;
    vector<ll> Q;
    vector<bool> P = primearray(1114514);
    
    cin >> N;
    for(int i=0;i<N;i++){
        ll q;
        cin >> q;
        Q.push_back(q);
    }
    
    vector<ll> dp(N,0),dp2(N,0);
    if(P[Q[0]]){
        dp[0]=1;
    }
    for(int i=1;i<N;i++){
        //基数にする場合
        if(P[Q[i]] && Q[i-1]<Q[i]){
            dp[i]+=dp[i-1];
            dp[i]%=MOD;
        }
        if(P[Q[i]] && i-2>=0 && Q[i-2]<Q[i]){
            dp[i]+=dp2[i-1];
            dp[i]%=MOD;
        }
        //指数にする場合
        dp2[i]+=dp[i-1];
        dp2[i]%=MOD;
    }
    
    ll r = dp[N-1]+dp2[N-1];
    r%=MOD;
    cout << r << endl;
    
    //for(int i=0;i<N;i++){cout << dp[i] << " ";}cout << endl;
    //for(int i=0;i<N;i++){cout << dp2[i] << " ";}cout << endl;
    
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5616
final_rank: 4

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

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n) for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n) for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v+n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout<<d<<endl;
#define coutd(d) cout<<std::setprecision(10)<<d<<endl;
#define cinline(n) getline(cin,n);
#define replace_all(s, b, a) replace(s.begin(),s.end(), b, a);
#define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll,ll,ll>>;
using vb = vector<bool>;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const ll INF = 1e9+10;
const ll MOD = 1e9+7;
const ll LINF = 1e18;

const ll maxn_eratosthenes = 1000005;
bool _is_prime[maxn_eratosthenes];
set<ll> P;

void eratosthenes(const ll N)
{
  P.clear();
  for (ll i = 0; i <= N; i++) {
    _is_prime[i] = true;
  }
  _is_prime[0]=_is_prime[1]=false;
  for (ll i = 2; i <= N; i++) {
    if (_is_prime[i]) {
      for (ll j = 2 * i; j <= N; j += i) {
        _is_prime[j] = false;
      }
      P.insert(i);
    }
  }
}

ll dp[100005][2]; // iまでで、iを指数にしたかがjの時の場合数

signed main()
{
  cin.tie( 0 ); ios::sync_with_stdio( false );
  
  ll n; cin>>n;
  vll a(n);
  rep(i,n) cin>>a[i];
  
  eratosthenes(1000000);
  if(P.count(a[0])) {
    dp[1][0]=1;
  }
  
  // 直前の数を指数として使ったなら、iから見て直前の数はa-2になる
  // prev_0: iを数として使った場合iがそのまま
  // prev_1: iを指数として使った場合prev_0
  
  irep(i,1,n){
    if(!P.count(a[i])){
      // 必ず指数にしないといけない
      (dp[i+1][1]+=dp[i][0])%=MOD;
    }else if(a[i-1]>a[i]){
      (dp[i+1][1]+=dp[i][0])%=MOD;
      if(i>1 && a[i-2]<a[i]) (dp[i+1][0]+=dp[i][1])%=MOD;
    }else if(a[i-1]==a[i]){
      (dp[i+1][1]+=dp[i][0])%=MOD;
      if(i>1 && a[i-2]<a[i]) (dp[i+1][0]+=dp[i][1])%=MOD;
    }else{
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][0])%=MOD;
      if(i>1 && a[i-2]<a[i]) (dp[i+1][0]+=dp[i][1])%=MOD;
    }
  }
  
  ll ans=(dp[n][0]+dp[n][1])%MOD;
  cout<<ans<<endl;
  
}
accuracy: 1
time_ms: 30
memory_kb: 9868
final_rank: 8

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

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n) for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n) for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v+n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout<<d<<endl;
#define coutd(d) cout<<std::setprecision(10)<<d<<endl;
#define cinline(n) getline(cin,n);
#define replace_all(s, b, a) replace(s.begin(),s.end(), b, a);
#define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll,ll,ll>>;
using vb = vector<bool>;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const ll INF = 1e9+10;
const ll MOD = 1e9+7;
const ll LINF = 1e18;

const ll maxn_eratosthenes = 1000005;
bool _is_prime[maxn_eratosthenes];
set<ll> P;

void eratosthenes(const ll N)
{
  P.clear();
  for (ll i = 0; i <= N; i++) {
    _is_prime[i] = true;
  }
  _is_prime[0]=_is_prime[1]=false;
  for (ll i = 2; i <= N; i++) {
    if (_is_prime[i]) {
      for (ll j = 2 * i; j <= N; j += i) {
        _is_prime[j] = false;
      }
      P.insert(i);
    }
  }
}

ll dp[100005][2]; // iまでで、iを指数にしたかがjの時の場合数

signed main()
{
  cin.tie( 0 ); ios::sync_with_stdio( false );
  
  ll n; cin>>n;
  vll a(n);
  rep(i,n) cin>>a[i];
  
  eratosthenes(1000000);
  ll prev[2];
  if(P.count(a[0])) {
    dp[1][0]=1;
    prev[0]=a[0];
  }
  
  // 直前の数を指数として使ったなら、iから見て直前の数はa-2になる
  // prev_0: iを数として使った場合iがそのまま
  // prev_1: iを指数として使った場合prev_0
  
  irep(i,1,n){
    if(!P.count(a[i])){
      // 必ず指数にしないといけない
      (dp[i+1][1]+=dp[i][0])%=MOD;
    }else if(a[i-1]>a[i]){
      (dp[i+1][1]+=dp[i][0])%=MOD;
      if(i>1 && a[i-2]<a[i]) (dp[i+1][0]+=dp[i][1])%=MOD;
    }else if(a[i-1]==a[i]){
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][1])%=MOD;
    }else{
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][1])%=MOD;
    }
  }
  
  ll ans=(dp[n][0]+dp[n][1])%MOD;
  cout<<ans<<endl;
  
}
accuracy: 0.08888888888888889
time_ms: 20
memory_kb: 8976
final_rank: 17

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

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n) for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n) for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v+n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout<<d<<endl;
#define coutd(d) cout<<std::setprecision(10)<<d<<endl;
#define cinline(n) getline(cin,n);
#define replace_all(s, b, a) replace(s.begin(),s.end(), b, a);
#define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll,ll,ll>>;
using vb = vector<bool>;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const ll INF = 1e9+10;
const ll MOD = 1e9+7;
const ll LINF = 1e18;

const ll maxn_eratosthenes = 1000005;
bool _is_prime[maxn_eratosthenes];
set<ll> P;

void eratosthenes(const ll N)
{
  P.clear();
  for (ll i = 0; i <= N; i++) {
    _is_prime[i] = true;
  }
  _is_prime[0]=_is_prime[1]=false;
  for (ll i = 2; i <= N; i++) {
    if (_is_prime[i]) {
      for (ll j = 2 * i; j <= N; j += i) {
        _is_prime[j] = false;
      }
      P.insert(i);
    }
  }
}

ll dp[100005][2]; // iまでで、iを指数にしたかがjの時の場合数

signed main()
{
  cin.tie( 0 ); ios::sync_with_stdio( false );
  
  ll n; cin>>n;
  vll a(n);
  rep(i,n) cin>>a[i];
  
  eratosthenes(1000000);
  
  dp[0][0]=1;
  if(P.count(a[0])) dp[1][0]=1;
  
  irep(i,1,n){
    if(a[i-1]>a[i] || !P.count(a[i])){
      // 必ず指数にしないといけない
      (dp[i+1][1]+=dp[i][0])%=MOD;
    }else if(a[i-1]==a[i]){
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][1])%=MOD;
    }else{
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][1])%=MOD;
    }
  }
  
  ll ans=(dp[n][0]+dp[n][1])%MOD;
  cout<<ans<<endl;
  
}
accuracy: 0.08888888888888889
time_ms: 20
memory_kb: 9056
final_rank: 18

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

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n) for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n) for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v+n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout<<d<<endl;
#define coutd(d) cout<<std::setprecision(10)<<d<<endl;
#define cinline(n) getline(cin,n);
#define replace_all(s, b, a) replace(s.begin(),s.end(), b, a);
#define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll,ll,ll>>;
using vb = vector<bool>;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const ll INF = 1e9+10;
const ll MOD = 1e9+7;
const ll LINF = 1e18;

const ll maxn_eratosthenes = 1000005;
bool _is_prime[maxn_eratosthenes];
set<ll> P;

void eratosthenes(const ll N)
{
  P.clear();
  for (ll i = 0; i <= N; i++) {
    _is_prime[i] = true;
  }
  _is_prime[0]=_is_prime[1]=false;
  for (ll i = 2; i <= N; i++) {
    if (_is_prime[i]) {
      for (ll j = 2 * i; j <= N; j += i) {
        _is_prime[j] = false;
      }
      P.insert(i);
    }
  }
}

ll dp[100005][2]; // iまでで、iを指数にしたかがjの時の場合数

signed main()
{
  cin.tie( 0 ); ios::sync_with_stdio( false );
  
  ll n; cin>>n;
  vll a(n);
  rep(i,n) cin>>a[i];
  
  eratosthenes(1000000);
  
  dp[0][0]=1;
  if(P.count(a[0])) dp[1][0]=1;
  
  irep(i,1,n){
    if(a[i-1]>a[i] || !P.count(a[i])){
      // 必ず指数にしないといけない
      dp[i+1][1]+=dp[i][0];
    }else if(a[i-1]==a[i]){
      dp[i+1][1]+=dp[i][0];
      if(P.count(a[i])) dp[i+1][0]+=dp[i][1];
    }else{
      (dp[i+1][1]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][0])%=MOD;
      (dp[i+1][0]+=dp[i][1])%=MOD;
    }
  }
  
  ll ans=(dp[n][0]+dp[n][1])%MOD;
  cout<<ans<<endl;
  
}
accuracy: 0.08888888888888889
time_ms: 20
memory_kb: 8956
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;

bool p[1000010];
void init(){
    int MAX = 1000010;
    for(int i=0;i<MAX;i++) p[i]=1;
    p[0]=0, p[1] = 1;
    for(int i=2;i<=MAX/2;i++){
        if(p[i]){
            for(int j=i+i;j<MAX;j+=i) p[j]=0;
        }
    }
}

signed main(){
    ios::sync_with_stdio(false);
	cin.tie(0);
    cout << fixed << setprecision(20);

    int n;
    cin>>n;
    int a[n];
    init();
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    if(p[a[0]]==false){
        cout << 0 << endl;
        return 0;
    }
    ll mod = 1e9+7;
    ll dp[n+1][2]={};
    dp[0][0]=1;
    for(int i=0;i<n;i++){
        if(i) dp[i+1][1] += dp[i][0];
        dp[i+1][1] %= mod;
        if(i-2>=0 && a[i]>a[i-2] && p[a[i]]){
            dp[i+1][0] += dp[i][1];
        }
        if(i && a[i]>a[i-1] && p[a[i]]){
            dp[i+1][0] += dp[i][0];
        }
        if(i==0){
            dp[i+1][0] += dp[i][0];
        }
        dp[i+1][0] %= mod;
    }
    ll ans = dp[n][0] + dp[n][1];
    ans %= mod;
    cout << ans << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 6140
final_rank: 5