#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>

using namespace std;

typedef long double ld;

#ifdef DEBUG
#define eprintf(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#else
#define eprintf(...) ;
#endif

#define sz(x) ((int) (x).size())
#define TASK "text"

const int inf = (int) 1.01e9;
const long long infll = (long long) 1.01e18;
const ld eps = 1e-9;
const ld pi = acos((ld) -1);

#ifdef DEBUG
mt19937 mrand(300); 
#else
mt19937 mrand(chrono::steady_clock::now().time_since_epoch().count()); 
#endif

int rnd(int x) {
  return mrand() % x;
}

void precalc() {
}

namespace Flow {
  struct edge {
    int to, c, f;

    edge(int _to, int _c): to(_to), c(_c), f(0) {}
  };

  const int maxn = (int) 2e5 + 5;
  int n;
  vector<edge> es;
  vector<int> g[maxn];

  void init(int _n) {
    n = _n;
    es.clear();
    for (int i = 0; i < n; i++) {
      g[i].clear();
    }
  }

  void addEdge(int v, int u, int c) {
    g[v].push_back(sz(es));
    es.push_back(edge(u, c));
    g[u].push_back(sz(es));
    es.push_back(edge(v, 0));
  }

  int d[maxn];
  int q[maxn];

  bool bfs(int s, int t) {
    for (int i = 0; i < n; i++) {
      d[i] = inf;
    }
    d[s] = 0;
    int ql = 0, qr = 0;
    q[qr++] = s;
    for (; ql < qr; ql++) {
      int v = q[ql];
      for (int i = 0; i < sz(g[v]); i++) {
        int e = g[v][i];
        int u = es[e].to, cf = es[e].c - es[e].f;
        if (cf && d[v] + 1 < d[u]) {
          d[u] = d[v] + 1;
          q[qr++] = u;
        }
      }
    }
    return d[t] < inf;
  }

  int p[maxn];

  int dfs(int v, int t, int mincf) {
    if (v == t) {
      return mincf;
    }
    int res = 0;
    for (auto &i = p[v]; i < sz(g[v]) && mincf; i++) {
      int e = g[v][i];
      int u = es[e].to, cf = es[e].c - es[e].f;
      if (d[u] != d[v] + 1 || !cf) {
        continue;
      }
      int f = dfs(u, t, min(mincf, cf));
      if (!f) {
        continue;
      }
      res += f;
      es[e].f += f;
      es[e ^ 1].f -= f;
      mincf -= f;
    }
    return res;
  }

  int maxFlow(int s, int t) {
    int res = 0;
    while (bfs(s, t)) {
      for (int i = 0; i < n; i++) {
        p[i] = 0;
      }
      while (int f = dfs(s, t, inf)) {
        res += f;
      }
    }
    return res;
  }
}

const int maxn = (int) 1e5 + 5;
int n;
int p[2][maxn];

bool read() {
  if (scanf("%d", &n) < 1) {
    return false;
  }
  for (int t = 0; t < 2; t++) {
    for (int i = 0; i < n; i++) {
      scanf("%d", &p[t][i]);
    }
  }
  return true;
}

int ids[2][maxn];
int cs[2];
int used[maxn];

void solve() {
  for (int t = 0; t < 2; t++) {
    for (int i = 0; i < n; i++) {
      used[i] = false;
    }
    cs[t] = 0;
    for (int s = 0; s < n; s++) {
      if (used[s]) {
        continue;
      }
      int v = s;
      while (!used[v]) {
        ids[t][v] = cs[t];
        used[v] = true;
        v = p[t][v];
      }
      cs[t]++;
    }
  }
  Flow::init(cs[0] + cs[1] + 2);
  int s = cs[0] + cs[1], t = s + 1;
  for (int i = 0; i < n; i++) {
    Flow::addEdge(cs[0] + ids[1][i], ids[0][i], 1);
    if (p[0][i] == p[1][i]) {
      Flow::addEdge(ids[0][i], cs[0] + ids[1][i], 1);
    }
    if (p[0][i] == i) {
      Flow::addEdge(ids[0][i], t, inf);
    }
    if (p[1][i] == i) {
      Flow::addEdge(s, cs[0] + ids[1][i], inf);
    }
  }
  printf("%d\n", n - Flow::maxFlow(s, t));
}

int main() {
  precalc();
#ifdef DEBUG
  assert(freopen(TASK ".in", "r", stdin));
  assert(freopen(TASK ".out", "w", stdout));
#endif
  while (read()) {
    solve();
#ifdef DEBUG
    eprintf("Time %.2f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
  }
  return 0;
}


Measured memory_bytes: 19756