#include <bits/stdc++.h>
using namespace std;
const int N = 20, M = 30, inf = 1000000000, L = 20000;
int nx, ny, cnt;
int link[M], lx[M], ly[M], slack[M];
int visx[M], visy[M], w[M][M];
int DFS(int x) {
  visx[x] = 1;
  for (int y = 1; y <= ny; y++) {
    if (visy[y]) continue;
    int t = lx[x] + ly[y] - w[x][y];
    if (t == 0) {
      visy[y] = 1;
      if (link[y] == -1 || DFS(link[y])) {
        link[y] = x;
        return 1;
      }
    } else if (slack[y] > t)
      slack[y] = t;
  }
  return 0;
}
int KM() {
  int i, j;
  memset(link, -1, sizeof(link));
  memset(ly, 0, sizeof(ly));
  for (i = 1; i <= nx; i++)
    for (j = 1, lx[i] = -inf; j <= ny; j++)
      if (w[i][j] > lx[i]) lx[i] = w[i][j];
  for (int x = 1; x <= nx; x++) {
    for (i = 1; i <= ny; i++) slack[i] = inf;
    while (1) {
      memset(visx, 0, sizeof(visx));
      memset(visy, 0, sizeof(visy));
      if (DFS(x)) break;
      int d = inf;
      for (i = 1; i <= ny; i++)
        if (!visy[i] && d > slack[i]) d = slack[i];
      for (i = 1; i <= nx; i++)
        if (visx[i]) lx[i] -= d;
      for (i = 1; i <= ny; i++)
        if (visy[i])
          ly[i] += d;
        else
          slack[i] -= d;
    }
  }
  int res = 0;
  for (i = 1; i <= ny; i++)
    if (link[i] > -1) res += w[link[i]][i];
  return res;
}
int ai[N + 10][N + 10], n, bi[N + 10][N + 10], ans, flag[N + 10];
int Work() {
  int i, j;
  for (i = 1; i <= n; i++) {
    if (flag[i])
      for (j = 1; j <= n; j++) w[i][j] = ai[i][j];
    else
      for (j = 1; j <= n; j++) w[i][j] = bi[i][j];
  }
  return KM();
}
int main() {
  int i, j, x, y, tmp, ans2 = 0;
  srand(5215251);
  scanf("%d", &n);
  nx = ny = n;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++) scanf("%d", &ai[i][j]);
  for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++) scanf("%d", &bi[i][j]);
  for (i = 1; i <= n / 2; i++) flag[i] = 1;
  cnt = L;
  while (cnt--) {
    x = rand() % (n / 2), y = rand() % (n / 2);
    for (i = 1; i <= n; i++) {
      if (flag[i]) {
        if (x == 0) break;
        x--;
      }
    }
    x = i;
    for (i = 1; i <= n; i++) {
      if (!flag[i]) {
        if (y == 0) break;
        y--;
      }
    }
    y = i;
    flag[x] ^= 1, flag[y] ^= 1;
    tmp = Work();
    if (tmp > ans)
      ans = tmp;
    else {
      if (rand() % L > (L - cnt + 100) / 3)
        flag[x] ^= 1, flag[y] ^= 1;
      else
        ans = tmp;
    }
    ans2 = max(ans2, ans);
  }
  printf("%d\n", ans2);
  return 0;
}
