#include <bits/stdc++.h>
using namespace std;
const int INF = (int)2e9 + 7;
const long double EPS = (long double)1e-5;
const int BASE = (int)1e9 + 7;
const int MAXN = 200500;
const long long INFLL = (long long)1e18;
int n;
int p[MAXN];
int to[MAXN];
int szin[MAXN], szout[MAXN];
set<int> g[MAXN];
bool used[MAXN];
bool is_loop[MAXN];
int get(int v) { return v == p[v] ? v : p[v] = get(p[v]); }
void unit(int a, int b) {
  a = get(a);
  b = get(b);
  if (a != b) {
    if (is_loop[a]) {
      p[b] = a;
      return;
    }
    if (is_loop[b]) {
      p[a] = b;
      return;
    }
    if (rand() & 1) swap(a, b);
    p[a] = b;
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= 2 * n; i++) p[i] = i;
  for (int i = 1; i <= n; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    if (a == b) {
      is_loop[a] = true;
      is_loop[get(a)] = true;
      continue;
    }
    to[a] = b;
    szin[b]++;
    szout[a]++;
    unit(a, b);
    used[a] = used[b] = true;
  }
  for (int i = 1; i <= 2 * n; i++) {
    if (!used[i]) continue;
    int pred = get(i);
    g[pred].insert(i);
  }
  long long ans = 1;
  queue<int> q;
  for (int i = 1; i <= 2 * n; i++) {
    while (!q.empty()) q.pop();
    if (g[i].empty()) continue;
    if (is_loop[i]) {
      continue;
    }
    if (g[i].size() == 2) {
      ans = (1ll * ans * 2) % BASE;
      continue;
    }
    int cur = (int)g[i].size();
    for (int v : g[i]) {
      if (szout[v] == 1 && szin[v] == 0) q.push(v);
    }
    while (!q.empty()) {
      int v = q.front();
      g[i].erase(v);
      q.pop();
      szout[v]--;
      szin[to[v]]--;
      if (szin[to[v]] == 0 && szout[to[v]] == 1) q.push(to[v]);
      if (szin[to[v]] == 0 && szout[to[v]] == 0) g[i].erase(to[v]);
    }
    if (g[i].empty())
      ans = (1ll * ans * cur) % BASE;
    else
      ans = (1ll * ans * 2) % BASE;
  }
  cout << ans;
  return 0;
}
