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;
const int N = 1e6 + 5;
int n, gs, ans = 1e9, Xma, Yma, ma[N], a[N], b[N], c[N], d[N], La[N], Lb[N],
           Lc[N], lst[N], tree[N * 4], mi[N * 4], lazy[N * 4];
inline int read() {
  int ret = 0, f = 0;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (isdigit(c)) {
    ret = ret * 10 + c - 48;
    c = getchar();
  }
  if (f) return -ret;
  return ret;
}
void build(int nod, int l, int r) {
  if (l == r) {
    tree[nod] = mi[nod] = l;
    return;
  }
  int mid = (l + r) / 2;
  build(nod * 2, l, mid);
  build(nod * 2 + 1, mid + 1, r);
  tree[nod] = min(tree[nod * 2], tree[nod * 2 + 1]);
  mi[nod] = min(mi[nod * 2], mi[nod * 2 + 1]);
}
void pushdown(int nod) {
  if (!lazy[nod]) return;
  mi[nod * 2] = max(mi[nod * 2], tree[nod * 2] + lazy[nod]);
  mi[nod * 2 + 1] = max(mi[nod * 2 + 1], tree[nod * 2 + 1] + lazy[nod]);
  lazy[nod * 2] = max(lazy[nod * 2], lazy[nod]);
  lazy[nod * 2 + 1] = max(lazy[nod * 2 + 1], lazy[nod]);
  ma[nod * 2] = max(ma[nod * 2], lazy[nod]);
  ma[nod * 2 + 1] = max(ma[nod * 2 + 1], lazy[nod]);
  lazy[nod] = 0;
}
void change(int nod, int l, int r, int L, int R, int val) {
  if (l == L && r == R) {
    ma[nod] = max(ma[nod], val);
    mi[nod] = max(mi[nod], tree[nod] + val);
    lazy[nod] = max(lazy[nod], val);
    return;
  }
  pushdown(nod);
  int mid = (l + r) / 2;
  if (R <= mid)
    change(nod * 2, l, mid, L, R, val);
  else if (L > mid)
    change(nod * 2 + 1, mid + 1, r, L, R, val);
  else {
    change(nod * 2, l, mid, L, mid, val);
    change(nod * 2 + 1, mid + 1, r, mid + 1, R, val);
  }
  mi[nod] = min(mi[nod * 2], mi[nod * 2 + 1]);
  ma[nod] = min(ma[nod * 2], ma[nod * 2 + 1]);
}
int find(int nod, int l, int r, int L, int R) {
  if (l == L && r == R) return mi[nod];
  pushdown(nod);
  int mid = (l + r) / 2;
  if (R <= mid)
    return find(nod * 2, l, mid, L, R);
  else if (L > mid)
    return find(nod * 2 + 1, mid + 1, r, L, R);
  else
    return min(find(nod * 2, l, mid, L, mid),
               find(nod * 2 + 1, mid + 1, r, mid + 1, R));
}
int query(int nod, int l, int r, int L, int R) {
  if (l == L && r == R) return ma[nod];
  pushdown(nod);
  int mid = (l + r) / 2;
  if (R <= mid)
    return query(nod * 2, l, mid, L, R);
  else if (L > mid)
    return query(nod * 2 + 1, mid + 1, r, L, R);
  else
    return min(query(nod * 2, l, mid, L, mid),
               query(nod * 2 + 1, mid + 1, r, mid + 1, R));
}
int Find(int l, int r, int val) {
  if (query(1, 0, n, 0, r) >= val) return n + 1;
  while (l < r) {
    int mid = (l + r) / 2;
    if (query(1, 0, n, 0, mid) >= val)
      l = mid + 1;
    else
      r = mid;
  }
  return r;
}
signed main() {
  n = read();
  for (int i = 1; i <= n; i++) {
    a[i] = read();
    d[++gs] = a[i];
  }
  for (int i = 1; i <= n; i++) {
    b[i] = read();
    d[++gs] = b[i];
  }
  for (int i = 1; i <= n; i++) {
    c[i] = read();
    d[++gs] = c[i];
  }
  sort(d + 1, d + gs + 1);
  gs = unique(d + 1, d + gs + 1) - d - 1;
  for (int i = 1; i <= n; i++) a[i] = lower_bound(d + 1, d + gs + 1, a[i]) - d;
  for (int i = 1; i <= n; i++) b[i] = lower_bound(d + 1, d + gs + 1, b[i]) - d;
  for (int i = 1; i <= n; i++) c[i] = lower_bound(d + 1, d + gs + 1, c[i]) - d;
  for (int i = 1; i <= gs; i++) lst[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (lst[a[i]]) continue;
    lst[a[i]] = 1;
    La[a[i]] = i;
  }
  for (int i = 1; i <= gs; i++) lst[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (lst[b[i]]) continue;
    lst[b[i]] = 1;
    Lb[b[i]] = i;
  }
  for (int i = 1; i <= gs; i++) lst[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (lst[c[i]]) continue;
    lst[c[i]] = 1;
    Lc[c[i]] = i;
  }
  build(1, 0, n);
  for (int i = 1; i <= n; i++)
    if ((!La[b[i]]) && (Lb[b[i]] == i)) {
      if (!Lc[b[i]]) Xma = max(Xma, i);
    }
  for (int i = 1; i <= n; i++)
    if ((!La[c[i]]) && (Lc[c[i]] == i)) {
      if (!Lb[c[i]]) Yma = max(Yma, i);
    }
  for (int i = 1; i <= n; i++)
    if ((!La[b[i]]) && (Lb[b[i]] == i)) {
      if (Lc[b[i]]) {
        int x = Find(0, i - 1, Lc[b[i]]);
        if (x <= i - 1) change(1, 0, n, x, i - 1, Lc[b[i]]);
      }
    }
  int x = Find(0, n, Yma);
  if (x <= n) change(1, 0, n, x, n, Yma);
  ans = min(ans, n + max(Xma + Yma, find(1, 0, n, Xma, n)));
  for (int i = n; i; i--) {
    if (La[a[i]] == i) {
      if (!Lb[a[i]]) {
        if (!Lc[a[i]]) break;
        Yma = max(Yma, Lc[a[i]]);
      } else if (!Lc[a[i]])
        Xma = max(Xma, Lb[a[i]]);
      else {
        int x = Find(0, Lb[a[i]] - 1, Lc[a[i]]);
        if (x <= Lb[a[i]] - 1) change(1, 0, n, x, Lb[a[i]] - 1, Lc[a[i]]);
      }
    }
    int x = Find(0, n, Yma);
    if (x <= n) change(1, 0, n, x, n, Yma);
    ans = min(ans, i - 1 + max(Xma + Yma, find(1, 0, n, Xma, n)));
  }
  cout << ans;
}