#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <cstdlib>
#include <utility>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>

using namespace std;

#define ll long long

// TEMPLATE STARTS BELOW

#define DEFMOD(mod, type) typedef ModInt<mod, int> type;     \
                          type operator "" _m(unsigned long long x) {   \
                              type res = x; return res; \
                          }

template<int mod, class itype> struct ModInt {
    int val;
    ModInt() {
        val = 0;
    }
    ModInt(int a) {
        val = a % mod;
    }
};

/* MODIFY AS NEEDED */

DEFMOD(1000000007, mi)

template<int mod, class itype> ModInt<mod, itype> fpow(ModInt<mod, itype> base, int exponent)
{
    ModInt<mod, itype> ans = 1_m;
    ModInt<mod, itype> cur = base;
    while (exponent) {
        if (exponent & 1) ans = ans * cur;
        cur = cur * cur; exponent >>= 1;
    }
    return ans;
}

template<int mod, class itype> ModInt<mod, itype> operator+(ModInt<mod, itype> a, ModInt<mod, itype> b)
{
    ModInt<mod, itype> ans;
    ll val = (ll)(a.val) + (ll)(b.val);
    if (val >= mod) val -= mod;
    ans.val = val; return ans;
}

template<int mod, class itype> ModInt<mod, itype> operator-(ModInt<mod, itype> a, ModInt<mod, itype> b)
{
    ModInt<mod, itype> ans;
    ans.val = a.val - b.val;
    if (ans.val < 0) ans.val += mod;
    return ans;
}

template<int mod, class itype> ModInt<mod, itype> operator*(ModInt<mod, itype> a, ModInt<mod, itype> b)
{
    ModInt<mod, itype> ans;
    ans.val = ((ll)(a.val) * (ll)(b.val)) % (ll)mod;
    return ans;
}

// PRIME MOD ONLY!
template<int mod, class itype> ModInt<mod, itype> operator/(ModInt<mod, itype> a, ModInt<mod, itype> b)
{
#ifndef ONLINE_JUDGE
    if (b.val == 0) {
        fprintf(stderr, "Division by zero :(\n"); abort();
    }
#endif
    return a * fpow(b, mod - 2);
}

//mi f[45][25][25][25];
mi f[605][305][305];

int seq[605];
int a[605];
bool remv[605];
int mapping[605];

int n;

bool in_x[605];

int free_cnt = 0;

void work(void)
{
    if (n == 0) {
        printf("1"); return;
    }
    for (int i = 1; i <= 2 * n; i++) {
        if (a[i] != -1) {
            in_x[a[i]] = true;
        }
    }
    f[2 * n + 1][0][0] = 1_m;
    for (int i = 2 * n + 1; i > 1; i--) {
        for (int j = 0; j <= n; j++) {
            for (int k = 0; k <= n; k++) {
                //if (f[i][j][k].val) printf("%d %d %d: %d\n", i, j, k, f[i][j][k].val);
                if (in_x[i - 1]) {
                    f[i-1][j][k+1] = f[i-1][j][k+1] + f[i][j][k];
                    if (j) f[i-1][j-1][k] = f[i-1][j-1][k] + f[i][j][k];
                } else {
                    f[i-1][j+1][k] = f[i-1][j+1][k] + f[i][j][k];
                    if (j) f[i-1][j-1][k] = f[i-1][j-1][k] + f[i][j][k];
                    if (k) f[i-1][j][k-1] = f[i-1][j][k-1] + f[i][j][k] * (mi)k;
                }
            }
        }
    }
    mi ans = f[1][0][0].val;
    for (int i = 1; i <= free_cnt; i++) {
        ans = ans * (mi)i;
    }
    printf("%d", ans.val);
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= 2 * n; i++) {
        scanf("%d", seq + i);
    }

    for (int i = 1; i <= 2 * n; i += 2) {
        if (seq[i] != -1 && seq[i+1] != -1) {
            remv[seq[i]] = remv[seq[i+1]] = true;
        }
    }
    for (int i = 1; i <= 2 * n; i++) {
        if (remv[i]) {
            mapping[i] = mapping[i-1];
        } else {
            mapping[i] = mapping[i-1] + 1;
        }
    }
    int realn = 0;
    for (int i = 1; i <= 2 * n; i += 2) {
        if (seq[i] == -1 || seq[i+1] == -1) {
            realn++;
            a[realn * 2 - 1] = (seq[i] == -1 ? -1 : mapping[seq[i]]);
            a[realn * 2] = (seq[i+1] == -1 ? -1 : mapping[seq[i+1]]);
        }
        if (seq[i] == -1 && seq[i+1] == -1) free_cnt++;
    }
    n = realn;
    work();
    return 0;
}


Measured memory_bytes: 221568