#include <bits/stdc++.h>
using namespace std;

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define PII pair < int, int >
#define PLL pair < LL, LL >
#define PIL pair < int, LL >
#define PLI pair < LL, int >
#define MP make_pair
#define PB push_back
#define PF push_front
#define POB pop_back
#define POF pop_front
#define PRF first
#define PRS second
#define INIT(ar,val) memset ( ar, val, sizeof ( ar ) )
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 100007;
const int MOD = 1000000007;

int n;
int a[MAXN];
int pw2[MAXN], rpw2[MAXN];
LL frac[MAXN], rf[MAXN];
bool vis[MAXN], ins[MAXN];
int stk[MAXN], top;
int vc[MAXN];
int inc[MAXN], ci[MAXN], kc;
int sz[MAXN];
int cc[MAXN];
bool nvc[MAXN];
bool isl[MAXN];
AR(int) cyc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now, int nl );

int getodd ( int n, int sz );
int geteven ( int n, int sz );



int add ( int x, int y )
{
	x += y;
	if ( x >= MOD ) x -= MOD;
	return x;
}

void addv ( int &x, int y )
{
	x += y;
	if ( x >= MOD ) x -= MOD;
}

int qpow ( int a, int b )
{
	LL base = a, ans = 1;
	while ( b ){
		if ( b & 1 ) ( ans *= base ) %= MOD;
		( base *= base ) %= MOD;
		b >>= 1;
	}
	return SC ( int, ans );
}

int C ( int n, int m )
{
	return SC ( int, frac[n] * rf[m] % MOD * rf[n-m] % MOD );
}



int main()
{
	init();
	input();
	work();
}



void init ()
{
	// Init Everything Here
	
	ios::sync_with_stdio ( false );
	
	pw2[0] = 1;
	lp ( i, 1, MAXN ) pw2[i] = add ( pw2[i-1], pw2[i-1] );
	int R2 = qpow ( 2, MOD-2 );
	rpw2[0] = 1;
	lp ( i, 1, MAXN ) rpw2[i] = SC ( LL, rpw2[i-1] ) * R2 % MOD;
	frac[0] = 1;
	lp ( i, 1, MAXN ) frac[i] = frac[i-1] * i % MOD;
	rf[MAXN-1] = qpow ( frac[MAXN-1], MOD-2 );
	lpdi ( i, MAXN-2, 0 ) rf[i] = rf[i+1] * ( i + 1 ) % MOD;
}

void input ()
{
	// input method
	
	scanf ( "%d", &n );
	lpi ( i, 1, n ) scanf ( "%d", &a[i] );
}

void work ()
{
	// main work
	
	INIT ( isl, true );
	lpi ( i, 1, n ) if ( a[i] ^ i ) isl[a[i]] = false;
	
	lpi ( i, 1, n ) if ( isl[i] ) dfs ( i, 0 );
	lpi ( i, 1, n ) if ( !vis[i] ) dfs ( i, 0 );
	
	if ( *max_element ( vc+1, vc+1+n ) > 1 ){
		printf ( "0\n" );
		return;
	}
	
	int ans = 1;
	lpi ( i, 1, kc ){
		if ( nvc[i] ) ++cc[sz[i]];
		else{
			int nc = 0;
			lp ( j, 0, sz[i] ){
				if ( !vc[cyc[i][j]] ){
					if ( !j || vc[cyc[i][j-1]] ) ++nc;
				}
			}
			if ( !vc[cyc[i].front()] && !vc[cyc[i].back()] ) --nc;
			ans = SC ( LL, ans ) * pw2[nc] % MOD; 
		}
	}
	
//	lpi ( i, 1, n ) cerr << cc[i] << " "; cerr << endl;
	
	lpi ( i, 1, n ) if ( cc[i] ) ans = SC ( LL, ans ) * ( ( i > 1 && ( i & 1 ) ) ? getodd ( cc[i], i ) : geteven ( cc[i], i ) ) % MOD;
	
	cout << ans << endl;
}



void dfs ( int now, int nl )
{
	if ( vis[now] ){
		if ( ins[now] ){
			++kc;
			nvc[kc] = true;
			for ( int t = top; stk[t] ^ now; --t ){
				inc[stk[t-1]] = kc;
				++sz[kc];
				ci[stk[t-1]] = cyc[kc].size ();
				cyc[kc].PB ( stk[t-1] );
			}
		}else if ( !inc[now] ) vc[now] = 2;
		return;
	}
	
	vis[now] = ins[now] = true;
	stk[top++] = now;
	dfs ( a[now], nl + 1 );
	if ( inc[a[now]] && !inc[now] ){
//		cerr << "from : " << now << " " << nl << endl;
		lp ( i, 0, nl+1 ) ++vc[cyc[inc[a[now]]][(ci[a[now]]+i)%sz[inc[a[now]]]]]; //, cerr << cyc[inc[a[now]]][(ci[a[now]]+i)%sz[inc[a[now]]]] << endl;
		nvc[inc[a[now]]] = false;
	}
	ins[now] = false;
	--top;
}



int getodd ( int n, int sz )
{
	int ans = 0;
	int tmp = 1;
	for ( int i = 0; i <= n; i += 2 ) addv ( ans, SC ( LL, C ( n, i ) ) * frac[i] % MOD * rpw2[i>>1] % MOD * rf[i>>1] % MOD * tmp % MOD * pw2[n-i] % MOD ), tmp = SC ( LL, tmp ) * sz % MOD;
	return ans;
}

int geteven ( int n, int sz )
{
	int ans = 0;
	int tmp = 1;
	for ( int i = 0; i <= n; i += 2 ) addv ( ans, SC ( LL, C ( n, i ) ) * frac[i] % MOD * rpw2[i>>1] % MOD * rf[i>>1] % MOD * tmp % MOD ), tmp = SC ( LL, tmp ) * sz % MOD;
	return ans;
}

Measured memory_bytes: 13436