Problem:
Score : 1400 points

Problem Statement

You are given an integer sequence a of length N.
How many permutations p of the integers 1 through N satisfy the following condition?

For each 1 ≤ i ≤ N, at least one of the following holds: p_i = a_i and p_{p_i} = a_i.

Find the count modulo 10^9 + 7.

Constraints

1 ≤ N ≤ 10^5

a_i is an integer.

1 ≤ a_i ≤ N

Input

The input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N

Output

Print the number of the permutations p that satisfy the condition, modulo 10^9 + 7.

Sample Input 1

3
1 2 3

Sample Output 1

4

The following four permutations satisfy the condition:

(1, 2, 3)

(1, 3, 2)

(3, 2, 1)

(2, 1, 3)

For example, (1, 3, 2) satisfies the condition because p_1 = 1, p_{p_2} = 2 and p_{p_3} = 3.

Sample Input 2

2
1 1

Sample Output 2

1

The following one permutation satisfies the condition:

(2, 1)

Sample Input 3

3
2 1 1

Sample Output 3

2

The following two permutations satisfy the condition:

(2, 3, 1)

(3, 1, 2)

Sample Input 4

3
1 1 1

Sample Output 4

0

Sample Input 5

13
2 1 4 3 6 7 5 9 10 8 8 9 11

Sample Output 5

6

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <ctime>

#define Rep(i, n) for (int i = 1; i <= n; i ++)
#define Rep0(i, n) for (int i = 0; i <= n; i ++)
#define RepG(i, x) for (int i = head[x]; i; i = edge[i].next)
#define v edge[i].to
#define mp(a, b) make_pair(a, b)

using namespace std;

typedef long long LL;
const int mod = 1e9 + 7;
const int N = 100010;

struct Edge{ int to, next;} edge[N];
int head[N], num, a[N], d[N];
void add_edge(int a, int b) { edge[++ num] = (Edge){b, head[a]}, head[a] = num;}

bool vis[N], v0[N];
int q[N], cnt, loop[N], nl[N], len[N], c0[N], ql[N];
void dfs(int x)
{
	vis[x] = true, q[++ cnt] = x;
	RepG(i, x) if (!vis[v]) dfs(v);
	if (!vis[a[x]]) dfs(a[x]);
}

LL w2[N], p[N], invp[N];
LL qpow(LL a, LL b)
{
	LL ret = 1, base = a;
	while (b){
		if (b & 1) ret = ret * base % mod;
		base = base * base % mod, b >>= 1;
	} 
	return ret;
}

LL C(int a, int b) { return p[a] * invp[b] % mod * invp[a - b] % mod;}

int main()
{
	//freopen("e.in", "r", stdin);
	//freopen("e.out", "w", stdout);
	
	int n;
	scanf("%d", &n);
	Rep(i, n){
		scanf("%d", &a[i]);
		add_edge(a[i], i), d[a[i]] ++;
	}
	LL ans = 1;
	Rep(i, n) if (!vis[i]){
		cnt = 0, dfs(i);
		bool flag = true;
		Rep(j, cnt) if (d[q[j]] != 1) flag = false;
		if (flag) loop[cnt] ++;
		else {
			int x = i, ll = 0;
			while (true) {
				if (c0[x]) break;
				c0[x] ++, x = a[x];
			}
			ql[++ ll] = x, v0[x] = true;
			for (int j = a[x]; j != x; j = a[j]) ql[++ ll] = j, v0[j] = true;
			Rep(j, ll) {
				bool flag0 = false;
				int x0 = ql[j];
				while (true){
					int cc = 0, tmp0;
					RepG(k, x0) if (!v0[edge[k].to]) cc ++, tmp0 = edge[k].to;
					if (!cc) break;
					else if (cc >= 2) { flag0 = true; break;}
					else x0 = tmp0, len[ql[j]] ++;
				}
				if (flag0) { printf("0\n"); return 0;}
			}
			int cl = 0;
			for (int j = ll; j; j --) {
				if (len[ql[j]]) break;
				cl ++;
			}
			Rep(j, ll) {
				nl[ql[j]] = ++ cl;
				if (len[ql[j]]){
					if (len[ql[j]] < nl[ql[j]]) ans = ans * 2 % mod;
					else if (len[ql[j]] > nl[ql[j]]) { printf("0\n"); return 0;}
					cl = 0;
				}
			}
		}
	}
	w2[0] = 1, p[0] = 1;
	Rep(i, n) w2[i] = w2[i - 1] * 2 % mod, p[i] = p[i - 1] * i % mod;
	invp[n] = qpow(p[n], mod - 2);
	for (int i = n - 1; i >= 0; i --) invp[i] = invp[i + 1] * (i + 1) % mod;
	
	Rep(i, n) if ((i & 1) && loop[i]) {
		LL tmp = 0;
		for (int j = 2; j <= loop[i]; j += 2) {
			if (i & 1 && i != 1) tmp += C(loop[i], j) * C(j, j / 2) % mod * qpow(i, j / 2) % mod * p[j / 2] % mod * w2[loop[i] - j] % mod;
			else tmp += C(loop[i], j) * C(j, j / 2) % mod * qpow(i, j / 2) % mod * p[j / 2] % mod;
			//printf("%lld\n", C(loop[i], j) * C(j, j / 2) % mod * qpow(i, j / 2) % mod * p[j / 2] % mod);
		}
		tmp = tmp * qpow(2, mod - 2) % mod;
		if (i & 1 && i != 1) tmp += w2[loop[i]];
		else tmp ++;
		ans = ans * tmp % mod;
	}
	
	printf("%lld\n", ans);
	
	return 0;
}
/*
9
2 3 4 1 2 5 4 7 8
*/