// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<iostream>

#include<vector>

#define debug(...) fprintf(stderr,__VA_ARGS__)

using namespace std;

const int inf=1e9;

const int maxn=1e5+50;

const int maxp=maxn<<1;

int n,m;

int N;

int a[maxn];

int b[maxn];

int P[maxn];

int Q[maxn];

int head[maxp];

struct edge

{

	int to,nex,cap,flow;

	edge(int to=0,int nex=0,int cap=0,int flow=0):to(to),nex(nex),cap(cap),flow(flow){}

};

vector<edge> G;

inline void addedge(int u,int v,int c)

{

	G.push_back(edge(v,head[u],c,0)),head[u]=G.size()-1;

	G.push_back(edge(u,head[v],0,0)),head[v]=G.size()-1;

}

namespace dinic

{

	int cur[maxp];

	int dis[maxp];

	bool BFS(int s,int t)

	{

		static int que[maxp];

		int hd=0,tl=0;

		memset(dis,-1,sizeof(dis));

		que[tl++]=s;

		dis[s]=0;

		while(hd<tl)

		{

			int u=que[hd++];

			for(int i=head[u];~i;i=G[i].nex) if(G[i].cap!=G[i].flow)

			{

				int v=G[i].to;

				if(dis[v]==-1)

				{

					dis[v]=dis[u]+1;

					que[tl++]=v;

				}

			}

		}

		return dis[t]!=-1;

	}

	int DFS(int u,int flow,int t)

	{

		if(u==t||flow==0) return flow;

		int rec=flow;

		for(int &i=cur[u];~i;i=G[i].nex)

		{

			int v=G[i].to;

			if(dis[v]==dis[u]+1)

			{

				int d=DFS(v,min(flow,G[i].cap-G[i].flow),t);

				G[i].flow+=d,G[i^1].flow-=d;

				flow-=d;

				if(flow==0) break;

			}

		} 

		return rec-flow;

	}

	int maxflow(int s,int t)

	{

		int flow=0;

		while(BFS(s,t))

		{

			memcpy(cur,head,sizeof(head));

			flow+=DFS(s,inf,t);

		}

		return flow;

	}

}

void findcircle(int &n,int *a,int *P)

{

	for(int i=0;i<N;++i) if(!a[i])

	{

		a[i]=++n;

		for(int u=P[i];u!=i;u=P[u]) a[u]=n;

	}

}

int solve()

{

	findcircle(n,a,P);

	findcircle(m,b,Q);

	memset(head,-1,sizeof(head));

	int an=N;

	int p=n+m;

	for(int i=0;i<N;++i)

	{

		if(P[i]==i&&Q[i]==i) --an;

		else if(P[i]==i)

		{

			addedge(n+b[i],p+1,1);

		}

		else if(Q[i]==i)

		{

			addedge(0,a[i],1);

		}

		else

		{

			addedge(n+b[i],a[i],1);

			if(P[i]==Q[i])

			{

				addedge(a[i],n+b[i],1);

			}

		}

	}

	an-=dinic::maxflow(0,p+1);

	return an;

}

int main()

{

	scanf("%d",&N);

	for(int i=0;i<N;++i) scanf("%d",&P[i]);

	for(int i=0;i<N;++i) scanf("%d",&Q[i]);

	printf("%d\n",solve());

	return 0;

} 

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<cstring>

#include<queue>

#include<map>

#define ull unsigned long long

using namespace std;

const int MAXN=100000+5;

struct Edge

{

	int flow,to,nxt;

}e[MAXN*20];

namespace Flow

{

	int dep[MAXN],tot,fir[MAXN],str,T,cur[MAXN];

	queue<int>q;

	void add(int x,int y,int w)

	{

		tot++;

		e[tot]=(Edge){w,y,fir[x]};

		fir[x]=tot;

		

		tot++;

		e[tot]=(Edge){0,x,fir[y]};

		fir[y]=tot;

	}

	void clr(int n)

	{

		T=n+1;str=0;

		memset(fir,0,sizeof(fir));

		tot=1;

	}

	bool bfs()

	{

		memset(dep,0,sizeof(dep));

		dep[str]=1;

		q.push(str);

		while(q.size())

		{

			int x=q.front();q.pop();

			for(int i=fir[x];i;i=e[i].nxt)

			{

				int v=e[i].to;

				if(e[i].flow==0||dep[v]) continue;

				dep[v]=dep[x]+1;

				q.push(v);

			}

		}

		return dep[T];

	}

	int dfs(int x,int flow)

	{

		if(x==T) return flow;

		int res=0,cnt;

		for(int &i=cur[x];i;i=e[i].nxt)

		{

			int v=e[i].to;

			if(dep[v]!=dep[x]+1||e[i].flow==0) continue;

			cnt=dfs(v,min(flow,e[i].flow));

			if(cnt)

			{

				e[i].flow-=cnt;

				e[i^1].flow+=cnt;

				res+=cnt;

				flow-=cnt;

			}

			if(!flow) return res;

		}

		return res;

	}

	int maxflow()

	{

		int res=0;

		while(bfs())

		{

			for(int i=str;i<=T;i++) cur[i]=fir[i];

			res+=dfs(str,1<<30);

		}

		return res;

	}

}

int n;

struct Node

{

	int p[MAXN],cnt,bel[MAXN];

}A,B;

int main()

{

//	freopen("1.in","r",stdin);

//	freopen("name.out","w",stdout);

	scanf("%d",&n);

	for(int i=1;i<=n;i++) scanf("%d",&A.p[i]),A.p[i]++;

	for(int i=1;i<=n;i++) scanf("%d",&B.p[i]),B.p[i]++;

	for(int i=1;i<=n;i++)

	if(!A.bel[i])

	{

		A.bel[i]=++A.cnt;

		for(int j=A.p[i];!A.bel[j];j=A.p[j])

			A.bel[j]=A.cnt;

	}

	for(int i=1;i<=n;i++)

	if(!B.bel[i])

	{

		B.bel[i]=++B.cnt;B.bel[i]=B.cnt+A.cnt;

		for(int j=B.p[i];!B.bel[j];j=B.p[j])

			B.bel[j]=B.cnt+A.cnt;

	}

	Flow::clr(A.cnt+B.cnt);

	int Ans=n;

	for(int i=1;i<=n;i++)

	if(A.p[i]!=i||B.p[i]!=i)

	{

		if(A.p[i]==i)

		{

			Flow::add(B.bel[i],Flow::T,1);

			continue;

		}

		if(B.p[i]==i)

		{

			Flow::add(0,A.bel[i],1);

			continue;

		}

		if(A.p[i]==B.p[i])

		{

			Flow::add(A.bel[i],B.bel[i],1);

			Flow::add(B.bel[i],A.bel[i],1);

			continue;

		}

		Flow::add(B.bel[i],A.bel[i],1);

	}

	else Ans--;

	printf("%d\n",Ans-Flow::maxflow());

	return 0;

}

	

// Fastest known solution for this problem: