#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define rep(i,n) for(int i=0;i<n;i++)
typedef long long ll;
ll ans;
int to[100005],n;
struct uf{
    int par[100005],ran[100005];
    void init(){
        rep(i,100005) par[i]=i,ran[i]=0;
    }
    int find(int x){
        if(x == par[x]) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int a,int b){
        a = find(a); b = find(b);
        if(a==b) return;
        if(ran[a]<ran[b]){
            par[a] = b;
        }
        else{
            par[b] = a;
            if(ran[a] == ran[b]) ran[a]++;
        }
    }
}kaede;
int cnt[100005];
bool used[100005];
bool in[100005];
map<int,int>M;
vector<int>rev[100005];
int rdfs(int v){
    if(rev[v].size() >= 2){
        ans = 0;
        return 0;
    }
    else if(rev[v].empty()) return 1;
    else return rdfs(rev[v][0])+1;
}
ll modpow(ll a,ll n){
    ll cur = a,ret = 1;
    while(n){
        if(n%2 == 1) ret = ret*cur%mod;
        cur = cur*cur%mod;
        n /= 2;
    }
    return ret;
}
int main(){
    ans = 1;
    scanf("%d",&n);
    kaede.init();
    for(int i=1;i<=n;i++){
        scanf("%d",&to[i]);
        kaede.unite(i,to[i]);
        rev[to[i]].push_back(i);
    }
    for(int i=1;i<=n;i++) cnt[kaede.find(i)] ++;
    for(int i=1;i<=n;i++){
        if(kaede.find(i) != i) continue;
        int cur = i;
        vector<int>vec;
        int C = 0;
        do{
            vec.push_back(cur);
            used[cur] = 1;
            C++;
            cur = to[cur];
        }while(!used[cur]);
        if(C == cnt[i] && i == cur){
            M[cnt[i]]++;
        }
        else{
            int cur2 = cur;
            do{
                in[cur2] = 1;
                cur2 = to[cur2];
            }while(cur2 != cur);
            cur2 = cur;
            vector<pair<int,int> >chain;
            int pos = 0;
            do{
                if(rev[cur2].size() > 2){
                    ans = 0;
                }
                else if(rev[cur2].size() == 2){
                    int to;
                    rep(w,2) if(!in[rev[cur2][w]]) to = rev[cur2][w];
                    int len = rdfs(to);
                    chain.push_back(make_pair(pos,len));
                }
                pos++;
                cur2 = to[cur2];
            }while(cur2 != cur);
            for(int i=0;i<chain.size();i++){
                int pos_pre = chain[i].first;
                int pos_next = chain[(i+1)%chain.size()].first;
                int dif = pos_next-pos_pre;
                if(dif <= 0) dif += pos;
                if(dif < chain[(i+1)%chain.size()].second){
                    ans = 0;
                }
                else if(dif > chain[(i+1)%chain.size()].second) ans = ans*2LL%mod;
            }
        }
    }
    for(map<int,int>::iterator it=M.begin();it!=M.end();++it){
        int L = it->first, cnt = it->second, zan = it->second;
      	ll mul = modpow(((L==1||L%2==0)?1LL:2LL),cnt);
        ll pre = modpow(((L==1||L%2==0)?1LL:2LL),cnt);
        for(int i=0;i<=cnt/2;i++){
            pre = pre*((1LL*zan*(zan-1)/2LL)%mod)%mod;
            pre = pre*modpow(1LL*(i+1),mod-2)%mod;
            pre = pre*1LL*L%mod;
            pre = pre*modpow(modpow(((L==1||L%2==0)?1LL:2LL),2),mod-2)%mod;
            mul += pre;
            mul %= mod;
            zan -= 2;
        }
        ans = ans*mul%mod;
    }
    cout << ans << endl;
}


Measured memory_bytes: 8064