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;
int n;
int a[100007];
int b[100007];
int c[100007];
int br[3 * 100007];
int fa[3 * 100007];
int fb[3 * 100007];
int fc[3 * 100007];
vector<int> srt;
map<int, int> ZX;
int MXVAL;
void compress() {
  sort(srt.begin(), srt.end());
  int i;
  int id = 1;
  ZX[srt[0]] = 1;
  int sz = srt.size();
  for (i = 1; i < sz; i++) {
    if (srt[i] == srt[i - 1]) {
      continue;
    }
    id++;
    ZX[srt[i]] = id;
  }
  MXVAL = id;
  for (i = 1; i <= n; i++) {
    a[i] = ZX[a[i]];
    b[i] = ZX[b[i]];
    c[i] = ZX[c[i]];
  }
}
class Tree {
 public:
  int tr[3 * 100007];
  int ans[3 * 100007];
  int lazy[3 * 100007];
  void init(int where, int IL, int IR) {
    tr[where] = lazy[where] = 0;
    ans[where] = IL;
    if (IL == IR) {
      return;
    }
    int mid = (IL + IR) / 2;
    init(2 * where, IL, mid);
    init(2 * where + 1, mid + 1, IR);
  }
  void push_lazy(int where, int IL, int IR) {
    if (lazy[where] == 0) {
      return;
    }
    tr[where] = max(tr[where], lazy[where]);
    ans[where] = tr[where] + IL;
    if (IL != IR) {
      lazy[2 * where] = max(lazy[2 * where], lazy[where]);
      lazy[2 * where + 1] = max(lazy[2 * where + 1], lazy[where]);
    }
    lazy[where] = 0;
  }
  void update(int where, int IL, int IR, int CURL, int CURR, int val) {
    push_lazy(where, IL, IR);
    if (CURR < IL || IR < CURL) {
      return;
    }
    if (CURL <= IL && IR <= CURR) {
      lazy[where] = val;
      push_lazy(where, IL, IR);
      return;
    }
    int mid = (IL + IR) / 2;
    update(2 * where, IL, mid, CURL, CURR, val);
    update(2 * where + 1, mid + 1, IR, CURL, CURR, val);
    tr[where] = max(tr[2 * where], tr[2 * where + 1]);
    ans[where] = min(ans[2 * where], ans[2 * where + 1]);
  }
  pair<int, int> getmx(int where, int IL, int IR, int CURL, int CURR) {
    push_lazy(where, IL, IR);
    if (IR < CURL || CURR < IL) {
      return make_pair(0, 1000000007);
    }
    if (CURL <= IL && IR <= CURR) {
      return make_pair(tr[where], ans[where]);
    }
    int mid = (IL + IR) / 2;
    pair<int, int> ret1 = getmx(2 * where, IL, mid, CURL, CURR);
    pair<int, int> ret2 = getmx(2 * where + 1, mid + 1, IR, CURL, CURR);
    ret1.first = max(ret1.first, ret2.first);
    ret1.second = min(ret1.second, ret2.second);
    return ret1;
  }
};
Tree w;
void add(int x) {
  if (fc[x] == 0) {
    w.update(1, 0, n, 0, fb[x] - 1, 1000000007);
    return;
  }
  int l, r, mid;
  l = 0;
  r = n;
  if (fb[x] != 0) {
    r = fb[x] - 1;
  }
  while (r - l > 3) {
    int mid = (l + r) / 2;
    int ret = w.getmx(1, 0, n, mid, mid).first;
    if (ret >= fc[x]) {
      l = mid;
    } else {
      r = mid;
    }
  }
  while (l <= r) {
    int ret = w.getmx(1, 0, n, l, l).first;
    if (ret < fc[x]) {
      break;
    }
    l++;
  }
  int st = l;
  int en = n;
  if (fb[x] != 0) {
    en = fb[x] - 1;
  }
  if (st <= en) {
    w.update(1, 0, n, st, en, fc[x]);
  }
}
void input() {
  scanf("%d", &n);
  int i;
  for (i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    srt.push_back(a[i]);
  }
  for (i = 1; i <= n; i++) {
    scanf("%d", &b[i]);
    srt.push_back(b[i]);
  }
  for (i = 1; i <= n; i++) {
    scanf("%d", &c[i]);
    srt.push_back(c[i]);
  }
  compress();
}
void solve() {
  int i;
  for (i = n; i >= 1; i--) {
    fa[a[i]] = i;
    fb[b[i]] = i;
    fc[c[i]] = i;
    br[a[i]]++;
  }
  w.init(1, 0, n);
  for (i = 1; i <= MXVAL; i++) {
    if (br[i] == 0) {
      add(i);
    }
  }
  int ans = 1000000007;
  for (i = n; i >= 0; i--) {
    int ret = w.getmx(1, 0, n, 0, n).second;
    ret += i;
    if (ans > ret) {
      ans = ret;
    }
    if (i == 0) {
      break;
    }
    br[a[i]]--;
    if (br[a[i]] == 0) {
      if (fb[a[i]] == 0 && fc[a[i]] == 0) {
        break;
      }
      add(a[i]);
    }
  }
  printf("%d\n", ans);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  input();
  solve();
  return 0;
}