#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAX_N = 3e5 + 10;
const ll INF = 1e6;

namespace Dinic {
    struct Edge;

    struct Node {
        int dis;
        Edge *head, *curr;
        Node();
    };
    vector<Node *> nodes;
    Node::Node() : head(nullptr) { nodes.push_back(this); }

    struct Edge {
        ll cap;
        Node *to;
        Edge *nxt, *rev;

        Edge(ll cap, Node *from, Node *to) : cap(cap), to(to), nxt(from->head) {
            from->head = this;
        }
    };

    void add_edge(ll cap, Node *a, Node *b) {
        new Edge(cap, a, b);
        new Edge(0, b, a);
        (a->head->rev = b->head)->rev = a->head;
    }

    bool bfs(Node *S, Node *T) {
        for (Node *i : nodes) i->dis = -1, i->curr = i->head;
        S->dis = 0;
        static Node *que[MAX_N];
        int head, tail; que[head = tail = 1] = S;
        while (head <= tail) {
            Node *x = que[head++];
            for (Edge *e = x->head; e; e = e->nxt) {
                if (!e->cap) continue;
                if (e->to->dis == -1) {
                    e->to->dis = x->dis + 1;
                    if (e->to == T) return true;
                    que[++tail] = e->to;
                }
            }
        }
        return false;
    }

    ll dfs(Node *x, Node *T, ll limit = LLONG_MAX) {
        if (x == T) return limit;
        for (Edge *&e = x->curr; e; e = e->nxt) {
            if (!e->cap || e->to->dis != x->dis + 1) continue;
            ll t = dfs(e->to, T, min(limit, e->cap));
            if (t) {
                e->cap -= t;
                e->rev->cap += t;
                return t;
            }
        }
        return 0;
    }

    ll solve(Node *S, Node *T) {
        ll res = 0;
        while (bfs(S, T)) {
            ll t = 0;
            while ((t = dfs(S, T)))
                res += t;
        }
        return res;
    }
}

using Dinic::Node;
using Dinic::Edge;
using Dinic::add_edge;

Edge *find_edge(Node *a, Node *b) {
    Edge *e = a->head;
    for (; e && e->to != b; e = e->nxt);
    return e;
}

int N, P[MAX_N], Q[MAX_N], lidP[MAX_N], lidQ[MAX_N], nlP, nlQ, ans_base;
Node *S, *T, *A[MAX_N], *B[MAX_N];
bool vis[MAX_N];

map<pair<Node *, Node *>, ll> blueprint;

int main() {
    scanf("%d", &N); ans_base = N;
    for (int i = 1; i <= N; i++) scanf("%d", &P[i]), P[i]++;
    for (int i = 1; i <= N; i++) scanf("%d", &Q[i]), Q[i]++;

    fill_n(vis + 1, N, false);
    for (int i = 1; i <= N; i++) {
        if (!vis[i]) {
            nlP++;
            for (int j = i; !vis[j]; vis[j] = true, j = P[j]) lidP[j] = nlP;
        }
    }

    fill_n(vis + 1, N, false);
    for (int i = 1; i <= N; i++) {
        if (!vis[i]) {
            nlQ++;
            for (int j = i; !vis[j]; vis[j] = true, j = Q[j]) lidQ[j] = nlQ;
        }
    }

    S = new Node();
    T = new Node();
    for (int i = 1; i <= nlP; i++)
        A[i] = new Node();
    for (int i = 1; i <= nlQ; i++)
        B[i] = new Node();

    for (int i = 1; i <= N; i++) {
        if (P[i] == i && Q[i] == i) ans_base--;
        else if (P[i] == i) {
            blueprint[make_pair(S, B[lidQ[i]])]++;
        } else if (Q[i] == i) {
            blueprint[make_pair(A[lidP[i]], T)]++;
        } else {
            blueprint[make_pair(A[lidP[i]], B[lidQ[i]])]++;
            if (P[i] == Q[i]) {
                blueprint[make_pair(B[lidQ[i]], A[lidP[i]])]++;
            }
        }
    }

    for (auto bp : blueprint) {
        add_edge(bp.second, bp.first.first, bp.first.second);
    }

    ll ans = ans_base - Dinic::solve(S, T);
    printf("%lld\n", ans);
}


Measured memory_bytes: 29044