#include<stdio.h>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
ll mod = 1000000007;
#define SIZE 200000
class unionfind
{
public:
	int par[SIZE];
	int ran[SIZE];
	int ren[SIZE];
	void init()
	{
		for (int i = 0; i<SIZE; i++)
		{
			par[i] = i;
			ran[i] = 0;
			ren[i] = 1;
		}
	}
	int find(int a)
	{
		if (a == par[a])return a;
		else return par[a] = find(par[a]);
	}
	void unite(int a, int b)
	{
		a = find(a);
		b = find(b);
		if (a == b)return;
		if (ran[a]>ran[b])
		{
			par[b] = a;
			ren[a] += ren[b];
		}
		else
		{
			par[a] = b;
			ren[b] += ren[a];
		}
		if (ran[a] == ran[b])ran[b]++;
	}
};
unionfind uf;
#define SIZE 300000
ll inv[SIZE + 1];
ll kai[SIZE + 1];
ll invkai[SIZE + 1];
void invinit()
{
	inv[1] = 1;
	for (int i = 2; i <= SIZE; i++)
	{
		inv[i] = mod - (mod / i)*inv[mod%i] % mod;
	}
	kai[0] = invkai[0] = 1;
	for (int i = 1; i <= SIZE; i++)
	{
		kai[i] = kai[i - 1] * i%mod;
		invkai[i] = invkai[i - 1] * inv[i] % mod;
	}
}
ll com(ll a, ll b)
{
	if (b < 0 || a < b)return 0;
	return (invkai[b] * invkai[a - b]) % mod*kai[a] % mod;
}
vector<int>pat[200000];
typedef pair<int, int>pii;
bool flag[200000];
vector<int>nowp;
vector<int>nowcirc;
void dfs(int node, int s, int p)
{
	if (flag[node])
	{
		if (s == node)nowcirc = nowp;
		return;
	}
	flag[node] = true;
	nowp.push_back(node);
	for (int i = 0; i < pat[node].size(); i++)
	{
		if (pat[node][i] != p)dfs(pat[node][i], s, node);
	}
	nowp.pop_back();
}
void no()
{
	printf("0\n");
	exit(0);
}
int pt = 0;
vector<int>ko[1000000];
int indeg[1000000];
map<pii, int>idx;
void dfs2(int x, int y, int d, int p)
{
	idx[make_pair(x, y)] = p;
	//printf("%d %d   %d %d\n", x/2 + 1, y/2 + 1, idx[make_pair(x, y)], d);
	if (d == 0)
	{
		for (int i = 0; i < pat[x].size(); i++)
		{
			pii z = make_pair(x, pat[x][i]);
			if (idx.count(z) == 0)
			{
				pt++;
				idx[z] = pt;
				if (pat[x][i] < y)
				{
					ko[p].push_back(pt);
					indeg[pt]++;
				}
				dfs2(x, pat[x][i], 1 ^ d, pt);
			}
		}
	}
	else
	{
		for (int i = 0; i < pat[y].size(); i++)
		{
			pii z = make_pair(pat[y][i], y);
			if (idx.count(z) == 0)
			{
				pt++;
				idx[z] = pt;
				if (pat[y][i] < x)
				{
					ko[p].push_back(pt);
					indeg[pt]++;
				}
				dfs2(pat[y][i], y, 1 ^ d, pt);
			}
		}
	}
}
pair<ll, ll>dfs3(int node)
{
	ll x = 1;
	int sum = 0;
	for (int i = 0; i < ko[node].size(); i++)
	{
		pair<ll, ll>t = dfs3(ko[node][i]);
		x = x*t.first%mod*com(sum + t.second, sum) % mod;
		sum += t.second;
	}
	return make_pair(x, sum + 1);
}
pair<ll, ll>solve(vector<int>circ, int mode)
{
	//for (int i = 0; i < circ.size(); i++)printf("%d ", circ[i]); printf("\n");
	pii maxi = make_pair(-1, -1);
	for (int i = 0; i < circ.size(); i++)
	{
		pii t;
		if (circ[i] % 2 == 0)t = make_pair(circ[i], circ[(i + 1) % circ.size()]);
		else t = make_pair(circ[(i + 1) % circ.size()], circ[i]);
		if (maxi < t)maxi = t;
	}
	pt++;
	int st = pt;
	dfs2(maxi.first, maxi.second, mode, pt);
	ll ans = 1;
	int sum = 0;
	for (int i = st; i <= pt; i++)
	{
		if (indeg[i] == 0)
		{
			pair<ll, ll>z = dfs3(i);
			ans = ans*z.first%mod*com(sum + z.second, sum) % mod;
			sum += z.second;
		}
	}
	return make_pair(ans, sum);
}
int main()
{
	int num;
	scanf("%d", &num);
	uf.init();
	invinit();
	vector<pii>circe;
	for (int i = 0; i < num + num; i++)
	{
		int za, zb;
		scanf("%d%d", &za, &zb);
		za--, zb--;
		za *= 2, zb *= 2, zb++;
		pat[za].push_back(zb);
		pat[zb].push_back(za);
		if (uf.find(za) == uf.find(zb))circe.push_back(make_pair(za, zb));
		uf.unite(za, zb);
	}
	for (int i = 0; i < num + num; i++)sort(pat[i].begin(), pat[i].end());
	vector<vector<int> >vec;
	for (int i = 0; i < circe.size(); i++)
	{
		if (flag[circe[i].first])no();
		dfs(circe[i].first, circe[i].first, circe[i].second);
		vec.push_back(nowcirc);
	}
	fill(flag, flag + num + num, false);
	ll ans = 1;
	int sum = 0;
	for (int i = 0; i < vec.size(); i++)
	{
		idx.clear();
		pair<ll, ll>a = solve(vec[i], 0);
		idx.clear();
		pair<ll, ll>b = solve(vec[i], 1);
		ans = ans*(a.first + b.first) % mod*com(sum + a.second, sum) % mod;
		sum += a.second;
	}
	printf("%lld\n", ans);
}

Measured memory_bytes: 74448