/*
把原排列P当成一个置换，那么就形成了若干个环。A就是由每个点i往环上的后继P[i]或后继的后继P[P[i]]连边得到的图
考虑一个环，分情况讨论：
(1)该环上的点i -> P[i]。那么该环在A中不变
(2)该环是一个（大小 != 1）奇环，环上的点i -> P[P[i]]，那么在A中变成一个大小不变的环
(3)该环是一个偶环，环上的点i -> P[P[i]]，那么在A中分裂成2个大小相同的环 
(4)不属于以上3种情况，那么该环在A中变成了一颗每个点出度 = 1的基环树，且一定有不在环上在树上的点 
对于前(3)种情况，直接对于环计数，考虑合并的情况即可。主要考虑情况(4)
首先，该基环树的每棵树一定是一条链，即一个点最多只有1个儿子
考虑把每条链“嵌入”到环中，那么链的顶端一定是其环上根的后继或后继的后继
容易发现对于一条链根据链的顶端嵌入在何处只有2种嵌入的方法，都是把链点插入在连续的环点之间，形成链点和环点交替的形状
需要满足嵌入的位置不能超过环上下一条链的根。那么每颗基环树的方案数可以直接计算
*/

#include <stack>
#include <vector>
#include <cstdio>
#include <algorithm>

using namespace std;
const int Max_N(100050);
const int MOD(1000000000 + 7);
typedef long long int LL;

constexpr int Mult(int a, int b)
{
	return a * 1LL * b % MOD;
}

constexpr int Add(int a, int b)
{
	return a + b >= MOD ? a + b - MOD : a + b;
}

constexpr int Sub(int a, int b)
{
	return a - b < 0 ? a - b + MOD : a - b;
}

void exgcd(int a, int b, int &x, int &y)
{
	if (b == 0)
		x = 1, y = 0;
	else
		exgcd(b, a % b, y, x), y -= x * (a / b);
}

inline int inverse(int a)
{
	int invx, invy;
	exgcd(a, MOD, invx, invy);
	return (invx % MOD + MOD) % MOD;
}

int N, F[Max_N], Father[Max_N], Fac[Max_N], Inv[Max_N], power[Max_N], Son[Max_N], dfsclock, Pre[Max_N], Lowlink[Max_N], scctot, sccno[Max_N], Ans, Cnt[Max_N];
vector<int> SCC[Max_N];

inline int C(int n, int m)
{
	return Mult(Fac[n], Mult(Inv[m], Inv[n - m]));
}

stack<int> S;
void Tarjan(int u)
{
	int v;
	S.push(u), Pre[u] = Lowlink[u] = ++dfsclock;
	if (!Pre[v = Father[u]])
		Tarjan(v), Lowlink[u] = min(Lowlink[u], Lowlink[v]);
	else
		if (!sccno[v])
			Lowlink[u] = min(Lowlink[u], Pre[v]);
	if (Lowlink[u] == Pre[u])
	{
		++scctot;
		while (true)
		{
			v = S.top(), S.pop();
			SCC[sccno[v] = scctot].push_back(v);
			if (u == v)
				break;
		}
		reverse(SCC[scctot].begin(), SCC[scctot].end());
	}
}

int dfs(int u)
{
	return 1 + (Son[u] ? dfs(Son[u]) : 0);
}

int Next[Max_N];
void work(const vector<int> &V)
{
	for (int i = 0, j = V.size() - 1;i < V.size();++i, (++j) %= V.size())
		Next[i] = (Son[V[j]] ? 1 : Next[j] + 1);
	for (int i = 0, j = V.size() - 1;i < V.size();++i, (++j) %= V.size())
		Next[i] = (Son[V[j]] ? 1 : Next[j] + 1);
	int Ret(1);
	for (int i = 0, u, d;i < V.size();++i)
		if (Son[u = V[i]])
			d = dfs(Son[u]), Ret = Mult(Ret, (d <= Next[i]) + (d + 1 <= Next[i]));
	Ans = Mult(Ans, Ret);
}

int main()
{
	scanf("%d", &N);
	for (int i = 1;i <= N;++i)
		scanf("%d", Father + i);
	Fac[0] = 1;
	for (int i = 1;i <= N;++i)
		Fac[i] = Mult(Fac[i - 1], i);
	Inv[N] = inverse(Fac[N]);
	for (int i = N - 1;i >= 0;--i)
		Inv[i] = Mult(Inv[i + 1], i + 1);
	power[0] = 1;
	for (int i = 1;i <= N;++i)
		power[i] = Add(power[i - 1], power[i - 1]);
	for (int i = 1;i <= N;++i)
		if (!Pre[i])
			Tarjan(i);
	for (int i = 1;i <= N;++i)
		if (sccno[Father[i]] != sccno[i])
		{
			if (Son[Father[i]])
			{
				printf("0");
				return 0;
			}
			Son[Father[i]] = i;
		}
	Ans = 1;
	for (int x = 1, flag;x <= scctot;++x)
		if (x == sccno[Father[SCC[x][0]]])
		{
			flag = 0;
			for (int i = 0;i < SCC[x].size();++i)
				flag |= Son[SCC[x][i]];
			if (flag)
				work(SCC[x]);
			else
				++Cnt[SCC[x].size()];
		}
	F[0] = 1;
	for (int n = 2;n <= N;n += 2)
		F[n] = Mult(n - 1, F[n - 2]);
	for (int x = 1, Ret;x <= N;++x)
	{
		Ret = 0;
		for (int i = 0, v = 1;2 * i <= Cnt[x];++i, v = Mult(v, x))
			Ret = Add(Ret, Mult(Mult(Mult(C(Cnt[x], 2 * i), F[2 * i]), v), ((x & 1) && x > 1) ? power[Cnt[x] - 2 * i] : 1));
		Ans = Mult(Ans, Ret);
	}
	printf("%d", Ans);
	return 0;
}

Measured memory_bytes: 12512