#include<algorithm>
#include<chrono>
#include<climits>
#include<functional>
#include<numeric>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<random>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<vector>
#include<cassert>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
// #include<bits/stdc++.h>
using namespace std;
 
struct Debug{
    int cnt = 0;
    bool on = false;
    char debug[10] = "debug";
    template<class T>
    Debug & operator<<(const T & v) {
        if(on && cnt++ == 0) cerr << "debug: ";
        if(on) cerr << v << ' ';
        return *this;
    }
    Debug & operator<<(ostream&(*pManip)(ostream&)) {
        if(on) cerr << (*pManip);
        cnt = 0;
        return *this;
    }
} debug;
#define rep(i, a, b) for(auto i = (a); i < (b); i++)
#define rrep(i, a, b) for(auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define print(v) {if(debug.on){for(auto x : v) debug << x; debug << endl;}}
#define printn(v, n) {if(debug.on){for(int _i = 0; _i < n; _i++) debug << *(v + _i); debug << endl;}}
 

typedef unsigned long long ull;
typedef long long ll;
 
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
 
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;


template<class vtype>
struct edge{
	int u, v;
	vtype f, cap;
	edge(int _u, int _v, vtype _f, vtype _cap): u(_u), v(_v), f(_f), cap(_cap) {}
};

template<class vtype>
class Dinic{
public:
	const vtype INF = 1e9;
	int s, t, n, m;
	vector<edge<vtype>> edges;
	vector<vector<int>> graph;
	vector<int> level;
	vector<int> pos;
	Dinic(int _n, int _s, int _t): n(_n), s(_s), t(_t), m(0), graph(n), level(n), pos(n) {}

	void add(int _u, int _v, vtype _cap) {
		edges.emplace_back(_u, _v, 0, _cap);
		edges.emplace_back(_v, _u, 0, 0);
		graph[_u].push_back(m);
		graph[_v].push_back(m + 1);
		m += 2;
	}

	bool bfs() {
		// return true if t is not reachable
		fill(level.begin(), level.end(), -1);
		queue<int> q({s});
		level[s] = 0;
		int len;
		while(q.size()) {
			len = q.size();
			while(len--) {
				int node = q.front();
				q.pop();
				for(int idx : graph[node]) {
					auto & e = edges[idx];
					if(level[e.v] >= 0 || e.cap - e.f <= 0)
						continue;
					level[e.v] = level[e.u] + 1;
					q.push(e.v);
				}
			}
		}
		// print(level);
		return level[t] < 0;
	}

	vtype dfs(int node, vtype val) {
		if(node == t) return val;
		vtype res = 0;
		for(int & idx = pos[node]; idx < graph[node].size(); idx++) {
			auto & e = edges[graph[node][idx]];
			vtype rem = e.cap - e.f;
			if(level[e.v] != level[e.u] + 1 || rem <= 0)
				continue;
			// debug << "consider" << e.u << "to" << e.v << endl;
			vtype tmp = dfs(e.v, min(val, rem));
			if(!tmp) continue;
			val -= tmp;
			res += tmp;
			if(graph[node][idx] & 1) {
				edges[graph[node][idx]].cap -= tmp;
				edges[graph[node][idx] ^ 1].f -= tmp;
			}
			else {
				edges[graph[node][idx]].f += tmp;
				edges[graph[node][idx] ^ 1].cap += tmp;
			}
			if(val <= 0) break;
		}
		return res;
	}

	vtype max_flow() {
		vtype res = 0;
		while(1) {
			// for(int i = 0; i < m; i++)
				// debug << edges[i].u << edges[i].v << edges[i].f << edges[i].cap << endl;
			if(bfs()) break;

			fill(pos.begin(), pos.end(), 0);
			res += dfs(s, INF);
			// while(vtype tmp = dfs(s, INF)) {
			// 	res += tmp;
			// 	// debug << tmp << endl;
			// }
			// debug << res << endl;
		}
		return res;
	}
};

const int MAXN = 1e5 + 20;


void get_group(int n, int * a, int * res, int & cnt) {
	fill(res, res + MAXN, -1);
	for(int i = 0; i < n; i++) {
		if(res[i] >= 0) continue;
		for(int j = a[i]; j != i; j = a[j]) 
			res[j] = cnt;
		res[i] = cnt++;
	}
}

int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    if(argc > 1 && !strcmp(argv[1], debug.debug)) debug.on = true;

    int n;
	int p[MAXN], q[MAXN], gp[MAXN], gq[MAXN];
	int cntp = 0, cntq = 0;

    cin >> n;
    for(int i = 0; i < n; i++)
    	cin >> p[i];
    for(int i = 0; i < n; i++)
    	cin >> q[i];

    // iota(p, p + n, 0);
    // iota(q, q + n, 0);
    // mt19937 rng;
    // shuffle(p, p + n, rng);
    // shuffle(q, q + n, rng);
    // printn(p, 10);
    // printn(q, 10);

    get_group(n, p, gp, cntp);
    get_group(n, q, gq, cntq);

    Dinic<int> dinic(cntp + cntq + 2, 0, cntp + cntq + 1);
    int res = n;

    for(int i = 0; i < n; i++) {
    	if(p[i] == i && q[i] == i)
    		res--;
    	else if(p[i] == i)
    		dinic.add(cntp + 1 + gq[i], cntp + cntq + 1, 1);
    	else if(q[i] == i)
    		dinic.add(0, gp[i] + 1, 1);
    	else if(p[i] != q[i])
    		dinic.add(cntp + 1 + gq[i], gp[i] + 1, 1);
    	else {
    		dinic.add(cntp + 1 + gq[i], gp[i] + 1, 1);
    		dinic.add(gp[i] + 1, cntp + 1 + gq[i], 1);
    	}
    }

    res -= dinic.max_flow();
    cout << res << endl;


    return 0;
}






















Measured memory_bytes: 16236