#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

template <typename T>
inline void read(T &x) {
  x = 0; char c = getchar();
  for(; !isdigit(c); c = getchar());
  for(;  isdigit(c); c = getchar())
    x = x * 10 + c - '0';
}

const int N = 2e5 + 50;
const int mod = 1e9 + 7;

# define pb push_back
# define row(x) ((x) <= n ? 1 : 0)
# define inv(x) (mul(ifac[(x)], fac[(x) - 1]))

int n, x, y, ans = 1, idx, dp[N], fac[N], ifac[N];
int arr[N], vl[N], fa[N], dfn[N], loop[N];
vector<int> g[N], E;

inline void add(int &a, int b) {
  a += b; if(a >= mod) a -= mod;
}
inline int mul(int a, int b) {
  return (LL) a * b % mod;
}
inline int Pow(int a, int b) {
  int r = 1;
  for(; b; b >>= 1, a = mul(a, a))
    if(b & 1) r = mul(r, a);  
  return r;
}
void pre() {
  fac[0] = 1;
  for(int i = 1; i <= 2 * n; ++i)
    fac[i] = mul(fac[i - 1], i);
  ifac[2 * n] = Pow(fac[2 * n], mod - 2);
  for(int i = 2 * n - 1; ~i; --i)
    ifac[i] = mul(ifac[i + 1], i + 1);
}
namespace jud {
  int cntn, cnte, vis[N];
  
  void dfs(int u) {
    vis[u] = 1;
    ++cntn;
    cnte += g[u].size();
    for(auto v : g[u]) {
      if(vis[v]) continue;
      dfs(v);
    }
  }
  void main(int u) {
    cntn = cnte = 0;
    dfs(u);
    cnte >>= 1;
    if(cntn != cnte) {
      puts("0");
      exit(0);
    }
  }
}
void dfs(int u) {
  static int icnt = 0;
  E.pb(u);
  dfn[u] = ++icnt;
  for(auto v : g[u]) {
    if(v == fa[u]) continue;
    if(!dfn[v]) {
      fa[v] = u;
      dfs(v);
    } else {
      if(dfn[u] > dfn[v]) continue;
      loop[++idx] = v;
      for(int i = v; i != u; i = fa[i])
        loop[++idx] = fa[i];
    }
  }
}
void Dfs(int u, int fa = 0) {
  for(auto v : g[u]) {
    if(v == fa || vl[v]) continue;
    Dfs(v, u);
    dp[v] = 1;
    for(auto x : g[v]) {
      if(x > u) continue;
      dp[v] += dp[x];
    }
  }
}
void calc(int u) {
  if(dp[arr[u]]) return ;
  int v = arr[u], res = 1;
  for(auto x : g[v]) {
    if(vl[x] || x > u) continue;
    res += dp[x];
  }
  if(arr[v] < u) {
    calc(v);
    res += dp[arr[v]];
  } 
  return (void) (dp[v] = res);
}
int doit(int step) {
  int res = 1;
  loop[0] = loop[idx];
  loop[idx + 1] = loop[1];
  int s = (step > 0) ? 1 : idx;
  for(; s && s <= idx; s += step) 
    arr[loop[s]] = loop[s + step];
  for(int i = 1; i <= idx; ++i) dp[loop[i]] = 0;
  for(int i = 1; i <= idx; ++i)
    calc(loop[i]);
  for(auto node : E) 
    res = mul(res, inv(dp[node]));
  return res;
}
int solve(int U) {
  jud :: main(U);
  E.clear();
  idx = 0, dfs(U);
  for(int i = 1; i <= idx; ++i) 
    vl[loop[i]] = 1;
  for(int i = 1; i <= idx; ++i)
    Dfs(loop[i]); 
  //for(int i = 1; i <= idx; ++i)
  //   cout << loop[i] << ' '; puts("");
  int ans = doit(1) + doit(-1);
  if(ans >= mod) ans -= mod;
  return ans;
}

int main() {
  read(n);
  pre();
  for(int i = 1; i <= 2 * n; ++i) {
    read(x), read(y);
    g[x].pb(y + n);
    g[y + n].pb(x);
  }
  for(int i = 1; i <= n; ++i)
    if(!jud :: vis[i]) ans = mul(ans, solve(i));
  printf("%d\n", mul(ans, fac[2 * n]));
  return 0;
}