// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<cstdlib>

using namespace std;

int p1[110000],p2[110000];

int a[110000];

int lb[110000];

inline void jio(){puts("0");exit(0);}

bool lowb[110000];

long long ff[110000];

int ljrose[110000];

long long renleizhihui[110000];

int main()

{

	int n;scanf("%d",&n);

	memset(p1,0,sizeof(p1));

	memset(p2,0,sizeof(p2));

	int lben=0;

	for(int i=1;i<=n;i++)

	{

		scanf("%d",&a[i]);

		if(a[i]<1||a[i]>n)jio();

		if(a[i]==i)lb[++lben]=i;

		if(p1[a[i]]==0)p1[a[i]]=i;

		else if(p2[a[i]]==0)p2[a[i]]=i;

		else jio();

	}

	int ss=0;

	memset(lowb,false,sizeof(lowb));

	for(int i=1;i<=lben;i++)

	{

		lowb[lb[i]]=true;

		if(p1[lb[i]]!=lb[i])p1[lb[i]]^=p2[lb[i]]^=p1[lb[i]]^=p2[lb[i]];

		if(p2[lb[i]]!=0)lowb[p2[lb[i]]]=true;

		if(p2[lb[i]]==0)ss++;

		else if(p1[p2[lb[i]]]!=0)jio();

	}

	long long lbsl=1;

	for(int i=1;i<=n;i++)

	{

		int xx=0,yy=0;

		long long s=2;

		if(p2[i]!=0&&lowb[i]==false)

		{

			lowb[i]=true;

			xx=p1[i];yy=p2[i];

			lowb[xx]=lowb[yy]=true;

			while(true)

			{

				if(yy>0)

				{

					int xr=xx,yr=yy;

					if(p2[xr]!=0&&p1[yr]!=0)jio();

					if(p1[xr]!=0&&p2[yr]!=0)jio();

					if(p1[xr]!=0&&p1[yr]!=0)xx=p1[xr],yy=p1[yr];

					else if(p2[xr]!=0)xx=p1[xr],yy=p2[xr];

					else if(p2[yr]!=0)xx=p1[yr],yy=p2[yr];

					else if(p1[xr]!=0)xx=p1[xr],yy=0;

					else if(p1[yr]!=0)xx=p1[yr],yy=0;

					else xx=yy=0;

				}

				else

				{

					int xr=xx;

					if(p2[xr]!=0)xx=p1[xr],yy=p2[xr],s=s*2%1000000007;

					else if(p1[xr]!=0)xx=p1[xr],yy=0;

					else xx=yy=0;

				}

				lowb[xx]=lowb[yy]=true;

				if(xx==0&&yy==0)jio();

				if(xx==i||yy==i)

				{

					if(yy==i)xx^=yy^=xx^=yy;

					if(yy==0)break;

					if(p1[yy]!=0)jio();

					else

					{

						if(s%2==0)s=s/2;

						else s=(s+1000000007)/2;

						break;

					}

				}

			}

			lbsl=lbsl*s%1000000007;

		}

	}

	ff[0]=1;ff[1]=1;ff[2]=2;

	for(int i=3;i<=n;i++)ff[i]=(ff[i-1]+ff[i-2]*(i-1)%1000000007)%1000000007;

	memset(ljrose,0,sizeof(ljrose));

	for(int i=1;i<=n;i++)

	{

		if(lowb[i]==false)

		{

			long long sr=1;int j=a[i];

			lowb[i]=true;

			while(j!=i)lowb[j]=true,j=a[j],sr++;

			ljrose[sr]++;

		}

	}

	for(int i=2;i<=n;i++)

	{

		if(i%2==1)

		{

			renleizhihui[0]=1;renleizhihui[1]=2;renleizhihui[2]=4+i;

			for(int j=3;j<=ljrose[i];j++)renleizhihui[j]=(renleizhihui[j-1]*2+renleizhihui[j-2]*(j-1)%1000000007*i%1000000007)%1000000007;

			lbsl=lbsl*renleizhihui[ljrose[i]]%1000000007;

			continue;

		}

		renleizhihui[0]=1;renleizhihui[1]=1;renleizhihui[2]=1+i;

		for(int j=3;j<=ljrose[i];j++)renleizhihui[j]=(renleizhihui[j-1]+renleizhihui[j-2]*(j-1)%1000000007*i%1000000007)%1000000007;

		lbsl=lbsl*renleizhihui[ljrose[i]]%1000000007;

	}

	lbsl=lbsl*ff[ss]%1000000007;

	printf("%lld\n",lbsl);

	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cctype>

#define RI register int

#define g (p1==p2&&(p2=(p1=buf)+fread(buf,1,size,stdin),p1==p2)?EOF:*p1++)

using namespace std;

typedef long long ll;

const int mod=1e9+7,N=1e5+10,size=N<<2;

char buf[size],*p1=buf,*p2=buf;

void qr(int &x) {

	char c=g;x=0;

	while(!isdigit(c))c=g;

	while(isdigit(c))x=x*10+c-'0',c=g;

}

int n; ll ans;

int a[N],deg[N],vis[N],footL[N],sum[N],f[N];

bool cir[N];

inline int qm(int x) {return x>=mod?x-mod:x;}

void workcir(int x) {

	int now=0,fr=0,frL=0,ed=0;

	//now是当前环的长度，fr是第一个有脚点的位置,frL是位置对应的脚长,ed为上一个有脚点的位置。 

	while(cir[x]) {

		++now; cir[x]=0;

		if(footL[x]) {

			if(!fr) ed=fr=now,frL=footL[x];

			else {

				ans=ans*((footL[x]<now-ed)+(footL[x]<=now-ed))%mod;//脚的放法 

				ed=now;

			}

		}

		x=a[x];

	}

	if(!ed) ++sum[now];

	else ans=ans*((frL<now-ed+fr)+(frL<=now-ed+fr))%mod;

}

void work() {

	for(RI i=1;i<=n;i++) {//脚对环上交接点贡献 

		if(deg[i]) continue;

		int x=i,len=0; while(!cir[x])x=a[x],++len;

		footL[x]=len;//脚长 

	}

	ans=f[0]=1;

	for(RI i=1;i<=n;i++) if(cir[i]) workcir(i);//以环为基准计算基环内向树的情况 

	for(RI i=1;i<=n&&ans;i++) {//计算简单环 

		for(RI j=1;j<=sum[i];j++) {

			if(i>1&&(i&1)) f[j]=qm(f[j-1]<<1);

			else f[j]=f[j-1];

			if(j>1) f[j]=qm(f[j]+(ll)f[j-2]*(j-1)%mod*i%mod);

		}

		ans=ans*f[sum[i]]%mod;

	}

}

int main() {

	qr(n);

	for(RI i=1;i<=n;i++) qr(a[i]),++deg[a[i]];

	for(RI i=1;i<=n;i++) if(!vis[i]) {

		int x=i;while(!vis[x]) vis[x]=i,x=a[x];

		if(vis[x]!=i) continue;//脚 

		while(!cir[x]) cir[x]=1,x=a[x];//标记环上点 

	}

	for(RI i=1;i<=n;i++)

		if((cir[i]&&deg[i]>2)||(!cir[i]&&deg[i]>1)) return puts("0"),0;//开叉就不行 

	work(); printf("%lld\n",ans); return 0;

}

// Fastest known solution for this problem: