#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<bitset>
#include<set>
#define N (200010)
#define P (1000000007)
#define M (N<<1)
#define inf (0x7f7f7f7f)
#define rg register int
#define Label puts("NAIVE")
#define spa print(' ')
#define ent print('\n')
#define rand() (((rand())<<(15))^(rand()))
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
typedef long double ld;
typedef long long LL;
typedef unsigned long long ull;
using namespace std;
namespace fastIO1{
	inline char read(){
		static const int IN_LEN=1000000;
		static char buf[IN_LEN],*s,*t;
		return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
	}
	template<class T>
	inline void read(T &x){
		static bool iosig;
		static char c;
		for(iosig=false,c=read();!isdigit(c);c=read()){
			if(c=='-')iosig=true;
			if(c==-1)return;
		}
		for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
		if(iosig)x=-x;
	}
	inline char readc(char &c){
		for(c=read();!isalpha(c)&&!isdigit(c);c=read())
		if(c==-1)return 0;
	}
	const int OUT_LEN = 10000000;
	char obuf[OUT_LEN],*ooh=obuf;
	inline void print(char c) {
		if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
		*ooh++=c;
	}
	template<class T>
	inline void print(T x){
		static int buf[30],cnt;
		if(x==0)print('0');
		else{
			if(x<0)print('-'),x=-x;
			for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
			while(cnt)print((char)buf[cnt--]);
		}
	}
	inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
}
namespace fastIO2{
	template<class T>
	inline void read(T &x){
		static bool iosig;
		static char c;
		for(iosig=false,c=getchar();!isdigit(c);c=getchar()){
			if(c=='-')iosig=true;
			if(c==-1)return;
		}
		for(x=0;isdigit(c);c=getchar())x=((x+(x<<2))<<1)+(c^'0');
		if(iosig)x=-x;
	}
}
using namespace fastIO1;
int n,deg[N],fi[N],ne[M],b[M],len[N],a[N],tmp[N],p[N],ans=1; queue<int> Q; 
bool vis[N],vv[N]; int siz[N],nxt[N],jc[N],inv[N],E;
#define GG puts("0"),exit(0)
void dfs(int x){
	int cnt=1,fl=len[x]; vv[x]=1;
	for(int i=nxt[x];i!=x;i=nxt[i])
	cnt++,fl|=len[i],vv[i]=1;
	if(!fl){siz[cnt]++;return;}
	int s=0; if(len[x])tmp[++s]=len[x],p[s]=1;
	for(int i=nxt[x],t=2;i!=x;i=nxt[i],t++)
	if(len[i])tmp[++s]=len[i],p[s]=t;
//	cout<<cnt<<endl;
	for(int i=1;i<=s;i++){
		int l=(i==1)?p[i]-p[s]+cnt:p[i]-p[i-1];
//		cout<<l<<" fafafa"<<endl;
		if(l>tmp[i])ans=2ll*ans%P;
		else if(l<tmp[i])GG;
	}
}
int ksm(int a,int p){
	int res=1;
	while(p){
		if(p&1)res=1ll*res*a%P;
		a=1ll*a*a%P,p>>=1;
	}
	return res;
}
void add(int x,int y){
	ne[++E]=fi[x],fi[x]=E,b[E]=y;
}
int C(int n,int m){
	return 1ll*jc[n]*inv[m]%P*inv[n-m]%P;
}
int main(){
//	freopen("1_01.txt","r",stdin);
	read(n);jc[0]=inv[0]=1;
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++)add(i,a[i]),deg[a[i]]++;
	for(int i=1;i<=n;i++)if(deg[i]==0)Q.push(i); 
	for(int i=1;i<=n;i++)jc[i]=1ll*jc[i-1]*i%P,inv[i]=ksm(jc[i],P-2);
	while(!Q.empty()){
		int u=Q.front(); vis[u]=1,Q.pop();
		for(int i=fi[u];i;i=ne[i]){
			int v=b[i];
			deg[v]--;
			if(len[v])GG; len[v]=len[u]+1;
			if(!deg[v])Q.push(v);
		}
	}
	for(int i=1;i<=n;i++)
	if(!vis[i])for(int j=fi[i];j;j=ne[j])
	if(!vis[b[i]])nxt[i]=b[i];
//	for(int i=1;i<=n;i++)cout<<len[i]<<" "; puts("");
	for(int i=1;i<=n;i++)if(!vis[i]&&!vv[i])dfs(i);
	for(int i=1;i<=n;i++)
	if(siz[i]){
		int T=0,w=1;
//		cout<<i<<" "<<siz[i]<<endl;
		for(int j=0;j<=siz[i]/2;j++){
			if(j>=1)w=1ll*C(j*2,j)*jc[j]%P*ksm(ksm(2,P-2),j)%P;
//			if(j==50000||j<=20)cout<<w<<endl;
			(T+=1ll*C(siz[i],j*2)*ksm(i,j)%P*w%P*(((i>1)&&(i&1))?ksm(2,siz[i]-j*2):1)%P)%=P;
		}
		
//		cout<<i<<" "<<T<<endl;
		ans=1ll*ans*T%P;
	}
	cout<<ans;
}

Measured memory_bytes: 12288