#include<bits/stdc++.h>
using namespace std;
#define mo 1000000007
#define M 400005
#define ll long long
int read() {
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
ll ksm(ll a,int k) {
	ll s=1;
	while(k)
	{
		if(k&1) s=s*a%mo;
		a=a*a%mo;
		k>>=1;
	}
	return s;
}
struct edge{
	int t,nxt;
}a[M*2],e[M*2];
int h1[M],t1,h2[M],t2,du[M];
void add(int st,int t) {
	a[++t1].nxt=h1[st],a[t1].t=t,h1[st]=t1;
	du[st]++,du[t]++;
}
void Add(int st,int t) {
	e[++t2].nxt=h2[st],e[t2].t=t,h2[st]=t2;
}
int n;
ll ans=1,jc[M];
int col[M];
void dfs1(int x,int fa) {
	if(col[x]) return ;
	col[x]=1;
	for(int i=h1[x];i;i=a[i].nxt)
	{
		int to=a[i].t;
		if(to==fa) continue ;
		dfs1(to,x);
	}
}
int findl;
int vis[M],sta[M],top,cir[M],tp[M],cnt,tol[M],cnt2;
void dfs2_2(int x) {
	vis[x]=1,tol[++cnt2]=x;
	for(int i=h1[x];i;i=a[i].nxt)
	{
		int to=a[i].t;
		if(vis[to]) continue ;
		dfs2_2(to);
	}
}
void dfs2(int x,int fa) {
	if(vis[x]&&!findl)
	{
		findl=1;
		int p=top;
		while(sta[p+1]!=x) cir[++cnt]=sta[p--],tp[cir[cnt]]=1;
		return ;
	}
	if(vis[x]) return ;
	vis[x]=1,sta[++top]=x;
	for(int i=h1[x];i;i=a[i].nxt)
	{
		int to=a[i].t;
		if(to==fa) continue ;
		dfs2(to,x);
		if(findl) return ;
	}
	vis[x]=0,top--;
}
int sz[M],dfn[M];
void dfs3(int x) {
	if(dfn[x]) return ;
	sz[x]=dfn[x]=1;
	for(int i=h2[x];i;i=e[i].nxt)
	{
		int to=e[i].t;
		dfs3(to);
		sz[x]+=sz[to];
	}
}
void dfs4(int x,int fa) {
	for(int i=h1[x];i;i=a[i].nxt)
	{
		int to=a[i].t;
		if(tp[to]||to==fa) continue ;
		if(fa>to) Add(x,to);
		dfs4(to,x);
	}
}
void clear() {
	for(int i=1;i<=cnt2;i++) h2[tol[i]]=dfn[tol[i]]=sz[tol[i]]=0;
	t2=0;
}
void link(int k) {
	if(!k) for(int i=1;i<=cnt;i++) dfs4(cir[i],cir[i+1]);
	else for(int i=1;i<=cnt;i++) dfs4(cir[i],cir[i-1]);
}
ll sol(int s) {
	findl=0;
	ll s1=1,s2=1;
	cnt=cnt2=0;
	dfs2_2(s);
	for(int i=1;i<=cnt2;i++) vis[tol[i]]=0;
	dfs2(s,0);
	cir[0]=cir[cnt],cir[cnt+1]=cir[1],cir[cnt+2]=cir[2];
	link(0);
	for(int i=2;i<=cnt+1;i++) if(cir[i+1]>cir[i-1]) Add(cir[i],cir[i-1]);
	for(int i=1;i<=cnt2;i++) dfs3(tol[i]);
	for(int i=1;i<=cnt2;i++) s1=s1*sz[tol[i]]%mo;
	clear();
	link(1);
	for(int i=2;i<=cnt+1;i++) if(cir[i+1]<cir[i-1]) Add(cir[i],cir[i+1]);
	for(int i=1;i<=cnt2;i++) dfs3(tol[i]);
	for(int i=1;i<=cnt2;i++) s2=s2*sz[tol[i]]%mo;
	clear();
	for(int i=1;i<=cnt;i++) tp[cir[i]]=0;
	for(int i=1;i<=cnt2;i++) vis[tol[i]]=0;
	top=0;
	s1=(ksm(s1,mo-2)+ksm(s2,mo-2))%mo;
	return s1;
}
void work() {
	for(int i=1;i<=n*2;i++)
		if(!col[i])
		{
			dfs1(i,0);
			ans=ans*sol(i)%mo;
		}
	ans=jc[n*2]*ans%mo;
	cout<<ans<<endl;
}
int main()
{
	//freopen("2.in","r",stdin);
	jc[0]=1;
	for(int i=1;i<M;i++) jc[i]=jc[i-1]*i%mo;
	n=read();
	for(int i=1,u,v;i<=n*2;i++)
	{
		u=read();v=read();
		add(u+n,v),add(v,u+n);
	}
	for(int i=1;i<=n*2;i++) if(!du[i]) {cout<<0<<endl;return 0;}
	work();
	return 0;
}