//Zory-2019
#include<bits/stdc++.h>
using namespace std;
namespace mine
{
    typedef long long ll;
    #define pr pair<int,int>
    #define FR first
    #define SE second
    #define MP make_pair
    #define PB push_back
    #define vc vector
    #define all(x) (x).begin(),(x).end()
    #define sz(x) ((int)(x).size())
    #define bin(x) (1ll<<(x))
    #define GG(x) if(x) {puts("error");exit(666);}
    #define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
    #define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
    ll qread()
    {
        ll ans=0,f=1;char c=getchar();
        while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
        while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
        return ans*f;
    }
    void write(ll num)
    {
        if(num<0) putchar('-'),num=-num;
        if(num>=10) write(num/10);
        putchar('0'+num%10);
    }
    void write1(ll num){write(num);putchar(' ');}
    void write2(ll num){write(num);putchar('\n');}
    template<typename T> void chmax(T &x,const T y) {x=(x>y?x:y);}
    template<typename T> void chmin(T &x,const T y) {x=(x<y?x:y);}
    ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}

    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    int mm(const int x){return x>=MOD?x-MOD:x;}
    template<typename T> void add(T &x,const T &y){x=(x+y>=MOD?x+y-MOD:x+y);}
    ll qpower(ll x,ll e,int mod=MOD){ll ans=1;GG(e<0)while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
    ll invm(ll x){return qpower(x,MOD-2);}
    const int N=1e6+10;

    int a[N],cnt[N],in[N],len[N],tim[N];
    vc<int> cir[N];int id;bool oncir[N];
    int tl[N];ll f[N];
    void main()
    {
        int n=qread();fo(i,1,n) a[i]=qread(),in[a[i]]++;
        fo(rt,1,n) if(!in[rt])//处理基环树
        {
            int now=rt;tim[rt]=rt;
            // puts("");
            while(!tim[a[now]]) now=a[now],tim[now]=rt;//a[now]为链头
            // puts("");
            if(tim[a[now]]==rt)//新找到的基环树
            {
                cir[++id].PB(now);for(int i=now;a[i]!=now;i=a[i]) cir[id].PB(a[i]);
                for(auto x:cir[id]) oncir[x]=1;
            }
            else if(!oncir[a[now]] or tl[a[now]]) {
                puts("0");return;}//非法的基环树
            int ln=0;for(int i=rt;i!=a[now];i=a[i]) ln++;tl[a[now]]=ln;
            // puts("");
        }
        fo(rt,1,n) if(!tim[rt])//环
        {
            int ln=0;for(int i=rt;!tim[i];i=a[i]) ln++,tim[i]=rt;
            cnt[ln]++;
        }
        ll ans=1;
        fo(siz,1,n)//环
        {
            int m=cnt[siz];f[0]=1;f[1]=(1+(siz&1 and siz>1));
            fo(i,2,m) f[i]=(f[i-1]*f[1]+f[i-2]*siz*(i-1))%MOD;
            ans=ans*f[m]%MOD;
        }
        fo(i,1,id)//基环树
        {
            int m=sz(cir[i]);reverse(all(cir[i]));
            cir[i].resize(m+m);
            fo(j,m,m+m-1) cir[i][j]=cir[i][j-m];
            int lstpos=INF;
            fd(j,m+m-1,0) if(tl[cir[i][j]]>0)
            {
                if(j<m)
                {
                    int l1=tl[cir[i][j]],l2=lstpos-j;
                    if(l1>l2)ans=0; else ans=ans*(1+(l1!=l2))%MOD;
                }
                lstpos=j;
            }
        }
        write(ans);
    }
};//(ans+MOD)%MOD
signed main()
{
    srand(time(0));
    mine::main();
}


Measured memory_bytes: 37760