Problem:
Score : 1600 points

Problem Statement

There is a sequence of length 2N: A_1, A_2, ..., A_{2N}.
Each A_i is either -1 or an integer between 1 and 2N (inclusive). Any integer other than -1 appears at most once in {A_i}.

For each i such that A_i = -1, Snuke replaces A_i with an integer between 1 and 2N (inclusive), so that {A_i} will be a permutation of 1, 2, ..., 2N.
Then, he finds a sequence of length N, B_1, B_2, ..., B_N, as B_i = min(A_{2i-1}, A_{2i}).

Find the number of different sequences that B_1, B_2, ..., B_N can be, modulo 10^9 + 7.

Constraints

1 \leq N \leq 300

A_i = -1 or 1 \leq A_i \leq 2N.

If A_i \neq -1, A_j \neq -1, then A_i \neq A_j. (i \neq j)

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_{2N}

Output

Print the number of different sequences that B_1, B_2, ..., B_N can be, modulo 10^9 + 7.

Sample Input 1

3
1 -1 -1 3 6 -1

Sample Output 1

5

There are six ways to make {A_i} a permutation of 1, 2, ..., 2N; for each of them, {B_i} would be as follows:

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 2, 4, 3, 6, 5): (B_1, B_2, B_3) = (1, 3, 5)

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 2, 5, 3, 6, 4): (B_1, B_2, B_3) = (1, 3, 4)

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 4, 2, 3, 6, 5): (B_1, B_2, B_3) = (1, 2, 5)

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 4, 5, 3, 6, 2): (B_1, B_2, B_3) = (1, 3, 2)

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 5, 2, 3, 6, 4): (B_1, B_2, B_3) = (1, 2, 4)

(A_1, A_2, A_3, A_4, A_5, A_6) = (1, 5, 4, 3, 6, 2): (B_1, B_2, B_3) = (1, 3, 2)

Thus, there are five different sequences that B_1, B_2, B_3 can be.

Sample Input 2

4
7 1 8 3 5 2 6 4

Sample Output 2

1

Sample Input 3

10
7 -1 -1 -1 -1 -1 -1 6 14 12 13 -1 15 -1 -1 -1 -1 20 -1 -1

Sample Output 3

9540576

Sample Input 4

20
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 6 -1 -1 -1 -1 -1 7 -1 -1 -1 -1 -1 -1 -1 -1 -1 34 -1 -1 -1 -1 31 -1 -1 -1 -1 -1 -1 -1 -1

Sample Output 4

374984201

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

#include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

template<typename T,T MOD = 1000000007>
struct Mint{
  T v;
  Mint():v(0){}
  Mint(signed v):v(v){}
  Mint(long long t){v=t%MOD;if(v<0) v+=MOD;}

  Mint pow(long long k){
    Mint res(1),tmp(v);
    while(k){
      if(k&1) res*=tmp;
      tmp*=tmp;
      k>>=1;
    }
    return res;
  }
  
  Mint inv(){return pow(MOD-2);}
  
  Mint& operator+=(Mint a){v+=a.v;if(v>=MOD)v-=MOD;return *this;}
  Mint& operator-=(Mint a){v+=MOD-a.v;if(v>=MOD)v-=MOD;return *this;}
  Mint& operator*=(Mint a){v=1LL*v*a.v%MOD;return *this;}
  Mint& operator/=(Mint a){return (*this)*=a.inv();}
  
  Mint operator+(Mint a) const{return Mint(v)+=a;};
  Mint operator-(Mint a) const{return Mint(v)-=a;};
  Mint operator*(Mint a) const{return Mint(v)*=a;};
  Mint operator/(Mint a) const{return Mint(v)/=a;};

  Mint operator-(){return v?MOD-v:v;}

  bool operator==(const Mint a)const{return v==a.v;}
  bool operator!=(const Mint a)const{return v!=a.v;}
  bool operator <(const Mint a)const{return v <a.v;}
  
};

//INSERT ABOVE HERE
const int MAX = 303;
using M = Mint<int>;
M dp[MAX][MAX*2];
int used[MAX*2];
int side[MAX*2];
int sml[MAX*2];
signed main(){
  int n;
  cin>>n;
  vector<int> a(n*2);
  for(int i=0;i<n*2;i++) cin>>a[i];
  
  memset(used,0,sizeof(used));
  for(int i=0;i<n*2;i++)
    if(~a[i]) used[a[i]]=1;

  int cnt=0;  
  memset(side,0,sizeof(side));
  memset(sml,0,sizeof(sml));
  for(int i=0;i<n;i++){
    if(a[i*2]<0&&a[i*2+1]<0){
      cnt++;
      continue;
    }
    if(a[i*2]>0&&a[i*2+1]>0){
      sml[a[i*2]]=a[i*2]<a[i*2+1];
      sml[a[i*2+1]]=a[i*2]>a[i*2+1];
      continue;
    }
    if(a[i*2]>0) side[a[i*2]]=1;
    if(a[i*2+1]>0) side[a[i*2+1]]=1;
  }
  
  for(int j=0;j<MAX;j++)
    for(int k=0;k<MAX*2;k++)
      dp[j][k]=0;

  dp[0][0]=1;
  
  int num=0,laz=0;
  for(int i=n*2;i>=1;i--){
    if(used[i]&&!side[i]) continue;
    
    if(used[i]){
      assert(side[i]);
      for(int j=n;j>=0;j--){
        for(int k=n*2;k>=0;k--){
          if(j*2+k+1<=laz) dp[j][k+1]+=dp[j][k];
        }
      }
      num++;
      continue;
    }
    
    if(!used[i]){      
      for(int j=n;j>=0;j--){
        for(int k=n;k>=0;k--){         
          if(j*2+k+1<=laz&&j+1<=cnt) dp[j+1][k]+=dp[j][k]*M(cnt-j);
          if(k+1<=num) dp[j][k+1]+=dp[j][k]*M(num-k);          
        }
      }
      laz++;
      continue;
    }
  }
  
  M ans=dp[cnt][num];
  cout<<ans.v<<endl;
  return 0;
}