#include <bits/stdc++.h>
using namespace std;
const int N = 25;
const int mo = 1000000007;
const int inf = (int)1e9;
inline int IN() {
  char ch;
  (ch = getchar());
  int f = 0, x = 0;
  for (; ((ch) == '\n' || (ch) == '\r' || (ch) == '\t' || (ch) == ' ');
       (ch = getchar()))
    ;
  if (ch == '-') f = 1, (ch = getchar());
  for (; !((ch) == '\n' || (ch) == '\r' || (ch) == '\t' || (ch) == ' ');
       (ch = getchar()))
    x = x * 10 + ch - '0';
  return (f) ? (-x) : (x);
}
int Pow(int x, int y, int p) {
  int A = 1;
  for (; y; y >>= 1, x = (long long)x * x % p)
    if (y & 1) A = (long long)A * x % p;
  return A;
}
int n, m, laba[N], labb[N], visa[N], visb[N], tim, mat[N], ans;
int w[N][N], a[N][N], b[N][N], c[N][N], tot_done;
bool extend(int x) {
  if (!x) return 1;
  visa[x] = tim;
  for (int i = (int)1; i <= (int)n; i++) {
    if (visb[i] != tim && laba[x] + labb[i] == w[x][i]) {
      visb[i] = tim;
      if (extend(mat[i])) {
        mat[i] = x;
        return 1;
      }
    }
  }
  return 0;
}
void change() {
  int delta = inf;
  for (int i = (int)1; i <= (int)n; i++)
    if (visa[i] == tim)
      for (int j = (int)1; j <= (int)n; j++)
        if (visb[j] != tim) {
          delta = min(delta, laba[i] + labb[j] - w[i][j]);
        }
  for (int i = (int)1; i <= (int)n; i++)
    if (visa[i] == tim) laba[i] -= delta;
  for (int i = (int)1; i <= (int)n; i++)
    if (visb[i] == tim) labb[i] += delta;
}
int KM() {
  for (int i = (int)1; i <= (int)n; i++) visa[i] = visb[i] = mat[i] = 0;
  for (int i = (int)1; i <= (int)n; i++) laba[i] = w[i][0], labb[i] = 0;
  tim = 0;
  for (int i = (int)1; i <= (int)n; i++) {
    for (;;) {
      ++tim;
      if (extend(i)) break;
      change();
    }
  }
  int re = 0;
  for (int i = (int)1; i <= (int)n; i++) re += w[mat[i]][i];
  return re;
}
void dfs(int x, int cnt) {
  int now = KM();
  if (now <= ans) return;
  if (x == n) {
    ans = now;
    return;
  }
  ++tot_done;
  if (tot_done >= 1e5) return;
  ++x;
  if (m - cnt < n - x + 1) {
    for (int i = (int)0; i <= (int)n; i++) w[x][i] = a[x][i];
    dfs(x, cnt);
  }
  if (cnt < m) {
    for (int i = (int)0; i <= (int)n; i++) w[x][i] = b[x][i];
    dfs(x, cnt + 1);
  }
  for (int i = (int)0; i <= (int)n; i++) w[x][i] = c[x][i];
}
int main() {
  scanf("%d", &n);
  m = n >> 1;
  for (int i = (int)1; i <= (int)n; i++)
    for (int j = (int)1; j <= (int)n; j++) {
      a[i][j] = IN();
      a[i][0] = max(a[i][0], a[i][j]);
    }
  for (int i = (int)1; i <= (int)n; i++)
    for (int j = (int)1; j <= (int)n; j++) {
      b[i][j] = IN();
      b[i][0] = max(b[i][0], b[i][j]);
    }
  for (int i = (int)1; i <= (int)n; i++)
    for (int j = (int)1; j <= (int)n; j++) {
      w[i][j] = c[i][j] = max(a[i][j], b[i][j]);
      w[i][0] = c[i][0] = max(w[i][0], c[i][j]);
    }
  dfs(0, 0);
  printf("%d\n", ans);
  return 0;
}
