#include <bits/stdc++.h>
using namespace std;
//#define cerr if (false) cerr
#define db(x) cerr << #x << "=" << x << endl
#define db2(x, y) cerr << #x << "=" << x << "," << #y << "=" << y << endl
#define db3(x, y, z) cerr << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << endl
#define dbv(v) cerr << #v << "="; for (auto _x : v) cerr << _x << ", "; cerr << endl
#define dba(a, n) cerr << #a << "="; for (int _i = 0; _i < (n); ++_i) cerr << a[_i] << ", "; cerr << endl
template <typename A, typename B>
ostream& operator<<(ostream& os, const pair<A, B>& x) {
	return os << "(" << x.first << "," << x.second << ")";
}
typedef long long ll;
typedef long double ld;
const int MAXN = 100005;
int cycA[MAXN], cycB[MAXN];
void getCycle(int x, const vector<int>& perm, int* cyc, int c) {
	int init = x;
	do {
		cyc[x] = c;
		x = perm[x];
	} while (x != init);
}
template <typename T>
struct Dinic {
	// vertices are 0..n-1
	static const T eps = 1e-9;
	int n, src, sink;
	struct Edge {
		int from, to;
		T f, cap;
	};
	vector<int> dist, Q, work;
	vector<Edge> edges;
	vector<vector<int>> G;
	Dinic(int _n) : n(_n) {
		G.resize(n);
		dist.resize(n);
		Q.resize(n);
		work.resize(n);
	}
	// Returns edge id added (rev edge is id ^ 1)
	int addEdge(int s, int t, T forwardCap, T backwardCap = 0) {
		int id = edges.size();
		G[s].push_back(id);
		edges.push_back({s, t, 0, forwardCap});
		G[t].push_back(id + 1);
		edges.push_back({t, s, 0, backwardCap});
		return id;
	}
	bool dinicBfs() {
		fill(dist.begin(), dist.begin() + n, -1);
		dist[src] = 0;
		int qt = 0;
		Q[qt++] = src;
		for (int qh = 0; qh < qt; ++qh) {
			int u = Q[qh];
			for (int eid : G[u]) {
				Edge& e = edges[eid];
				int v = e.to;
				if (dist[v] < 0 && e.cap - e.f > eps) {
					dist[v] = dist[u] + 1;
					Q[qt++] = v;
				}
			}
		}
		return dist[sink] >= 0;
	}
	T dinicDfs(int u, T f) {
		if (u == sink) return f;
		// Edges 0..work[u] - 1 have been saturated
		for (int& i = work[u]; i < G[u].size(); ++i) {
			int eid = G[u][i];
			Edge& e = edges[eid];
			if (e.cap <= e.f) continue;
			int v = e.to;
			if (dist[v] == dist[u] + 1) {
				T df = dinicDfs(v, min(f, e.cap - e.f));
				if (df > 0) {
					e.f += df;
					edges[eid ^ 1].f -= df;
					return df;
				}
			}
		}
		return 0;
	}
	T maxFlow() {
		assert(src != -1 && sink != -1);
		T result = 0;
		while (dinicBfs()) {
			fill(work.begin(), work.begin() + n, 0);
			for (;;) {
				T delta = dinicDfs(src, numeric_limits<T>::max());
				if (delta <= eps) break;
				result += delta;
			}
		}
		return result;
	}
	vector<bool> minCut() {
		maxFlow();
		vector<bool> ret(n);
		for (int i = 0; i < n; ++i)
			ret[i] = dist[i] >= 0;
		return ret;
	}
	// Matching, A={0..na-1}, B={0..nb-1}.
	int na, nb;
	vector<int> matcha, matchb;
	Dinic(int _na, int _nb) : Dinic(_na + _nb + 2) {
		na = _na;
		nb = _nb;
		src = n - 2;
		sink = n - 1;
		for (int i = 0; i < na; ++i) addEdge(src, i, 1);
		for (int i = 0; i < nb; ++i) addEdge(na + i, sink, 1);
	}
	int addMatchEdge(int s, int t) {
		return addEdge(s, t + na, 1);
	}
	int maxMatching() {
		int ret = maxFlow();
		matcha.resize(na);
		matchb.resize(nb);
		for (int i = 0; i < na; ++i) {
			for (int eid : G[i]) {
				auto& e = edges[eid];
				if (e.to != src && e.f == 1) {
					matcha[i] = e.to - na;
					matchb[e.to - na] = i;
				}
			}
		}
		return ret;
	}
};
int main() {
	int n;
	scanf("%d", &n);
	vector<int> a(n), b(n);
	for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
	for (int i = 0; i < n; ++i) scanf("%d", &b[i]);
	memset(cycA, -1, sizeof(cycA));
	memset(cycB, -1, sizeof(cycB));
	int ca = 0, cb = 0;
	for (int i = 0; i < n; ++i) {
		if (cycA[i] != -1) continue;
		getCycle(i, a, cycA, ca++);
	}
	for (int i = 0; i < n; ++i) {
		if (cycB[i] != -1) continue;
		getCycle(i, b, cycB, cb++);
	}
	int ans = n;
	Dinic<int> g(ca + cb + 2);
	g.src = g.n - 2;
	g.sink = g.n - 1;
	for (int i = 0; i < n; ++i) {
		int x = cycA[i], y = cycB[i];
		if (a[i] == i && b[i] == i) {
			--ans;
		} else if (a[i] == i) {
			g.addEdge(g.src, y + ca, 1);
		} else if (b[i] == i) {
			g.addEdge(x, g.sink, 1);
		} else if (a[i] != b[i]) {
			g.addEdge(x, y + ca, 1);
		} else {
			g.addEdge(x, y + ca, 1);
			g.addEdge(y + ca, x, 1);
		}
	}
	ans -= g.maxFlow();
	printf("%d\n", ans);
}


Measured memory_bytes: 16492