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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXT=100005;
const int MAXN=5*MAXT;
const int MAXM=20*MAXT;
const int INF=0X3F3F3F3F;
int N,S,T,top=1,Ans;
int dep[MAXN],vis[MAXN];
int head[MAXN],cur[MAXN];
struct Node{int v,next,val;}node[MAXM];
void Addedge(int u,int v,int val1,int val2){
	node[++top].v=v;node[top].val=val1;node[top].next=head[u];head[u]=top;
	node[++top].v=u;node[top].val=val2;node[top].next=head[v];head[v]=top;
}
int bfs(int u,int v){
	queue<int>Q;
	while(!Q.empty())Q.pop();
	for(int i=S;i<=T;i++)
		cur[i]=head[i],dep[i]=INF,vis[i]=0;
	Q.push(u);dep[u]=v;
	while(!Q.empty()){
		u=Q.front();Q.pop();vis[u]=0;
		for(int i=head[u];i;i=node[i].next){
			v=node[i].v;
			if(dep[v]>dep[u]+1&&node[i].val){
				dep[v]=dep[u]+1;
				if(!vis[v]){
					Q.push(v);
					vis[v]=1;
				}
			}
		}
	}
	if(dep[T]==INF)return 0;
	return 1;
}
int dfs(int u,int flow){
	int rlow=0,used=0;
	if(u==T){
		Ans+=flow;
		return flow;
	}
	for(int i=cur[u];i;i=node[i].next){
		int v=node[i].v;cur[u]=i;
		if(node[i].val&&dep[v]==dep[u]+1)
			if(rlow=dfs(v,min(flow-used,node[i].val))){
				used+=rlow;
				node[i].val-=rlow;
				node[i^1].val+=rlow;
				if(used==flow)break;
			}
	}
	return used;
}
void Dinic(){
	while(bfs(S,0))dfs(S,INF);
}
int K,A[MAXT],B[MAXT];
int main(){
	//freopen("door.in","r",stdin);
	//freopen("door.out","w",stdout);
	scanf("%d",&K);
	for(int i=1;i<=K;i++)scanf("%d",&A[i]),A[i]++;
	for(int i=1;i<=K;i++)scanf("%d",&B[i]),B[i]++;
	S=0;T=K*2;
	for(int i=1;i<=K;i++){
		if(vis[i])continue;
		int t=i;T++;
		while(!vis[t]){
			vis[t]=1;
			Addedge(T,t,INF,INF);
			t=A[t];
		}
	}memset(vis,0,sizeof(vis));
	for(int i=1;i<=K;i++){
		if(vis[i])continue;
		int t=i;T++;
		while(!vis[t]){
			vis[t]=1;
			Addedge(T,t+K,INF,INF);
			t=B[t];
		}
	}memset(vis,0,sizeof(vis));T++;
	for(int i=1;i<=K;i++){
		if(i==A[i]&&i==B[i])//a=1 c=1
			Addedge(S,i,1,0),Addedge(i,T,1,0);
		if(i==A[i]&&i!=B[i])//b=1
			Addedge(S,i+K,1,0);
		if(i!=A[i]&&i==B[i])//c=1
			Addedge(i,T,1,0);
		if(i!=A[i]&&i!=B[i]&&A[i]==B[i])//e=f=1
			Addedge(i,i+K,1,1);
		if(i!=A[i]&&i!=B[i]&&A[i]!=B[i])//f=1
			Addedge(i,i+K,1,0);
	}//s->i (a),s->i+N (b),i->t (c),i+N->t (d),i+N->i (e),i->i+N (f)
	N=T;Dinic();printf("%d\n",K-Ans);
}