#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=200005;
const int mod=1000000007;

struct E{
	int to,next;
}mem[N<<1];
int h,t,num,n,x,y,m,ans,res,sum,ns,siz,ssr;
int dp[N],sz[N],head[N],tp[N],q[N],fac[N],inv[N],d[N];
bool vis[N];

void addedge(int x,int y){
	num++;
	mem[num].to=y; mem[num].next=head[x];
	head[x]=num; d[x]++;
}

int quickpow(int x,int y){
	int s=1;
	for (;y;y>>=1,x=1ll*x*x%mod)
		if (y&1) s=1ll*s*x%mod;
	return s;
}

void init(int n){
	int i; fac[0]=fac[1]=inv[0]=inv[1]=1;
	for (i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
	inv[n]=quickpow(fac[n],mod-2);
	for (i=n-1;i>=1;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
}

int C(int x,int y){
	if (x<y) return 0;
	return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
}

void add(int &x,int y){
	x+=y;
	(x>=mod)?x-=mod:0;
}

void bfs(int st){
	int k,u,j;
	h=t=0; q[++t]=st;
	while (h<t){
		k=q[++h]; vis[k]=1;
		for (j=head[k];j;j=mem[j].next){
			u=mem[j].to;
			if (!vis[u]){
				q[++t]=u; vis[u]=1;
			}
		}
	}
}

void topsort(){
	int k,u,j;
	while (h<t){
		k=tp[++h];
		for (j=head[k];j;j=mem[j].next){
			u=mem[j].to; d[u]--;
			if (d[u]==1) tp[++t]=u;
		}
	}
}

void dfs(int k,int pre,int rt){
	int u,j; bool tag=0;
	for (j=head[k];j;j=mem[j].next){
		u=mem[j].to;
		if (u==pre||u==rt) continue;
		dfs(u,k,rt); tag=1;
	}
	if (!tag){
		sz[k]=dp[k]=1;
		return;
	}
	sz[k]=0; dp[k]=1;
	for (j=head[k];j;j=mem[j].next){
		u=mem[j].to;
		if (u==pre||u==rt) continue;
		if (u<pre){
			dp[k]=1ll*dp[k]*C(sz[k]+sz[u],sz[u])%mod*dp[u]%mod;
			sz[k]+=sz[u];
		}
		else{
			ssr=1ll*ssr*C(siz+sz[u],sz[u])%mod*dp[u]%mod;
			siz+=sz[u];
		}
	}
	sz[k]++;
}

void solve(int x,int &res,int &ns){
	int i,j,k,st=0;
	ns=0; res=0;
	bfs(x);
	ns=t; m=0; h=t=0;
	for (i=1;i<=ns;i++){
		k=q[i];
		for (j=head[k];j;j=mem[j].next) m++;
		if (d[k]==1) tp[++t]=k;
	}
	if (m/2!=ns) return;
	topsort(); t=0;
	for (i=1;i<=ns;i++)
		if (d[q[i]]>1&&q[i]>st) st=q[i];
	for (j=head[st];j;j=mem[j].next)
		if (d[mem[j].to]>1) tp[++t]=mem[j].to;
	for (i=1;i<=t;i++){
		k=tp[i]; ssr=1; siz=0;
		dfs(st,k,st);
		ssr=1ll*ssr*C(siz+sz[st],sz[st])%mod*dp[st]%mod;
		add(res,ssr);
	}
}

int main(){
	int i;
	scanf("%d",&n);
	for (i=1;i<=2*n;i++){
		scanf("%d%d",&x,&y);
		addedge(x,y+n); addedge(y+n,x);
	}
	init(n*2);
	ans=1;
	for (i=1;i<=n;i++)
		if (!vis[i]){
			solve(i,res,ns);
			ans=1ll*ans*C(sum+ns,ns)%mod*res%mod;
			sum+=ns;
		}
	printf("%d\n",ans);
	return 0;
}