#include using namespace std; const int MAXN = 1210; const int MOD = 1E9 + 7; typedef long long ll; #define ADD(x, y) (((x) + (y)) % MOD) #define TIMES(x, y) (((x) * (y)) % MOD) ll ar[MAXN]; int N; ll facts[MAXN]; ll ifacts[MAXN]; void prec() { facts[0] = 1; for(int i = 0; i + 1 < MAXN; ++i) { facts[i + 1] = TIMES(facts[i], i + 1); } ifacts[1200] = 929600184; // Powermod[1200!, -1, 1E9+7] for(int i = 1200; i - 1 >= 0; --i) { ifacts[i - 1] = TIMES(ifacts[i], i); } /* for(int i = 0; i < 10; ++i) { printf("%lld %lld %lld\n", facts[i], ifacts[i], TIMES(facts[i], ifacts[i])); }*/ } // n!/(n-k)! ll P(int n, int k) { return TIMES(facts[n], ifacts[n - k]); /* int prod = 1; for(int i = 0; i < k; ++i) { prod *= n - i; } return prod;*/ } int run[MAXN]; bool can(int n, int k) { return k <= run[n]; /* for(int i = 0; i + 1 < k; ++i) { if (ar[n + i] > ar[n + i + 1]) return false; } return true; */ } ll DP[MAXN][MAXN]; // O(n^3) with great constant factor. we'll see how it does. ll go(int n, int slice) { if (n == N) return 1; ll &ret = DP[n][slice]; if (ret) return ret - 1; for(int i = 1; i <= slice && i + n <= N; ++i) { if (can(n, i)) { // is this subarray strictly increasing? ret = ADD(ret, TIMES(P(slice, i), go(n + i, i))); } } return ret++; } int main(){ prec(); int n; cin >> n; N = n; vector m(n); for(int m_i = 0; m_i < n; m_i++){ cin >> m[m_i]; ar[m_i] = m[m_i]; } run[n - 1] = 1; for(int i = n - 2; i >= 0; --i) { if (ar[i] < ar[i + 1]) { run[i] = run[i + 1] + 1; } else { run[i] = 1; } } ll ans = 0; for(int i = 1; i <= n; ++i) { if (can(0, i)) { ans = ADD(ans, go(i, i)); } } cout << ans << "\n"; return 0; }