#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
int n,fa[SZ]; Edg
ll fac[SZ],rfac[SZ];
const int MOD=1e9+7;
namespace Topo
{
Edg
bool ro[SZ];
int sz[SZ];
ll wo(int x)
{
	sz[x]=0; ll ans=1;
	for esb(x,e,b)
	{
		ans*=wo(b); ans%=MOD;
		sz[x]+=sz[b];
		ans=ans*fac[sz[x]]%MOD*
		rfac[sz[b]]%MOD*rfac[sz[x]-sz[b]]%MOD;
	}
	++sz[x]; return ans;
}
}
bool vis[SZ];
vector<int> cm,cyc;
int edg=0,cx,cyy,ys[SZ];
void dfs(int x)
{
	vis[x]=1; cm.pb(x);
	for esb(x,e,b) ++edg;
	for esb(x,e,b) if(!vis[b])
	{
		fa[b]=x; dfs(b);
	}
	else
	{
		if(b!=fa[x]) cx=x,cyy=b;
	}
}
bool cy[SZ]; int ff[SZ];
void d2(int x,int f=0)
{
	for esb(x,e,b) if(b!=f&&!cy[b])
	{
		ff[b]=x; d2(b,x);
	}
}
int vv[SZ],pp=0;
ll qp(ll a,ll b)
{
	ll x=1;
	while(b)
	{
		if(b&1) x=x*a%MOD;
		a=a*a%MOD; b>>=1;
	}
	return x;
}
int main()
{
	fac[0]=1;
	for(int i=1;i<SZ;++i) fac[i]=fac[i-1]*i%MOD;
	rfac[SZ-1]=qp(fac[SZ-1],MOD-2);
	for(int i=SZ-1;i>=1;--i)
		rfac[i-1]=rfac[i]*i%MOD;
	scanf("%d",&n);
	for(int i=1;i<=n+n;++i)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		adde(a,b+n);
	}
	ll ans=1; int ss=0;
	for(int i=1;i<=n+n;++i) if(!vis[i])
	{
		cm.clear(); cyc.clear(); fa[i]=0; edg=0; dfs(i);
		if(edg!=cm.size()*2)
		{
			puts("0");
			return 0;
		}
		++pp;
		for(int a=cx;a;a=fa[a]) vv[a]=pp;
		int rs=0; vector<int> ts;
		for(int a=cyy;a;a=fa[a])
		{
			ts.pb(a);
			if(vv[a]==pp) {rs=a; break;}
		}
		for(int a=cx;a!=rs;a=fa[a])
			cyc.pb(a);
		for(int i=int(ts.size())-1;i>=0;--i)
			cyc.pb(ts[i]);
		for(auto s:cyc) cy[s]=1;
		for(auto s:cyc) d2(s);
		for(auto g:cm) if(!cy[g])
			ys[g]=ff[g];
		ll a1=1,a2=1;
		for(int i=0;i<cyc.size();++i)
			ys[cyc[i]]=cyc[(i+1)%cyc.size()];
		for(auto s:cm) Topo::fst[s]=0,Topo::ro[s]=1;
		for(auto x:cm)
			for esb(x,e,b) if(b<ys[x])
				Topo::ad_de(x,b),Topo::ro[b]=0;
		int sp;
		sp=0;
		for(auto x:cm)
			if(Topo::ro[x])
			{
				a1=a1*Topo::wo(x)%MOD;
				int s=Topo::sz[x]; sp+=s;
				a1=a1*fac[sp]%MOD*rfac[s]%MOD
				*rfac[sp-s]%MOD;
			}
		for(int i=0;i<cyc.size();++i)
			ys[cyc[(i+1)%cyc.size()]]=cyc[i];
		for(auto s:cm) Topo::fst[s]=0,Topo::ro[s]=1;
		for(auto x:cm)
			for esb(x,e,b) if(b<ys[x])
				Topo::ad_de(x,b),Topo::ro[b]=0;
		sp=0;
		for(auto x:cm)
			if(Topo::ro[x])
			{
				a2=a2*Topo::wo(x)%MOD;
				int s=Topo::sz[x]; sp+=s;
				a2=a2*fac[sp]%MOD*rfac[s]%MOD
				*rfac[sp-s]%MOD;
			}
		ans=ans*(a1+a2)%MOD;
		int cs=cm.size(); ss+=cs;
		ans=ans*fac[ss]%MOD*rfac[cs]%MOD*rfac[ss-cs]%MOD;
	}
	ans=(ans%MOD+MOD)%MOD;
	cout<<ans<<"\n";
}


Measured memory_bytes: 42740