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.
#include <bits/stdc++.h>
using namespace std;
constexpr int kN = int(3E5 + 10);
struct seg_tree {
  int val[kN << 2], flag[kN << 2];
  void addtag(int n, int x) {
    flag[n] += x;
    val[n] += x;
    return;
  }
  void pull(int n) {
    val[n] = min(val[n << 1], val[n << 1 | 1]);
    return;
  }
  void push(int n) {
    if (flag[n]) {
      addtag(n << 1, flag[n]);
      addtag(n << 1 | 1, flag[n]);
      flag[n] = 0;
    }
    return;
  }
  void add(int n, int l, int r, int L, int R, int x) {
    if (L <= l && r <= R)
      addtag(n, x);
    else if (!(l > R || L > r)) {
      int mid = (l + r) >> 1;
      push(n);
      add(n << 1, l, mid, L, R, x);
      add(n << 1 | 1, mid + 1, r, L, R, x);
      pull(n);
    }
  }
  int fval(int n, int l, int r, int pos) {
    if (l == r)
      return val[n];
    else {
      int mid = (l + r) >> 1;
      push(n);
      if (pos <= mid)
        return fval(n << 1, l, mid, pos);
      else
        return fval(n << 1 | 1, mid + 1, r, pos);
    }
  }
  int fpos(int n, int l, int r, int nv) {
    if (l == r)
      return l;
    else {
      int mid = (l + r) >> 1;
      push(n);
      if (val[n << 1] > nv)
        return fpos(n << 1 | 1, mid + 1, r, nv);
      else
        return fpos(n << 1, l, mid, nv);
    }
  }
  pair<int, int> ask(int n, int l, int r, int pos) {
    int nv = fval(n, l, r, pos);
    return make_pair(nv, fpos(n, l, r, nv));
  }
};
int a[kN], b[kN], c[kN], va[kN], vb[kN], vc[kN], sz, idx[kN];
tuple<int, int, int> p[kN];
seg_tree sg_C, sg_BC;
int main() {
  int n, ans = kN, lst, npos;
  pair<int, int> tmp;
  vector<int> v;
  vector<tuple<int, int, int, int>> events;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
  for (int i = 1; i <= n; i++) v.push_back(a[i]);
  for (int i = 1; i <= n; i++) v.push_back(b[i]);
  for (int i = 1; i <= n; i++) v.push_back(c[i]);
  sort(v.begin(), v.end());
  v.resize(unique(v.begin(), v.end()) - v.begin());
  sz = int(v.size());
  for (int i = 1; i <= sz; i++) va[i] = vb[i] = vc[i] = kN;
  for (int i = 1; i <= n; i++)
    a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;
  for (int i = 1; i <= n; i++)
    b[i] = lower_bound(v.begin(), v.end(), b[i]) - v.begin() + 1;
  for (int i = 1; i <= n; i++)
    c[i] = lower_bound(v.begin(), v.end(), c[i]) - v.begin() + 1;
  for (int i = 1; i <= n; i++)
    if (va[a[i]] == kN) va[a[i]] = i;
  for (int i = 1; i <= n; i++)
    if (vb[b[i]] == kN) vb[b[i]] = i;
  for (int i = 1; i <= n; i++)
    if (vc[c[i]] == kN) vc[c[i]] = i;
  for (int i = 1; i <= sz; i++) p[i] = make_tuple(vb[i], vc[i], i);
  sort(p + 1, p + sz + 1);
  for (int i = 1; i <= sz; i++) idx[get<2>(p[i])] = i;
  for (int i = 1; i <= sz; i++)
    events.push_back(make_tuple(va[i], idx[i], vb[i], vc[i]));
  sort(events.begin(), events.end(), greater<tuple<int, int, int, int>>());
  lst = get<0>(events[0]);
  memset(&sg_C, 0, sizeof(sg_C));
  memset(&sg_BC, 0, sizeof(sg_BC));
  ans = min(ans, lst);
  sg_BC.add(1, 0, sz, 1, sz, kN);
  for (tuple<int, int, int, int> i : events) {
    if (get<0>(i) < lst) {
      lst = get<0>(i);
      ans = min(ans, lst + sg_BC.val[1]);
    }
    npos = get<1>(i);
    sg_BC.add(1, 0, sz, npos, npos, get<2>(i) - kN);
    npos--;
    while (0 <= npos) {
      tmp = sg_C.ask(1, 0, sz, npos);
      if (tmp.first < get<3>(i)) {
        sg_C.add(1, 0, sz, tmp.second, npos, get<3>(i) - tmp.first);
        sg_BC.add(1, 0, sz, tmp.second, npos, get<3>(i) - tmp.first);
        npos = tmp.second - 1;
      } else
        break;
    }
  }
  ans = min(ans, sg_BC.val[1]);
  printf("%d\n", ans);
}
