Problem: There are three arrays a, b and c. Each of them consists of n integers. SmallY wants to find three integers u, v, w (0 ≤ u, v, w ≤ n) such that the following condition holds: each number that appears in the union of a, b and c, appears either in the first u elements of a, or in the first v elements of b, or in the first w elements of c. Of course, SmallY doesn't want to have huge numbers u, v and w, so she wants sum u + v + w to be as small as possible.

Please, help her to find the minimal possible sum of u + v + w.

Input

The first line contains a single integer n (1 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, ..., an — array a. The third line contains the description of array b in the same format. The fourth line contains the description of array c in the same format. The following constraint holds: 1 ≤ ai, bi, ci ≤ 109.

Output

Print a single integer — the minimum possible sum of u + v + w.

Examples

Input

3
1 1 101
1 2 1
3 2 1


Output

5

Input

5
1 1 2 2 3
2 2 4 3 3
3 3 1 1 1


Output

5

Note

In the first example you should choose u = 3, v = 0, w = 2. 

In the second example you should choose u = 1, v = 3, w = 1.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void umax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void umin(T &a, T b) {
  if (a > b) a = b;
}
template <class T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <class T>
inline T gcd(T a, T b) {
  return __gcd(a, b);
}
template <class T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
const int inf = 1e9 + 143;
const long long longinf = 1e18 + 143;
inline int read() {
  int x;
  scanf(" %d", &x);
  return x;
}
const int N = 1 << 19;
const int M = 300300;
const int off = 10;
int a[3][M];
map<int, int> loc[3];
int fen[M];
void put(int x, int v) {
  x += off;
  while (x > 0) {
    umax(fen[x], v);
    x -= x & -x;
  }
}
int get(int x) {
  x += off;
  int s = 0;
  while (x < M) {
    umax(s, fen[x]);
    x += x & -x;
  }
  return s;
}
int T[N << 1], lazy[N << 1];
void upd(int x, int l, int r, int x1, int x2, int v) {
  if (l > x2 || r < x1) return;
  if (l >= x1 && r <= x2) {
    lazy[x] += v;
    return;
  }
  int m = (l + r) >> 1;
  upd(x + x, l, m, x1, x2, v);
  upd(x + x + 1, m + 1, r, x1, x2, v);
  T[x] = min(T[x + x] + lazy[x + x], T[x + x + 1] + lazy[x + x + 1]);
}
void add(int x, int y) {
  int cur = x;
  while (cur >= 0) {
    int val = get(cur);
    if (val > y) break;
    int l = -1, r = cur;
    while (l + 1 < r) {
      int m = (l + r) >> 1;
      if (get(m) == val)
        r = m;
      else
        l = m;
    }
    int from = r;
    upd(1, 0, N - 1, from, cur, y - val);
    cur = from - 1;
  }
  put(x, y);
}
inline int best() { return T[1] + lazy[1]; }
int main() {
  int n = read();
  vector<int> seen;
  for (int i = 0; i < 3; i++) {
    for (int j = 1; j <= n; j++) {
      int x = read();
      a[i][j] = x;
      seen.push_back(x);
      if (!loc[i].count(x)) {
        loc[i][x] = j;
      }
    }
  }
  for (int i = 1; i < N; i++) upd(1, 0, N - 1, i, i, i - 1);
  for (__typeof((seen).begin()) it = (seen).begin(); it != (seen).end(); it++) {
    int x = *it;
    if (!loc[0].count(x)) {
      int p1 = loc[1].count(x) ? loc[1][x] : 3 * n + 5;
      int p2 = loc[2].count(x) ? loc[2][x] : 3 * n + 5;
      add(p1, p2);
    }
  }
  int ans = best() + n;
  for (int i = n; i > 0; i--) {
    int x = a[0][i];
    if (i == loc[0][x]) {
      int p1 = loc[1].count(x) ? loc[1][x] : 3 * n + 5;
      int p2 = loc[2].count(x) ? loc[2][x] : 3 * n + 5;
      add(p1, p2);
    }
    umin(ans, i - 1 + best());
  }
  printf("%d\n", ans);
  return 0;
}