#include <bits/stdc++.h>
using namespace std;
const int MAXN = 22, INF = 1e9;
int N, L[2][MAXN][MAXN];
int ans;
int A[MAXN][MAXN];
int U[MAXN], V[MAXN], P[MAXN], way[MAXN];
int minv[MAXN];
bool used[MAXN];
void dfs(int i, int fri, int sat) {
  if (i == N + 1) {
    ans = max(ans, V[0]);
    return;
  }
  int oldu[MAXN], oldv[MAXN], oldp[MAXN], oldway[MAXN];
  for (int tu = 0; tu < 2; tu++) {
    if (fri == N / 2 && tu == 0) {
      continue;
    }
    if (sat == N / 2 && tu == 1) {
      continue;
    }
    for (int j = 0; j < N; j++) {
      A[i][j + 1] = -L[tu][i - 1][j];
    }
    for (int j = 0; j <= N; j++) {
      oldu[j] = U[j];
      oldv[j] = V[j];
      oldp[j] = P[j];
      oldway[j] = way[j];
    }
    P[0] = i;
    int j0 = 0;
    fill_n(minv, N + 1, INF);
    fill_n(used, N + 1, false);
    do {
      used[j0] = true;
      int i0 = P[j0], delta = INF, j1;
      for (int j = 1; j <= N; j++) {
        if (!used[j]) {
          int cur = A[i0][j] - U[i0] - V[j];
          if (cur < minv[j]) {
            minv[j] = cur;
            way[j] = j0;
          }
          if (minv[j] < delta) {
            delta = minv[j];
            j1 = j;
          }
        }
      }
      for (int j = 0; j <= N; j++) {
        if (used[j]) {
          U[P[j]] += delta;
          V[j] -= delta;
        } else {
          minv[j] -= delta;
        }
      }
      j0 = j1;
    } while (P[j0]);
    do {
      int j1 = way[j0];
      P[j0] = P[j1];
      j0 = j1;
    } while (j0);
    dfs(i + 1, fri + (tu == 0), sat + (tu == 1));
    for (int j = 0; j <= N; j++) {
      U[j] = oldu[j];
      V[j] = oldv[j];
      P[j] = oldp[j];
      way[j] = oldway[j];
    }
  }
}
int main() {
  if (fopen("input.txt", "r")) {
    freopen("input.txt", "r", stdin);
  }
  scanf("%d", &N);
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
        scanf("%d", &L[i][j][k]);
      }
    }
  }
  dfs(1, 0, 0);
  printf("%d\n", ans);
}
