#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(v) v.begin(),v.end()

const int maxn = 1e5 + 100;
const ll inf = 2e18, mod = 1e9 + 7;

int n, a[maxn], cnt[maxn], mark[maxn], len[maxn], dist[maxn];
vector<int> gin[maxn], gout[maxn], pool;
bool visited[maxn];
ll pw[maxn], fact[maxn], invfact[maxn], ans = 1;

void getPool(int u)
{
	visited[u] = true;
	for (int i : gout[u])
		if (!visited[i])
			getPool(i);
	for (int i : gin[u])
		if (!visited[i])
			getPool(i);
	pool.pb(u);
}

void getCycle(int u)
{
	mark[u]++;
	for (int i : gout[u])
		if (mark[i] != 2)
			getCycle(i);
}

void getLen(int u, int vert)
{
	len[vert]++;
	for (int i : gin[u])
		if (mark[i] != 2)
			getLen(i, vert);
}

void getDist(int u, int vert)
{
	dist[vert]++;
	for (int i : gin[u])
		if (mark[i] == 2 && gin[i].size() == 1)
			getDist(i, vert);
}

ll powmod(ll a, ll b)
{
	if (!b)
		return 1;
	ll tmp = powmod(a, b / 2);
	tmp = tmp * tmp % mod;
	if (b & 1)
		tmp = tmp * a % mod;
	return tmp;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	fact[0] = invfact[0] = pw[0] = 1;
	for (int i = 1; i < maxn; i++)
	{
		pw[i] = pw[i - 1] * 2 % mod;
		fact[i] = fact[i - 1] * i % mod;
		invfact[i] = powmod(fact[i], mod - 2);
	}

	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
		a[i]--;
		gout[i].pb(a[i]);
		gin[a[i]].pb(i);
	}

	for (int i = 0; i < n; i++)
		if (gin[i].size() > 2)
		{
			cout << 0 << endl;
			return 0;
		}

	for (int vert = 0; vert < n; vert++)
		if (!visited[vert])
		{
			pool.clear();
			getPool(vert);


			for (int i : pool)
				if (gin[i].empty())
					getCycle(i);
			/*for (int i : pool)
				cerr << "VERT " << i << ':' << mark[i] << endl;*/
			bool isCycle = true;
			for (int i : pool)
				isCycle &= (gin[i].size() == 1);
			if (isCycle)
				cnt[pool.size()]++;
			else
			{
				for (int i : pool)
					if (mark[i] != 2 && gin[i].size() > 1)
					{
						cout << 0 << endl;
						return 0;
					}
				for (int i : pool)
					if (mark[i] == 2 && gin[i].size() == 2)
						getLen(i, i);
				for (int i : pool)
					if (mark[i] == 2 && gin[i].size() == 2)
					{
						getDist(i, i);
						//cerr << "GET DIST " << i << ' ' << dist[i] << endl;
					}

				for (int i : pool)
					if (gin[i].size() == 2)
					{
						//cerr << "YOLO " << i << ':' << len[i] << ' ' << dist[i] << endl;
						if (len[i] - 1 < dist[i])
							ans = ans * 2 % mod;
						else if (len[i] - 1 > dist[i])
						{
							//cerr << "NOW" << endl;
							cout << 0 << endl;
							return 0;
						}
					}
			}
			//cerr << '#' << isCycle << endl;
		}
	for (int i = 1; i <= n; i++)
		if (cnt[i])
		{
			//cerr << "HERE " << i << ' ' << cnt[i] << endl;
			ll add = 0, val = 1;
			for (int j = 0; j <= cnt[i]; j += 2)
			{
				//cerr << "FOR " << j << ' ' << val << endl;
				if ((i & 1) && i > 1)
					add = (add + ((pw[cnt[i] - j] * val % mod) * invfact[j / 2] % mod)) % mod;
				else
					add = (add + val * invfact[j / 2] % mod) % mod;
				val = val * (((ll)(cnt[i] - j) * (cnt[i] - j - 1) / 2) % mod) % mod;
				val = val * i % mod;
			}
			//cerr << "ADD " << i << ' ' << add << endl;
			ans = ans * add % mod;
		}
	cout << ans << endl;
}



Measured memory_bytes: 22012