#include <queue>
#include <cstdio>
#include <algorithm>
#include<bits/stdc++.h> 
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while ((ch < '0') || (ch > '9'))
    {
        if (ch == '-')
        {
            f = -f;
        }
        ch = getchar();
    }
    while ((ch >= '0') && (ch <= '9'))
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int maxn = 100000;
const int maxv = maxn * 2;
const int maxe = maxv * 2;
const int mod = 1000000007;

std::queue<int> q;
std::vector<int> cur;
int n, pre[maxe + 10], now[maxv + 10], son[maxe + 10], tot, _pre[maxe + 10], _now[maxv + 10], _son[maxe + 10], _tot, vis[maxv + 10], ecnt, cir[maxv + 10], deg[maxv + 10], choose[maxv + 10], fac[maxv + 10], ifac[maxv + 10], f[maxv + 10], size[maxv + 10];

int C(int a, int b)
{
    return 1ll * fac[a] * ifac[b] % mod * ifac[a - b] % mod;
}

int _ins(int a, int b)
{
    _pre[++_tot] = _now[a];
    _now[a] = _tot;
    _son[_tot] = b;
    return 0;
}

int calc()
{
    for (auto i : cur)
    {
        deg[i] = _now[i] = 0;
    }
    for (auto i : cur)
    {
        for (int j = now[i]; j; j = pre[j])
        {
            int v = son[j];
            if (v < choose[i])
            {
                _ins(v, i);
                ++deg[i];
            }
        }
    }
    for (auto i : cur)
    {
        if (!deg[i])
        {
            q.push(i);
        }
        f[i] = 1;
        size[i] = 1;
    }
    int sz = 0, ans = 1;
    while (!q.empty())
    {
        int u = q.front(), flag = 0;
        q.pop();
        for (int i = _now[u]; i; i = _pre[i])
        {
            flag = 1;
            int v = _son[i];
            --deg[v];
            size[v] += size[u];
            f[v] = 1ll * f[v] * f[u] % mod * C(size[v] - 1, size[u]) % mod;
            if (!deg[v])
            {
                q.push(v);
            }
        }
        if (!flag)
        {
            sz += size[u];
            ans = 1ll * ans * f[u] % mod * C(sz, size[u]) % mod;
        }
    }
    return ans;
}

int ins(int a, int b)
{
    pre[++tot] = now[a];
    now[a] = tot;
    son[tot] = b;
    return 0;
}

int dfs(int u)
{
    vis[u] = 1;
    cur.push_back(u);
    for (int i = now[u]; i; i = pre[i])
    {
        ++ecnt;
        int v = son[i];
        if (!vis[v])
        {
            dfs(v);
        }
    }
    return 0;
}

int search(int u)
{
    cir[++cir[0]] = u;
    vis[u] = 1;
    for (int i = now[u]; i; i = pre[i])
    {
        int v = son[i];
        if (!vis[v])
        {
            search(v);
        }
    }
    return 0;
}

int solve()
{
    if ((int)cur.size() != ecnt)
    {
        return 0;
    }
    for (auto i : cur)
    {
        if (deg[i] == 1)
        {
            q.push(i);
        }
    }
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = now[u]; i; i = pre[i])
        {
            int v = son[i];
            if (deg[v] != 1)
            {
                --deg[v];
                choose[u] = v;
                if (deg[v] == 1)
                {
                    q.push(v);
                }
            }
        }
    }
    int st = 0;
    for (auto i : cur)
    {
        if (deg[i] > 1)
        {
            st = i;
            vis[i] = 0;
        }
    }
    cir[0] = 0;
    search(st);
    cir[cir[0] + 1] = cir[1];
    for (int i = 1; i <= cir[0]; ++i)
    {
        choose[cir[i]] = cir[i + 1];
    }
    int res = calc();
    for (int i = 2; i <= cir[0] + 1; ++i)
    {
        choose[cir[i]] = cir[i - 1];
    }
    res += calc();
    if (res >= mod)
    {
        res -= mod;
    }
    for (auto i : cur)
    {
        vis[i] = 1;
    }
    return res;
}

int main()
{
    n = read();
    fac[0] = 1;
    for (int i = 1; i <= n << 1; ++i)
    {
        fac[i] = 1ll * fac[i - 1] * i % mod;
    }
    ifac[0] = ifac[1] = 1;
    for (int i = 2; i <= n << 1; ++i)
    {
        ifac[i] = 1ll * (mod - mod / i) * ifac[mod % i] % mod;
    }
    for (int i = 2; i <= n << 1; ++i)
    {
        ifac[i] = 1ll * ifac[i - 1] * ifac[i] % mod;
    }
    for (int i = 1; i <= n << 1; ++i)
    {
        int x = read(), y = read();
        ins(x, y + n);
        ins(y + n, x);
        ++deg[x];
        ++deg[y + n];
    }
    int tsize = 0, ans = 1;
    for (int i = 1; i <= n << 1; ++i)
    {
        if (!vis[i])
        {
            cur.clear();
            ecnt = 0;
            dfs(i);
            ecnt /= 2;
            int res = solve();
            tsize += ecnt;
            ans = 1ll * ans * res % mod * C(tsize, ecnt) % mod;
        }
    }
    printf("%d\n", ans);
    return 0;
}


Measured memory_bytes: 17268