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 = 100 * 1000 + 3;
const int inf = 1e9 + 3;
int n, ans;
vector<int> vec;
int arr[3][N], appear[3][N];
struct segmentTree {
  int segMax[N << 2], segMin[N << 2], realMin[N << 2];
  bool lazy[N << 2];
  void update(int k, int lp, int rp, int v = 1, int L = 0, int R = n + 1) {
    realMin[v] = max(realMin[v], L);
    if (R <= lp || rp <= L || segMin[v] >= k) return;
    if (lp <= L && R <= rp && segMax[v] < k) {
      segMax[v] = segMin[v] = k;
      realMin[v] = k + L;
      lazy[v] = true;
      return;
    }
    if (lazy[v]) relax(v, L, R);
    int mid = (L + R) >> 1;
    update(k, lp, rp, v << 1, L, mid);
    update(k, lp, rp, v << 1 | 1, mid, R);
    segMax[v] = max(segMax[v << 1], segMax[v << 1 | 1]);
    segMin[v] = min(segMin[v << 1], segMin[v << 1 | 1]);
    realMin[v] = min(realMin[v << 1], realMin[v << 1 | 1]);
    return;
  }
  void relax(int v, int L, int R) {
    segMin[v << 1] = segMax[v << 1] = segMax[v];
    segMin[v << 1 | 1] = segMax[v << 1 | 1] = segMax[v];
    realMin[v << 1] = L + segMax[v];
    realMin[v << 1 | 1] = (L + R) / 2 + segMax[v];
    lazy[v << 1] = lazy[v << 1 | 1] = true;
    lazy[v] = false;
    return;
  }
} tree;
void input() {
  cin.tie(0);
  cin >> n;
  for (int i = 0; i < 3; i++)
    for (int j = 1; j <= n; j++) cin >> arr[i][j];
  return;
}
void prePros() {
  for (int i = 0; i < 3; i++)
    for (int j = 1; j <= n; j++) vec.push_back(arr[i][j]);
  sort(vec.begin(), vec.end());
  vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
  for (int i = 0; i < 3; i++)
    for (int j = 1; j <= n; j++) {
      arr[i][j] =
          lower_bound(vec.begin(), vec.end(), arr[i][j]) - vec.begin() + 1;
      if (!appear[i][arr[i][j]]) appear[i][arr[i][j]] = j;
    }
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < vec.size(); j++)
      if (!appear[i][j + 1]) appear[i][j + 1] = inf;
  return;
}
void solve() {
  prePros();
  for (int i = 0; i < vec.size(); i++)
    if (appear[0][i + 1] == inf && appear[1][i + 1] == inf)
      tree.update(appear[2][i + 1], 0, n + 1);
  for (int j = n - 1; j >= 0; j--)
    if (appear[0][arr[1][j + 1]] == inf && appear[1][arr[1][j + 1]] == j + 1)
      tree.update(appear[2][arr[1][j + 1]], 0, j + 1);
  ans = tree.realMin[1] + n;
  for (int u = n - 1; u >= 0; u--) {
    if (appear[0][arr[0][u + 1]] == u + 1)
      tree.update(appear[2][arr[0][u + 1]], 0,
                  min(appear[1][arr[0][u + 1]], n + 1));
    ans = min(ans, u + tree.realMin[1]);
  }
  return;
}
int main() {
  ios::sync_with_stdio(false), cout.tie(0);
  input();
  solve();
  cout << ans << endl;
  return 0;
}