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 double eps = 1e-8;
const double PI = acos(0.) * 2;
const int lim = 1000000000;
const int inf = ~0U >> 1;
template <class T>
T abs(T first) {
  return first < 0 ? -first : first;
}
const int N = 100005;
int g[N];
struct node {
  int a[3];
  node() {
    for (int i = 0; i < 3; ++i) a[i] = lim / 10;
  }
  bool operator<(const node &b) const {
    for (int i = 0; i < 3; ++i) {
      if (a[i] < b.a[i]) return true;
      if (a[i] > b.a[i]) return false;
    }
    return false;
  }
};
map<int, node> f;
void read(int type, int i) {
  int first;
  scanf("%d", &first);
  if (!f.count(first)) f[first] = node();
  f[first].a[type] = min(f[first].a[type], i);
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) read(0, i);
  for (int i = 1; i <= n; ++i) read(1, i);
  for (int i = 1; i <= n; ++i) read(2, i);
  vector<node> a;
  for (map<int, node>::iterator i = f.begin(); i != f.end(); ++i)
    a.push_back(i->second);
  sort(a.begin(), a.end());
  map<int, node> F;
  multiset<int> G;
  int tt = 0;
  for (int i = ((int)((a).size())) - 1; i >= 0; --i) {
    tt = max(tt, a[i].a[2]);
    map<int, node>::iterator j;
    j = F.find(a[i].a[1]);
    if (j == F.end()) {
      F[a[i].a[1]] = node();
      j = F.find(a[i].a[1]);
      j->second.a[1] = a[i].a[2];
      G.insert(j->first + j->second.a[0]);
    } else
      j->second.a[1] = max(j->second.a[1], a[i].a[2]);
    G.erase(G.find(j->first + j->second.a[0]));
    map<int, node>::iterator k = j;
    ++k;
    if (k == F.end())
      j->second.a[0] = 0;
    else
      j->second.a[0] = max(k->second.a[0], k->second.a[1]);
    G.insert(j->first + j->second.a[0]);
    int last = -1;
    node tmp = j->second;
    tmp.a[0] = max(j->second.a[0], j->second.a[1]);
    while (1) {
      k = j;
      if (k == F.begin()) break;
      --k;
      if (k->second.a[0] <= max(j->second.a[0], j->second.a[1])) {
        tmp.a[1] = max(tmp.a[1], k->second.a[1]);
        last = k->first;
        G.erase(G.find(k->first + k->second.a[0]));
        F.erase(k);
      } else
        break;
    }
    if (last != -1) {
      F[last] = tmp;
      j = F.find(last);
      G.insert(j->first + j->second.a[0]);
    }
    g[i] = *G.begin();
    if (tt < g[i]) g[i] = tt;
  }
  int ans = g[0];
  for (int i = 0; i < ((int)((a).size())); ++i) {
    ans = min(ans, a[i].a[0] + g[i + 1]);
  }
  printf("%d\n", ans);
  return 0;
}