//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define bged(v) (v).begin(),(v).end()
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
typedef long long ll;
const int Imx=2147483647;
const ll Lbig=2e18;
const int mod=1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it,len;
	fastio(){it=len=0;}
	inline char get()
	{
		if(it<len)return s[it++];it=0;
		len=fread(s,1,100000,stdin);
		if(len==0)return EOF;else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while(c==' '||c=='\n')c=get();
		if(it>0)it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0;bool ng=0;char c;c=_buff.get();
	while(c!='-'&&(c<'0'||c>'9'))c=_buff.get();
	if(c=='-')ng=1,c=_buff.get();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=_buff.get();
	return ng?-r:r;
}
template<class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline char getreal(){char c=_buff.get();while(c==' '||c=='\n')c=_buff.get();return c;}
int n;
int p[100111],deg[100111];
map<int,int> mp;
int vis[100111];
bool tvis[100111];
bool cyc[100111],tag[100111];
ll dp[100111];
ll calc(int x,int y)
{
//	cerr<<"calc:"<<x<<","<<y<<endl;
	dp[0]=dp[1]=1;
	if(x>1&&(x&1))dp[1]=2;
	for(int i=2;i<=y;i++)
	{
		if(!(x>1&&(x&1)))dp[i]=(dp[i-1]+dp[i-2]*(i-1)%mod*x)%mod;
		else dp[i]=(dp[i-1]*2+dp[i-2]*(i-1)%mod*x)%mod;
	}
	return dp[y];
}
int f[100111];
int gf(int x){return f[x]==x?x:f[x]=gf(f[x]);}
int arr[100111],a[100111];
ll solve(int n)
{
//	cout<<"solve:"<<n<<endl;
//	for(int i=0;i<n;i++)cerr<<arr[i]<<" ";cerr<<endl;
	ll ret=1;
	int st=0;
	while(arr[st]==0)st++;
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		cnt++;
		int cur=arr[(st+i)%n];
		if(cur>0)
		{
			if(cnt>cur)ret=ret*2%mod;
			if(cnt<cur)return 0;
			cnt=0;
		}
	}
//	cerr<<"return "<<ret<<endl;
	return ret;
}
int main()
{
//	freopen("1_04.txt","r",stdin);
	dp[0]=dp[1]=1;
	for(int i=2;i<=100005;i++)
	{
		dp[i]=(dp[i-1]+(i-1)*dp[i-2])%mod;
	}
	geti(n);
	for(int i=1;i<=n;i++)geti(p[i]),deg[p[i]]++;
	for(int i=1;i<=n;i++)
	{
		if(deg[i]>2)
		{
			puts("0");
			return 0;
		}
	}
	for(int i=1;i<=n;i++)if(!vis[i])
	{
		int x=i;
		while(!vis[x])vis[x]=i,x=p[x];
		if(vis[x]==i)
		{
			while(!cyc[x])cyc[x]=1,x=p[x];
		}
	}
//	for(int i=1;i<=n;i++)cerr<<cyc[i]<<" ";cerr<<endl;
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=n;i++)
	{
		if(!cyc[i]&&deg[i]>1)
		{
			puts("0");
			return 0;
		}
		if(!cyc[i])f[i]=p[i];
	}
	for(int i=1;i<=n;i++)
	{
		if(!cyc[i])a[gf(i)]++;
	}
	memset(vis,0,sizeof(vis));
	ll ans=1;
	for(int i=1;i<=n;i++)
	{
		if(!cyc[i]||vis[i])continue;
		int x=i,sz=0;
		bool has=0;
		while(!vis[x])
		{
			vis[x]=1;
			arr[sz++]=a[x];
			if(a[x])has=1;
			x=p[x];
		}
		if(!has)mp[sz]++;
		else ans=ans*solve(sz)%mod;
	}
	foreach(it,mp)ans=ans*calc(it->FF,it->SS)%mod;
	cout<<ans<<endl;
	return 0;
}


Measured memory_bytes: 3584