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;
const int N = 1e5 + 8, M = 3e5 + 8, INF = 10 * N;
int n, m, a[N], b[N], c[N], d[M], flag[M], ans;
struct Node {
  int x, y, p;
  Node(int _x = 0, int _y = 0, int _p = 0) {
    x = _x;
    y = _y;
    p = _p;
  }
  bool operator<(const Node &b) const { return x == b.x ? y < b.y : x < b.x; }
} coo[M];
struct Point {
  int x, y, p1, p2;
  Point() { x = y = p1 = p2 = 0; }
  Point(int _x, int _y, int _p1, int _p2) {
    x = _x;
    y = _y;
    p1 = _p1;
    p2 = _p2;
  }
  bool operator<(const Point &b) const { return x + y > b.x + b.y; }
};
set<Node> bst;
set<Node>::iterator it, tmpit;
priority_queue<Point> q;
int POS(int x) { return lower_bound(d + 1, d + m + 1, x) - d; }
void Insert(Node A) {
  if ((*bst.upper_bound(A)).y >= A.y) return;
  it = (--bst.lower_bound(A));
  tmpit = it;
  while ((*it).y <= A.y) --tmpit, bst.erase(it), it = tmpit;
  q.push(Point((*it).x, A.y, (*it).p, A.p));
  it = bst.upper_bound(A);
  q.push(Point(A.x, (*it).y, A.p, (*it).p));
  bst.insert(A);
}
bool check(Point A) {
  if ((*bst.lower_bound(coo[A.p1])).p != A.p1 ||
      (*bst.lower_bound(coo[A.p2])).p != A.p2)
    return 0;
  return ((*bst.upper_bound(coo[A.p1])).p == A.p2 &&
          (*--bst.lower_bound(coo[A.p2])).p == A.p1);
}
int query() {
  while (!check(q.top())) q.pop();
  return q.top().x + q.top().y;
}
void solve() {
  for (int i = 1; i <= n; i++) flag[POS(a[i])]++;
  for (int i = 1; i <= m; i++) coo[i] = Node(INF, INF, i);
  for (int i = 1; i <= n; i++) {
    int p = POS(b[i]);
    coo[p].x = min(coo[p].x, i);
    p = POS(c[i]);
    coo[p].y = min(coo[p].y, i);
  }
  bst.insert(coo[0] = Node(0, INF + 1, 0));
  bst.insert(coo[m + 1] = Node(INF + 1, 0, m + 1));
  q.push(Point(0, 0, 0, m + 1));
  for (int i = 1; i <= m; i++)
    if (!flag[i]) Insert(coo[i]);
  ans = 3 * n;
  for (int i = n; i >= 0; i--) {
    ans = min(ans, i + query());
    if (!i) break;
    int p = POS(a[i]);
    flag[p]--;
    if (!flag[p]) {
      if (coo[p].x <= n || coo[p].y <= n)
        Insert(coo[p]);
      else
        break;
    }
  }
  printf("%d\n", ans);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]), d[++m] = a[i];
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]), d[++m] = b[i];
  for (int i = 1; i <= n; i++) scanf("%d", &c[i]), d[++m] = c[i];
  sort(d + 1, d + m + 1);
  m = unique(d + 1, d + m + 1) - d - 1;
  solve();
  return 0;
}
