#include <iostream>
#include <vector>
#include <numeric>
#include <set> // Used for conceptual clarity in merge, can be optimized
using namespace std;
long long power(long long base, long long exp) {
long long res = 1;
base %= 1000000007;
while (exp > 0) {
if (exp % 2 == 1) res = (res * base) % 1000000007;
base = (base * base) % 1000000007;
exp /= 2;
}
return res;
}
long long inv(long long n) {
return power(n, 1000000007 - 2);
}
const int MAX_N = 2005; // Adjust based on constraints if necessary
long long fact[MAX_N];
long long invFact[MAX_N];
const long long MOD = 1000000007;
void precompute_factorials(int n) {
fact[0] = 1;
invFact[0] = 1;
for (int i = 1; i <= n; ++i) {
fact[i] = (fact[i - 1] * i) % MOD;
invFact[i] = inv(fact[i]); // Can optimize inv calculation
}
// Optimized inverse factorial calculation:
// invFact[n] = inv(fact[n]);
// for (int i = n - 1; i >= 0; --i) {
// invFact[i] = (invFact[i + 1] * (i + 1)) % MOD;
// }
}
long long nPr_mod(int n, int r) {
if (r < 0 || r > n) {
return 0;
}
long long num = fact[n];
long long den = invFact[n - r];
return (num * den) % MOD;
}
// Global variables for precomputed data
int n;
vector<int> a;
vector<int> pos;
vector<bool> is_fixed;
vector<bool> is_missing;
vector<int> missing_numbers;
vector<int> minus1_prefix;
vector<int> missing_lt_k_count;
int total_missing_count;
// --- Calculation Functions ---
long long calculate_count(int l, int r, int k) {
// Base case: k=0 means MEX >= 0, which is always true for non-empty subsegments.
// However, our sum starts from k=1 for V(l,r) = Sum_{k=1..n} Count(l,r,k)
if (k == 0) return 0; // Or handle differently if MEX=0 contribution needed elsewhere
// 1. Check fixed numbers 0..k-1 are within [l,r]
for (int x = 0; x < k; ++x) {
if (is_fixed[x]) {
if (pos[x] < l || pos[x] > r) {
return 0; // Fixed number required for MEX >= k is outside the segment
}
}
}
// 2. Count required missing numbers (N_k)
int N_k = missing_lt_k_count[k];
// 3. Count available -1 slots inside [l,r] (m_in)
int m_in = minus1_prefix[r + 1] - minus1_prefix[l];
// 4. Check feasibility
if (m_in < N_k) {
return 0; // Not enough slots to place required missing numbers
}
// 5. Calculate ways P(m_in, N_k) * (m - N_k)!
long long term1 = nPr_mod(m_in, N_k);
long long term2 = fact[total_missing_count - N_k];
long long result = (term1 * term2) % MOD;
return result;
}
// Calculate V(l, r) = Sum_{k=1..n} Count(l, r, k)
// This is O(N) per call.
long long calculate_V(int l, int r) {
long long val_lr = 0;
for (int k = 1; k <= n; ++k) {
val_lr = (val_lr + calculate_count(l, r, k)) % MOD;
}
return val_lr;
}
// --- Divide and Conquer ---
// Naive O(N^3) merge step: iterates l, r and calls calculate_V (which is O(N))
long long compute_crossing_sum_naive(int L, int mid, int R) {
long long crossing_sum = 0;
for (int l = mid; l >= L; --l) {
for (int r = mid + 1; r <= R; ++r) {
// O(N) calculation inside O(N^2) loops -> O(N^3)
long long val_lr = calculate_V(l, r);
crossing_sum = (crossing_sum + val_lr) % MOD;
}
}
return crossing_sum;
}
// ** PLACEHOLDER for Optimized O(N^2) merge step **
// This function would replace compute_crossing_sum_naive.
// It requires efficiently calculating Sum_{l=L..mid, r=mid+1..R} Sum_{k=1..n} Count(l,r,k)
// without the innermost O(N) loop over k for each (l,r).
// This likely involves maintaining state (like running sums or bounds for k)
// as l and r loops progress. The exact implementation is complex.
/*
long long compute_crossing_sum_optimized(int L, int mid, int R) {
long long crossing_sum = 0;
// Iterate l from mid down to L
for (int l = mid; l >= L; --l) {
// Maintain state for [l, mid] (fixed nums, -1 count)
// Iterate r from mid + 1 up to R
for (int r = mid + 1; r <= R; ++r) {
// Maintain state for [mid + 1, r] (fixed nums, -1 count)
// Combine states for [l, r]
// Efficiently update/calculate Sum_{k=1..n} Count(l, r, k)
// Add to crossing_sum
}
}
return crossing_sum;
}
*/
long long run_solve(int L, int R) {
if (L > R) {
return 0;
}
if (L == R) {
// Base case: Single element subsegment
return calculate_V(L, L);
}
int mid = L + (R - L) / 2; // Avoid potential overflow
long long res = (run_solve(L, mid) + run_solve(mid + 1, R)) % MOD;
// *** Use the naive merge for now. Replace with optimized version if available ***
long long cross_sum = compute_crossing_sum_naive(L, mid, R);
// long long cross_sum = compute_crossing_sum_optimized(L, mid, R);
res = (res + cross_sum) % MOD;
return res;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
a.resize(n);
pos.assign(n, -1);
is_fixed.assign(n, false);
is_missing.assign(n, true); // Assume missing initially
minus1_prefix.assign(n + 1, 0);
missing_lt_k_count.assign(n + 1, 0);
for (int i = 0; i < n; ++i) {
cin >> a[i];
minus1_prefix[i + 1] = minus1_prefix[i];
if (a[i] != -1) {
pos[a[i]] = i;
is_fixed[a[i]] = true;
is_missing[a[i]] = false;
} else {
minus1_prefix[i + 1]++;
}
}
for (int i = 0; i < n; ++i) {
if (is_missing[i]) {
missing_numbers.push_back(i);
}
}
total_missing_count = missing_numbers.size();
int current_missing_lt_k = 0;
for (int k = 0; k < n; ++k) {
if (is_missing[k]) {
current_missing_lt_k++;
}
missing_lt_k_count[k + 1] = current_missing_lt_k; // missing_lt_k_count[k] stores count < k
}
precompute_factorials(n); // Precompute up to n
cout << run_solve(0, n - 1) << endl;
return 0;
}