#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> a) {
  out << a.first << " " << a.second;
  return out;
}
template <typename T, typename T1>
T amax(T &a, T1 b) {
  if (b > a) a = b;
  return a;
}
template <typename T, typename T1>
T amin(T &a, T1 b) {
  if (b < a) a = b;
  return a;
}
const long long INF = 1e18;
const int32_t M = 1e9 + 7;
const int32_t MM = 998244353;
template <int32_t MOD>
struct mod_field {
  int32_t val;
  mod_field(long long v = 0) {
    if (v < 0) v = v % MOD + MOD;
    if (v >= MOD) v %= MOD;
    val = v;
  }
  static int32_t mod_inv(int32_t a, int32_t m = MOD) {
    int32_t g = m, r = a, x = 0, y = 1;
    while (r != 0) {
      int32_t q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }
    return x < 0 ? x + m : x;
  }
  static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
    return x % m;
    unsigned x_high = x >> 32, x_low = (unsigned)x;
    unsigned quot, rem;
    asm("divl %4\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }
  explicit operator long long() const { return val; }
  mod_field &operator+=(const mod_field &other) {
    val += other.val;
    if (val >= MOD) val -= MOD;
    return *this;
  }
  mod_field &operator-=(const mod_field &other) {
    val -= other.val;
    if (val < 0) val += MOD;
    return *this;
  }
  mod_field &operator*=(const mod_field &other) {
    val = fast_mod((uint64_t)val * other.val);
    return *this;
  }
  mod_field &operator/=(const mod_field &other) { return *this *= other.inv(); }
  friend mod_field operator+(const mod_field &a, const mod_field &b) {
    return mod_field(a) += b;
  }
  friend mod_field operator-(const mod_field &a, const mod_field &b) {
    return mod_field(a) -= b;
  }
  friend mod_field operator*(const mod_field &a, const mod_field &b) {
    return mod_field(a) *= b;
  }
  friend mod_field operator/(const mod_field &a, const mod_field &b) {
    return mod_field(a) /= b;
  }
  mod_field &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }
  mod_field &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }
  mod_field operator++(int32_t) {
    mod_field before = *this;
    ++*this;
    return before;
  }
  mod_field operator--(int32_t) {
    mod_field before = *this;
    --*this;
    return before;
  }
  mod_field operator-() const { return val == 0 ? 0 : MOD - val; }
  bool operator==(const mod_field &other) const { return val == other.val; }
  bool operator!=(const mod_field &other) const { return val != other.val; }
  mod_field inv() const { return mod_inv(val); }
  friend ostream &operator<<(ostream &stream, const mod_field &m) {
    return stream << m.val;
  }
  friend istream &operator>>(istream &stream, mod_field &m) {
    return stream >> m.val;
  }
  mod_field pow(long long p) const {
    assert(p >= 0);
    mod_field a = *this, result = 1;
    while (p > 0) {
      if (p & 1) result *= a;
      a *= a;
      p >>= 1;
    }
    return result;
  }
};
const long long N = 2e5 + 5;
vector<long long> g[N];
vector<long long> gr[N];
bool used[N], cyc[N];
vector<long long> order, component;
void dfs1(long long v) {
  used[v] = true;
  for (size_t i = 0; i < g[v].size(); ++i)
    if (!used[g[v][i]]) dfs1(g[v][i]);
  order.push_back(v);
}
void dfs2(long long v) {
  used[v] = true;
  component.push_back(v);
  for (size_t i = 0; i < gr[v].size(); ++i)
    if (!used[gr[v][i]]) dfs2(gr[v][i]);
}
mod_field<M> dfs(long long z) {
  mod_field<M> ans = 1;
  for (long long x : gr[z]) {
    ans += dfs(x);
  }
  return ans;
}
void solve() {
  long long n;
  cin >> n;
  for (long long i = 0; i < n; i++) {
    long long x, y;
    cin >> x >> y;
    g[x].push_back(y);
    gr[y].push_back(x);
  }
  n *= 2;
  memset(used, 0, sizeof(used));
  for (long long i = 1; i < n + 1; i++) {
    if (!used[i]) dfs1(i);
  }
  memset(used, 0, sizeof(used));
  mod_field<M> ans = 1;
  for (long long i = 1; i < n + 1; i++) {
    long long v = order[n - i];
    if (!used[v]) {
      dfs2(v);
      if ((long long)((component).size()) > 1) {
        for (long long x : component) {
          cyc[x] = 1;
        }
        ans *= 2;
      }
      component.clear();
    }
  }
  for (long long i = 1; i < n + 1; i++) {
    if ((long long)((g[i]).size()) == 0) {
      ans *= dfs(i);
    }
  }
  cout << ans;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long t = 1;
  while (t--) solve();
  return 0;
}

### Prompt

Please provide a cpp coded solution to the problem described below:

A new set of desks just arrived, and it's about time! Things were getting quite cramped in the office. You've been put in charge of creating a new seating chart for the engineers. The desks are numbered, and you sent out a survey to the engineering team asking each engineer the number of the desk they currently sit at, and the number of the desk they would like to sit at (which may be the same as their current desk). Each engineer must either remain where they sit, or move to the desired seat they indicated in the survey. No two engineers currently sit at the same desk, nor may any two engineers sit at the same desk in the new seating arrangement.

How many seating arrangements can you create that meet the specified requirements? The answer may be very large, so compute it modulo 1000000007 = 109 + 7.

Input

Input will begin with a line containing N (1 ≤ N ≤ 100000), the number of engineers. 

N lines follow, each containing exactly two integers. The i-th line contains the number of the current desk of the i-th engineer and the number of the desk the i-th engineer wants to move to. Desks are numbered from 1 to 2·N. It is guaranteed that no two engineers sit at the same desk.

Output

Print the number of possible assignments, modulo 1000000007 = 109 + 7.

Examples

Input

4
1 5
5 2
3 7
7 3


Output

6


Input

5
1 10
2 10
3 10
4 10
5 5


Output

5

Note

These are the possible assignments for the first example: 

  * 1 5 3 7 
  * 1 2 3 7 
  * 5 2 3 7 
  * 1 5 7 3 
  * 1 2 7 3 
  * 5 2 7 3 

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> a) {
  out << a.first << " " << a.second;
  return out;
}
template <typename T, typename T1>
T amax(T &a, T1 b) {
  if (b > a) a = b;
  return a;
}
template <typename T, typename T1>
T amin(T &a, T1 b) {
  if (b < a) a = b;
  return a;
}
const long long INF = 1e18;
const int32_t M = 1e9 + 7;
const int32_t MM = 998244353;
template <int32_t MOD>
struct mod_field {
  int32_t val;
  mod_field(long long v = 0) {
    if (v < 0) v = v % MOD + MOD;
    if (v >= MOD) v %= MOD;
    val = v;
  }
  static int32_t mod_inv(int32_t a, int32_t m = MOD) {
    int32_t g = m, r = a, x = 0, y = 1;
    while (r != 0) {
      int32_t q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }
    return x < 0 ? x + m : x;
  }
  static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
    return x % m;
    unsigned x_high = x >> 32, x_low = (unsigned)x;
    unsigned quot, rem;
    asm("divl %4\n" : "=a"(quot), "=d"(rem) : "d"(x_high), "a"(x_low), "r"(m));
    return rem;
  }
  explicit operator long long() const { return val; }
  mod_field &operator+=(const mod_field &other) {
    val += other.val;
    if (val >= MOD) val -= MOD;
    return *this;
  }
  mod_field &operator-=(const mod_field &other) {
    val -= other.val;
    if (val < 0) val += MOD;
    return *this;
  }
  mod_field &operator*=(const mod_field &other) {
    val = fast_mod((uint64_t)val * other.val);
    return *this;
  }
  mod_field &operator/=(const mod_field &other) { return *this *= other.inv(); }
  friend mod_field operator+(const mod_field &a, const mod_field &b) {
    return mod_field(a) += b;
  }
  friend mod_field operator-(const mod_field &a, const mod_field &b) {
    return mod_field(a) -= b;
  }
  friend mod_field operator*(const mod_field &a, const mod_field &b) {
    return mod_field(a) *= b;
  }
  friend mod_field operator/(const mod_field &a, const mod_field &b) {
    return mod_field(a) /= b;
  }
  mod_field &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }
  mod_field &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }
  mod_field operator++(int32_t) {
    mod_field before = *this;
    ++*this;
    return before;
  }
  mod_field operator--(int32_t) {
    mod_field before = *this;
    --*this;
    return before;
  }
  mod_field operator-() const { return val == 0 ? 0 : MOD - val; }
  bool operator==(const mod_field &other) const { return val == other.val; }
  bool operator!=(const mod_field &other) const { return val != other.val; }
  mod_field inv() const { return mod_inv(val); }
  friend ostream &operator<<(ostream &stream, const mod_field &m) {
    return stream << m.val;
  }
  friend istream &operator>>(istream &stream, mod_field &m) {
    return stream >> m.val;
  }
  mod_field pow(long long p) const {
    assert(p >= 0);
    mod_field a = *this, result = 1;
    while (p > 0) {
      if (p & 1) result *= a;
      a *= a;
      p >>= 1;
    }
    return result;
  }
};
const long long N = 2e5 + 5;
vector<long long> g[N];
vector<long long> gr[N];
bool used[N], cyc[N];
vector<long long> order, component;
void dfs1(long long v) {
  used[v] = true;
  for (size_t i = 0; i < g[v].size(); ++i)
    if (!used[g[v][i]]) dfs1(g[v][i]);
  order.push_back(v);
}
void dfs2(long long v) {
  used[v] = true;
  component.push_back(v);
  for (size_t i = 0; i < gr[v].size(); ++i)
    if (!used[gr[v][i]]) dfs2(gr[v][i]);
}
mod_field<M> dfs(long long z) {
  mod_field<M> ans = 1;
  for (long long x : gr[z]) {
    ans += dfs(x);
  }
  return ans;
}
void solve() {
  long long n;
  cin >> n;
  for (long long i = 0; i < n; i++) {
    long long x, y;
    cin >> x >> y;
    g[x].push_back(y);
    gr[y].push_back(x);
  }
  n *= 2;
  memset(used, 0, sizeof(used));
  for (long long i = 1; i < n + 1; i++) {
    if (!used[i]) dfs1(i);
  }
  memset(used, 0, sizeof(used));
  mod_field<M> ans = 1;
  for (long long i = 1; i < n + 1; i++) {
    long long v = order[n - i];
    if (!used[v]) {
      dfs2(v);
      if ((long long)((component).size()) > 1) {
        for (long long x : component) {
          cyc[x] = 1;
        }
        ans *= 2;
      }
      component.clear();
    }
  }
  for (long long i = 1; i < n + 1; i++) {
    if ((long long)((g[i]).size()) == 0) {
      ans *= dfs(i);
    }
  }
  cout << ans;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long t = 1;
  while (t--) solve();
  return 0;
}

```