#include<bits/stdc++.h>
namespace my_std{
	using namespace std;
	#define reg register
	#define Rint register int
	#define FOR(i,a,b) for(register int i=(a),ed_##i=(b);i<=ed_##i;++i)
	#define ROF(i,a,b) for(register int i=(a),ed_##i=(b);i>=ed_##i;--i)
	#define FORit(templ,arr,i,a,b) for(register templ *i=(arr)+(a),*ed_##i=(arr)+(b)+1;i!=ed_##i;++i)
	#define ROFit(templ,arr,i,a,b) for(register templ *i=(arr)+(a),*ed_##i=(arr)+(b)-1;i!=ed_##i;--i)
	#define GO(x,p,e,i,v) for(register int i=p[x].head,v;i;i=e[i].link)
	#define MEM(x,v) memset(x,v,sizeof(x))
	#define fir first
	#define sec second
	#define pq priority_queue
	#define MP make_pair
	typedef long long LL;
	typedef double DB;
	typedef pair<int,int> PII;
	#define Templ(T) template<typename T>
	inline int read(){
		Rint ans=0,f=1;reg char c=getchar();
		while(!isdigit(c)){ f^=(c=='-'); c=getchar(); }
		for(;isdigit(c);c=getchar()) ans=ans*10+c-'0'; return f?ans:-ans;
	}
	Templ(_Tp) inline int chkmin(_Tp &x,_Tp y){ return x>y?x=y,1:0; }
	Templ(_Tp) inline int chkmax(_Tp &x,_Tp y){ return x<y?x=y,1:0; }
	#define using_mod
	const int mod = 0x3b9aca07, N = 100010;
	#ifdef using_mod
	inline void inc(int &x,const int &y){ x+=y; if(x>=mod) x-=mod; }
	inline int ksm(int x,LL y){ int res=1; for(;y;y>>=1,x=1ll*x*x%mod) if(y&1) res=1ll*res*x%mod; return res;}
	#endif
	Templ(_Tp) inline _Tp gcd(_Tp x,_Tp y){ return y?gcd(y,x%y):x; }
	#define FILE(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
	#define PBTXDY
}
using namespace my_std;

const int v2r = (mod + 1) >> 1;
int n, a[N], vis[N], cnt[N], fac[N] = {1}, ifac[N] = {1}, dep[N], dgr[N], ord[N];
vector<int >rnd[N];
int stk[N], *stop = stk, stv[N];

inline int CC(int n, int m){
//	if(m == 2){
//		return ((1ll * n * (n - 1)) >> 1) % mod;
//	}
	return int(1ll * ifac[n - m] * ifac[m] % mod * fac[n] % mod);
}

namespace brute{
int p_p[15], ans;
inline void kechc(){
	FOR(i, 1, n) if(a[i] != p_p[i] && a[i] != p_p[p_p[i]]) return;
//	FOR(i, 1, n) printf("%d ",p_p[i]); putchar('\n');
	return void(++ans);
}
void dfs_(int dep){
	if(dep > n) return kechc();
	FOR(i, 1, n){
		if(p_p[i] != a[i] && ((p_p[i] && p_p[i] < dep) && p_p[p_p[i]] != a[i])) return;
	}
	FOR(i, 1, n) if(!vis[i]){
		vis[p_p[dep] = i] = dep;
		dfs_(dep + 1);
		vis[i] = p_p[dep] = 0;
	}
}
int work_10(){
	dfs_(1);
	return printf("%d\n", ans), 0;
}
}

int work_PerMuTaTion(){
	FOR(i, 1, n) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[n] = ksm(fac[n], mod - 2);
	ROF(i, n - 1, 1) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
	MEM(cnt, 0);
	Rint x, res, tem = 0, ans = 1;
	FOR(i, 1, n) if(!vis[i]){
		vis[i] = 1 , x = a[i], res = 1;
		while(!vis[x]) vis[x] = 1, x = a[x], ++res;
		++cnt[res];
	}
	FOR(k, 1, n){
		x = cnt[k];
		if(!x) continue;
		tem = 0;
		FOR(i, 0, x >> 1){
			res = 1ll * ifac[i] * ksm(int(1ll * k * v2r % mod), i) % mod;
			res = 1ll * fac[x] * ifac[x - 2 * i] % mod * res % mod;
			if((k & 1) && k > 1) res = 1ll * ksm(2, x - 2 * i) * res % mod;
			inc(tem, res);
		}
		ans = 1ll * ans * tem % mod;
	}
	return printf("%d\n",ans), 0;
}

int work_Solution(){
	FOR(i, 1, n) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[n] = ksm(fac[n], mod - 2);
	ROF(i, n - 1, 1) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
	MEM(cnt, 0);
	Rint x, res, tem = 0, ans = 1;
	FOR(i, 1, n) dgr[ a[i] ]++;
	FOR(i, 1, n) if(dgr[i] > 2) return puts("0"), 0;
//	FOR(i, 1, n) printf("%d ",dgr[i]); puts("");
	//Step 1 :
	FOR(i, 1, n) if(!dgr[i]){
		vis[i] = 1, res = 1, x = a[i];
		while(dgr[x] != 2) vis[x] = 1, ++res, x = a[x];
		if(dep[x]) return puts("0"), 0;
		dep[x] = res;
	}
//	FOR(i, 1, n) printf("%d ",vis[i]); puts("");
//	FOR(i, 1, n) printf("%d ",dep[i]); puts("");
	//Step 2 :
	FOR(i, 1, n) if(dgr[i] == 2 && !vis[i]){
		vis[i] = 1, tem = 1, x = a[i];
		while(!vis[x]){
			vis[x] = 1;
//			printf("%d %d\n",x,tem);
			if(dgr[x] == 2){
				if(tem < dep[x]) return puts("0"), 0;
				if(tem > dep[x]) ans = (ans << 1) % mod;
				tem = 0;
			}
			++tem, x = a[x];
		}
//		printf("%d %d\n",x,tem);
		if(tem < dep[x]) return puts("0"), 0;
		if(tem > dep[x]) ans = (ans << 1) % mod;
	}
//	FOR(i, 1, n) printf("%d ",vis[i]); puts("");
	//Step 3 :
	FOR(i, 1, n) if(!vis[i]){
		vis[i] = 1, res = 1, x = a[i];
		while(!vis[x]) vis[x] = 1, ++res, x = a[x];
		++cnt[res];
	}
//	FOR(i, 1, n) if(cnt[i]) printf("cnt[%d] : %d\n", i, cnt[i]);
	FOR(k, 1, n){
		x = cnt[k];
		if(!x) continue;
		tem = 0;
		FOR(i, 0, x >> 1){
			res = 1ll * ifac[i] * ksm(int(1ll * k * v2r % mod), i) % mod;
			res = 1ll * fac[x] * ifac[x - 2 * i] % mod * res % mod;
			if((k & 1) && k > 1) res = 1ll * ksm(2, x - 2 * i) * res % mod;
			inc(tem, res);
		}
		ans = 1ll * ans * tem % mod;
	}
	return printf("%d\n",ans), 0;
}

int main(){
//	FILE("dayinf");
	n = read();
	FOR(i, 1, n) cnt[a[i] = read()]++;
	if(n <= 10) return brute::work_10();
	Rint french_flag = 1;
	FOR(i, 1, n) if(cnt[i] != 1){ french_flag = 0; break; }
	if(french_flag) return work_PerMuTaTion();
	return work_Solution();
}

Measured memory_bytes: 5888