#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>

using namespace std;

typedef long long ll;

const int MOD = 1e9 + 7; // change if needed

struct Modint {
  ll val;
  
  Modint (ll _val = 0)
    : val(_val % MOD) {}

  Modint operator+ (Modint other) const {
    return Modint(val + other.val);
  }

  void operator+= (Modint other) {
    val += other.val;
    val %= MOD;
  }

  Modint operator- () const {
    return Modint(MOD - val);
  }

  Modint operator- (Modint other) const {
    return Modint(val + MOD - other.val);
  }

  void operator-= (Modint other) {
    val += MOD - other.val;
    val %= MOD;
  }

  Modint operator* (Modint other) const {
    return Modint(val * other.val);
  }

  void operator*= (Modint other) {
    val *= other.val;
    val %= MOD;
  }

  bool operator== (Modint other) const {
    return val == other.val;
  }

  bool operator!= (Modint other) const {
    return val != other.val;
  }
};

Modint exp (Modint a, int k) {
  if (k == 0) {
    return Modint(1);
  } else if (k % 2 == 0) {
    Modint half = exp(a, k / 2);
    return half * half;
  } else {
    return a * exp(a, k - 1);
  }
}

Modint inv (Modint a) {
  return exp(a, MOD - 2);
}

ostream& operator<< (ostream& out, Modint p) {
  out << p.val;
  return out;
}

void failure () {
  cout << 0 << endl;
  exit(0);
}

const int MAX_N = 1 << 17;

int arr [MAX_N];
vector<int> ins [MAX_N];

int on_cyc [MAX_N];
deque<int> cyc [MAX_N];

int vis [MAX_N];
deque<int> stk;
void find_cyc (int u, int src) {
  if (vis[u] != 0 && vis[u] != src) return;

  if (vis[u]) {
    while (stk.front() != u) stk.pop_front();
    cyc[src] = stk;
    stk.clear();

    for (int v : cyc[src]) {
      on_cyc[v] = src;
    }
    return;
  }

  vis[u] = src;
  stk.push_back(u);
  find_cyc(arr[u], src);
}

int stem [MAX_N];
void find_stem (int u, int src) {
  if (on_cyc[u]) {
    if (ins[u].size() > 2) failure();
    
    for (int nxt : ins[u]) {
      if (!on_cyc[nxt]) {
        find_stem(nxt, src);
      }
    }
  } else {
    stem[src]++;
    
    if (ins[u].size() > 1) {
      failure();
    }

    for (int nxt : ins[u]) {
      if (!on_cyc[nxt]) {
        find_stem(nxt, src);
      }
    }
  }
}

bool pure (const deque<int> &vs) {
  for (int u : vs) {
    if (stem[u] > 0) return false;
  }
  return true;
}

Modint proc (const deque<int> &vs) {
  int n = vs.size();

  vector<int> ss (n);
  for (int i = 0; i < n; i++) {
    ss[i] = stem[vs[i]];
  }

  // distance from previous nonzero stem
  vector<int> ds (n);
  ds[0] = 2 * MAX_N;
  for (int i = 1; i < n; i++) {
    if (ss[i - 1] > 0) {
      ds[i] = 1;
    } else {
      ds[i] = ds[i - 1] + 1;
    }
  }

  if (ss[n - 1] > 0) {
    ds[0] = 1;
  } else {
    ds[0] = ds[n - 1] + 1;
  }
  
  for (int i = 1; i < n; i++) {
    if (ss[i - 1] > 0) {
      ds[i] = 1;
    } else {
      ds[i] = ds[i - 1] + 1;
    }
  }

  /*
  cerr << "a cycle" << endl;
  cerr << "ss    ds" << endl;
  for (int i = 0; i < n; i++) {
    cerr << ss[i] << " " << ds[i] << endl;
  }
  */

  Modint ans (1);
  for (int i = 0; i < n; i++) {
    if (ss[i] > 0) {
      if (ds[i] > ss[i]) ans *= Modint(2);
      else if (ds[i] < ss[i]) failure();
    }
  }

  return ans;
}

Modint fact [MAX_N];
Modint ifact [MAX_N];
Modint pow2 [MAX_N];
Modint powi2 [MAX_N];

Modint count_ev (int n, Modint y) {
  Modint ans (0);
  Modint ypw (1);
  for (int k = 0; 2 * k <= n; k++) {
    ans += powi2[k] * ifact[k] * ifact[n - 2 * k] * ypw;
    ypw *= y;
  }
  ans *= fact[n];
  return ans;
}

Modint count_od (int n, Modint y) {
  Modint ans (0);
  Modint ypw (1);
  for (int k = 0; 2 * k <= n; k++) {
    ans += powi2[k] * ifact[k] * ifact[n - 2 * k] * ypw * pow2[n - 2 * k];
    ypw *= y;
  }
  ans *= fact[n];
  return ans;
}

int main () {
  fact[0] = Modint(1);
  for (int i = 1; i < MAX_N; i++) {
    fact[i] = fact[i - 1] * Modint(i);
  }

  ifact[0] = Modint(1);
  for (int i = 1; i < MAX_N; i++) {
    ifact[i] = inv(fact[i]);
  }

  pow2[0] = Modint(1);
  for (int i = 1; i < MAX_N; i++) {
    pow2[i] = pow2[i - 1] * Modint(2);
  }

  powi2[0] = Modint(1);
  Modint i2 = inv(Modint(2));
  for (int i = 1; i < MAX_N; i++) {
    powi2[i] = powi2[i - 1] * i2;
  }

  ios::sync_with_stdio(false);

  int n;
  cin >> n;

  for (int i = 1; i <= n; i++) {
    cin >> arr[i];
    ins[arr[i]].push_back(i);
  }

  for (int i = 1; i <= n; i++) {
    find_cyc(i, i);
  }

  for (int i = 1; i <= n; i++) {
    if (on_cyc[i]) {
      find_stem(i, i);
    }
  }

  Modint ans (1);
  vector<int> pures;
  for (int i = 1; i <= n; i++) {
    if (!cyc[i].empty()) {
      if (pure(cyc[i])) {
        pures.push_back((int) cyc[i].size());
      } else {
        ans *= proc(cyc[i]);
      }
    }
  }

  sort(pures.begin(), pures.end());
  vector<pair<int, int>> pure_blocks;
  for (auto C : pures) {
    if (pure_blocks.empty() || pure_blocks.back().first != C) {
      pure_blocks.push_back({C, 0});
    }
    pure_blocks.back().second++;
  }

  /*
  cerr << "ans before pures " << ans << endl;
  for (auto pr : pure_blocks) {
    cerr << "(" << pr.first << " " << pr.second << ") ";
  }
  cerr << endl;
  */

  for (auto pr : pure_blocks) {
    if (pr.first % 2 == 0 || pr.first == 1) { // 1 is an even number :O
      ans *= count_ev(pr.second, Modint(pr.first));
    } else {
      ans *= count_od(pr.second, Modint(pr.first));
    }
  }

  cout << ans << endl;
}


Measured memory_bytes: 152700