///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//                       _oo0oo_                         //
//                      o8888888o                        //
//                      88" . "88      ------ hzt1       //
//                      (| -_- |)                        //
//                      0\  =  /0                        //
//                    ___/`---'\___                      //
//                  .' \|     |// '.                     //
//                 / \|||  :  |||// \                    //
//                / _||||| -:- |||||- \                  //
//               |   | \  -  /// |     |                 //
//               | \_|  ''\---/''  |_/ |                 //
//               \  .-\__  '-'  ___/-. /                 //
//             ___'. .'  /--.--\  `. .'___               //
//          ."" '<  `.___\_<|>_/___.' >' "".             //
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |           //
//         \  \ `_.   \_ __\ /__ _/   .-` /  /           //
//     =====`-.____`.___ \_____/___.-`___.-'=====        //
//                       `=---='                         //
//                                                       //
//                                                       //
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~       //
//                                                       //
//                 God-He Bless All.                     //
//           This Code Will Never Explode.               //
//                                                       //
//                                                       //
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<vector>
#define pb push_back
#define mp make_pair
#define xx first
#define yy second
#define rep(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;i++)
#define dwn(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;i--)
using namespace std;
const int Size=1<<16;
char buffer[Size],*head,*tail;
inline char Getchar() {
    if(head==tail) {
        int l=fread(buffer,1,Size,stdin);
        tail=(head=buffer)+l;
    }
    if(head==tail) return -1;
    return *head++;
}
inline int read() {
    int x=0,f=1;char c=Getchar();
    for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
    return x*f;
}
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=200010;
const int mod=1000000007;
int n,first[maxn],nxt[maxn<<1],to[maxn<<1],dis[maxn<<1],e;
void Add(int u,int v,int w) {
//	printf("%d -> %d %d\n",u,v,w);
	to[++e]=v;dis[e]=w;nxt[e]=first[u];first[u]=e;
	to[++e]=u;dis[e]=w;nxt[e]=first[v];first[v]=e;
}
int pa[maxn],siz[maxn],es[maxn],vis[maxn];
int findset(int x) {return x==pa[x]?x:pa[x]=findset(pa[x]);}
void GG() {puts("0");exit(0);}
int sta[maxn],cir[maxn],left[maxn],right[maxn],col[maxn],clo,top;
vector<int> s,all;
int dfs(int x,int la) {
	if(vis[x]) {
		while(top) {
			int y=sta[top--];
			cir[y]=1;s.pb(y);
			if(x==y) break;
		}
		return 1;
	}
	vis[x]=++clo;sta[++top]=x;
	for(int i=first[x];i;i=nxt[i]) if((i-1)!=(la-1^1)){
		if(dfs(to[i],i)) return 1;
	}
	top--;
	return 0;
}
void dfsout(int x,int fa) {
	all.pb(x);
	for(int i=first[x];i;i=nxt[i]) if(to[i]!=fa&&!cir[to[i]]) {
		col[to[i]]=dis[i];
		dfsout(to[i],x);
	}
}
int fac[maxn],ifac[maxn],size[maxn];
int C(int a,int b) {return (ll)fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
vector<int> G[maxn];
int deg[maxn],f[maxn];
void dp(int x) {
	f[x]=1;size[x]=0;
	rep(i,0,G[x].size()-1) {
		dp(G[x][i]);
		f[x]=(ll)f[x]*f[G[x][i]]%mod;
		f[x]=(ll)f[x]*ifac[size[G[x][i]]]%mod;
		size[x]+=size[G[x][i]];
	}
	f[x]=(ll)f[x]*fac[size[x]]%mod;
	size[x]++;
}
int work() {
	rep(j,0,all.size()-1) G[all[j]].clear(),deg[all[j]]=0;
	rep(j,0,all.size()-1) {
		int x=all[j];
		for(int i=first[x];i;i=nxt[i]) if(dis[i]<col[x]) G[x].pb(to[i]),deg[to[i]]++;
	}
	int ans=1,cur=0;
	rep(i,0,all.size()-1) if(!deg[all[i]]) {
		dp(all[i]);
		ans=(ll)ans*C(cur+size[all[i]],cur)%mod;
		ans=(ll)ans*f[all[i]]%mod;
		cur+=size[all[i]];
	}
	return ans;
}
int main() {
	n=read();
	ifac[0]=ifac[1]=fac[0]=1;
	rep(i,2,n*2) ifac[i]=(ll)(mod-mod/i)*ifac[mod%i]%mod;
	rep(i,1,n*2) fac[i]=(ll)fac[i-1]*i%mod,ifac[i]=(ll)ifac[i-1]*ifac[i]%mod;
	rep(i,1,n*2) pa[i]=i,siz[i]=1;
	rep(i,1,n*2) {
		int x=read(),y=read(),w=x+y;
		Add(x,y+n,w);
		x=findset(x);y=findset(y+n);
		if(x!=y) {pa[x]=y;siz[y]+=siz[x];es[y]+=es[x];}
		es[y]++;
	}
	int ans=1,cur=0;
	rep(i,1,n*2) if(i==findset(i)) {
		if(siz[i]!=es[i]) GG();
		s.clear();all.clear();dfs(i,0);top=0;
		rep(j,0,s.size()-1) {
			dfsout(s[j],0);
			int prev=((!j)?s[s.size()-1]:s[j-1]);
			int nxtv=(j==s.size()-1?s[0]:s[j+1]);
			for(int k=first[s[j]];k;k=nxt[k]) {
				if(to[k]==prev) left[s[j]]=dis[k];
				if(to[k]==nxtv) right[s[j]]=dis[k];
			}
		}
		ans=(ll)ans*C(cur+all.size(),cur)%mod;
		cur+=all.size();
		int tmp=0;
		rep(j,0,s.size()-1) col[s[j]]=left[s[j]];
		(tmp+=(ll)work()*ans%mod)%=mod;
		rep(j,0,s.size()-1) col[s[j]]=right[s[j]];
		(tmp+=(ll)work()*ans%mod)%=mod;
		ans=tmp;
	}
	printf("%d\n",ans);
	return 0;
}

Measured memory_bytes: 27124