#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
 
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef unsigned long long ull;
typedef long double ld; 
typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds;

vector<int> fact;
vector<int> ifact;
vector<int> inv;
vector<int> pow2;
const int MOD = (1e9 + 7);
int add(int a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
	return a;
}
void radd(int &a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
}	

int mult(int a, int b)
{
	return (a*1LL*b)%MOD;
}
int modpow(int a, int b)
{
	int r=1;
	while(b)
	{
		if(b&1) r=mult(r,a);
		a=mult(a,a);
		b>>=1;
	}
	return r;
}
int choose(int a, int b)
{
	if(a<b) return 0;
	if(b==0) return 1;
	if(a==b) return 1;
	return mult(fact[a],mult(ifact[b],ifact[a-b]));
}
int inverse(int a)
{
	return modpow(a,MOD-2);
}
void init(int _n)
{
	fact.clear(); ifact.clear(); inv.clear(); pow2.clear();
	fact.resize(_n+1);
	ifact.resize(_n+1);
	inv.resize(_n+1);
	pow2.resize(_n+1);
	pow2[0]=1;
	ifact[0]=1;
	fact[0]=1;
	for(int i=1;i<=_n;i++)
	{
		pow2[i]=add(pow2[i-1],pow2[i-1]);
		fact[i]=mult(fact[i-1],i);
		//ifact[i]=mult(ifact[i-1],inv[i]);
	}
	ifact[_n] = inverse(fact[_n]);
	for(int i=_n-1;i>=1;i--)
	{
		ifact[i] = mult(ifact[i + 1], i + 1);
	}
	for(int i=1;i<=_n;i++)
	{
		inv[i] = mult(fact[i-1],ifact[i]);
	}
}
	
int a[1111];
int used[1111];
int id[11111];
int dp[2][311][311];

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin>>n;
	init(5555);
	for(int i=0;i<n*2;i++)
	{
		cin>>a[i]; a[i]--;
	}
	set<int> S;
	for(int i=0;i<n*2;i++) S.insert(i);
	int blanks=0;
	vector<int> V;
	for(int i=0;i<n;i++)
	{
		if(a[i*2]>=0&&a[i*2+1]>=0)
		{
			S.erase(a[i*2]); S.erase(a[i*2+1]);
		}
		else if(a[i*2]<0&&a[i*2+1]<0)
		{
			blanks++;
		}
		else
		{
			V.pb(max(a[i*2],a[i*2+1]));
		}
	}
	int cnt=0;
	for(auto z:S)
	{
		id[z]=cnt++;
	}
	for(int i=0;i<V.size();i++) V[i]=id[V[i]];
	n = cnt;
	//new n is even
	//blanks vs V
	for(int v:V) used[v]=1;
	dp[n&1][0][0]=1;
	int up = 0;
	for(int i=n-1;i>=0;i--)
	{
		int cur=i&1; int pre=cur^1;
		
			for(int k=0;k<=min(n-i,n/2);k++)
			{
				for(int l=0;l<=n;l++)
				{
					dp[cur][k][l]=0;
				}
			}
		
			for(int k=0;k<=min(n-i,n/2);k++)
			{
				for(int l=0;l<=up;l++)
				{
					if(dp[pre][k][l])
					{
						int v=dp[pre][k][l];
						if(used[i])
						{
							//i is small
							if(k>0)
							{
								radd(dp[cur][k-1][l+1],v);
							}
							//i is large
							radd(dp[cur][k][l],v);
						}
						else
						{
							//big number
							radd(dp[cur][k+1][l],v);
							//add(dp[cur][j][k][l],v);
							//add to min a thing
							//# of non-completed = up - l
							if(up-l>0)
							{
								radd(dp[cur][k][l+1],mult(up-l,v));
							}
							//use as new hostage
							if(k>0)
							{
								radd(dp[cur][k-1][l],v);
							}
						}
					}
				}
		}
		if(used[i]) up++;
	}
	int ans = 0;
	/*
	for(int i=0;i<=0;i++) 
	{
		//cerr<<i<<' '<<dp[0][blanks][i][up-i]<<'\n';
		radd(ans, dp[0][blanks][i][up-i]);
	}
	*/
	radd(ans, dp[0][0][up]);
	ans = mult(ans,fact[blanks]);
	cout<<ans<<'\n';
	
}


Measured memory_bytes: 1152