#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;
const int SIZE = 1e5+10;
int a[SIZE],b[SIZE],p[SIZE];
LL an=1;
int used[SIZE],tt,in_cycle[SIZE],cn[SIZE],at[SIZE],in_deg[SIZE],from[SIZE];
int cid;
VI cy[SIZE];
int clear_cycle[SIZE];

void handle(int id){
    int two_id=-1;
    REP(i,SZ(cy[id])){
        if(in_deg[cy[id][i]]==2)two_id=i;
    }
    if(two_id==-1){
        clear_cycle[SZ(cy[id])]++;
        return;
    }
    LL res=1;
    REP(i,SZ(cy[id])){
        if(in_deg[cy[id][i]]==2){
            int tail=0;
            int now=cy[id][i];
            while(from[now]){
                tail++;
                now=from[now];
            }
            int cc=1;
            int it=i-1;
            while(1){
                if(it<0)it=SZ(cy[id])-1;
                if(in_deg[cy[id][it]]==2)break;
                cc++;
                it--;
            }
            if(tail<cc)res=res*2%MOD;
            else if(tail>cc)res=0;
        }
    }
    an=an*res%MOD;
}
LL mypow(LL x,LL y){
    x%=MOD;
    LL res=1%MOD;
    while(y){
        if(y&1)res=res*x%MOD;
        y>>=1;
        x=x*x%MOD;
    }
    return res;
}
int main(){
    DRI(n);
    REPP(i,1,n+1)RI(a[i]);
    REPP(i,1,n+1){
        in_deg[a[i]]++;
        if(used[i])continue;
        tt++;
        int now=i;
        for(int j=0;;j++){
            b[j]=now;
            p[now]=j;
            used[now]=tt;
            now=a[now];
            if(used[now]==tt){
                REPP(k,1,p[now]+1){
                    from[b[k]]=b[k-1];
                }
                REPP(k,p[now],j+1){
                    cy[cid].PB(b[k]);
                    at[b[k]]=k-p[now];
                    in_cycle[b[k]]=1;
                    cn[b[k]]=j+1-p[now];
                }
                cid++;
                break;
            }
            else if(used[now]){
                from[now]=b[j];
                REPP(k,1,j+1){
                    from[b[k]]=b[k-1];
                }
                break;
            }
        }
    }
    REPP(i,1,n+1){
        if(in_deg[i]>2||(!in_cycle[i]&&in_deg[i]==2))return 0*puts("0");
    }
    REP(i,cid)handle(i);
    REPP(i,1,n+1){
        if(clear_cycle[i]){
            LL now=1;
            LL inv=1;
            if(i%2==1&&i!=1){
                now=mypow(2,clear_cycle[i]);
                inv=mypow(2,MOD-2);
            }
            LL tmp=now;
            int len=clear_cycle[i];
            //printf("[%d:%d]:%lld %lld\n",i,len,tmp,an);
            for(int j=1;j*2<=len;j++){
                now=now*(((len-j*2+2)*(len-j*2+1LL)/2)%MOD)%MOD*i%MOD;
                now=now*inv%MOD*inv%MOD;
                now=now*mypow(j,MOD-2)%MOD;
                tmp=(tmp+now)%MOD;
            }
            an=an*tmp%MOD;
        }
    }
    cout<<an<<endl;
    return 0;
}


Measured memory_bytes: 8448