Problem:
Score : 1600 points

Problem Statement

Snuke has permutations (P_0,P_1,\cdots,P_{N-1}) and (Q_0,Q_1,\cdots,Q_{N-1}) of (0,1,\cdots,N-1).

Now, he will make new permutations A and B of (0,1,\cdots,N-1), under the following conditions:

For each i (0 \leq i \leq N-1), A_i should be i or P_i.

For each i (0 \leq i \leq N-1), B_i should be i or Q_i.

Let us define the distance of permutations A and B as the number of indices i such that A_i \neq B_i.
Find the maximum possible distance of A and B.

Constraints

1 \leq N \leq 100000

0 \leq P_i \leq N-1

P_0,P_1,\cdots,P_{N-1} are all different.

0 \leq Q_i \leq N-1

Q_0,Q_1,\cdots,Q_{N-1} are all different.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
P_0 P_1 \cdots P_{N-1}
Q_0 Q_1 \cdots Q_{N-1}

Output

Print the maximum possible distance of A and B.

Sample Input 1

4
2 1 3 0
0 2 3 1

Sample Output 1

3

For example, if we make A=(0,1,2,3) and B=(0,2,3,1), the distance will be 3, which is the maximum result possible.

Sample Input 2

10
0 4 5 3 7 8 2 1 9 6
3 8 5 6 4 0 2 1 7 9

Sample Output 2

8

Sample Input 3

32
22 31 30 29 7 17 16 3 14 9 19 11 2 5 10 1 25 18 15 24 20 0 12 21 27 4 26 28 8 6 23 13
22 3 2 7 17 9 16 4 14 8 19 26 28 5 10 1 25 18 15 13 11 0 12 23 21 20 29 24 27 6 30 31

Sample Output 3

28

Solution in C++ (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
const int N = 3e5+10; // 不开大点都对不起1024MB。。。 
inline int read()
{
	register int x = 0 , f = 0; register char c = getchar();
	while(c < '0' || c > '9') f |= c == '-' , c = getchar();
	while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
	return f ? -x : x;
}
int n , tot , S , T , cnt = 1;
int p[N] , q[N] , id[2][N] , head[N] , d[N];
struct edge{ int v , nex , c; }e[N << 3];
inline void add(int u , int v , int c)
{
	e[++cnt].v = v; e[cnt].nex = head[u]; e[cnt].c = c; head[u] = cnt;
	e[++cnt].v = u; e[cnt].nex = head[v]; e[cnt].c = 0; head[v] = cnt;
}
void col(int x , int *p , int *id , int c)
{
	id[x] = c;
	if(!id[p[x]]) col(p[x] , p , id , c);
}

bool bfs()
{
	queue<int> q;
	for(int i = 1 ; i <= T ; ++i) d[i] = 0; d[S] = 1; q.push(S);
	while(q.size())
	{
		int x = q.front(); q.pop();
		for(int i = head[x] ; i ; i = e[i].nex) if(e[i].c && !d[e[i].v]) d[e[i].v] = d[x] + 1 , q.push(e[i].v);
	}
	return d[T] != 0;
}

int dfs(int x , int flow)
{
	if(x == T || flow == 0) return flow;
	int res = 0 , k;
	for(int i = head[x] , v; i ; i = e[i].nex)
	{
		v = e[i].v;
		if(e[i].c && d[v] == d[x] + 1)
		{
			k = dfs(v , min(flow , e[i].c));
			if(k) { e[i].c -= k; e[i^1].c += k; res += k; flow -= k; if(flow == 0) return res; }
			else d[v] = 0;
		}
	}
	return res;
}

inline int Dinic() { int ans = 0; while(bfs()) ans += dfs(S , 1e8); return ans; }

int main()
{
	n = read();
	for(int i = 1 ; i <= n ; ++i) p[i] = read() + 1;
	for(int i = 1 ; i <= n ; ++i) q[i] = read() + 1;
	for(int i = 1 ; i <= n ; ++i) if(!id[0][i]) col(i , p , id[0] , ++tot);
	for(int i = 1 ; i <= n ; ++i) if(!id[1][i]) col(i , q , id[1] , ++tot);
	S = tot + 1; T = tot + 2; int ans = n;
	for(int i = 1 ; i <= n ; ++i)
	{
		if(p[i] == i && q[i] == i) ans--;
		else
		if(p[i] == i) add(id[1][i] , T , 1);
		else
		if(q[i] == i) add(S , id[0][i] , 1);
		else
		if(p[i] != q[i])
			add(id[1][i] , id[0][i] , 1);
		else
			add(id[1][i] , id[0][i] , 1) , add(id[0][i] , id[1][i] , 1);
	}
	cout << ans - Dinic() << '\n';
	return 0;
}