#include <bits/stdc++.h>
char T[1 << 21];
int n, m, ar[21][21];
int U[21], V[21], P[21], way[21], minv[21];
int hungarian(int n, int m, int ar[21][21]) {
  memset(way, 0, sizeof(way)), memset(U, 0, sizeof(U)), memset(V, 0, sizeof(V)),
      memset(P, 0, sizeof(P));
  int i, j, i0, i1, j0, j1, x, y, cur, delta, used, lim = (1 << (m + 1)) - 1;
  for (i = 1; i <= n; i++) {
    used = 0;
    P[0] = i, j0 = 0;
    for (j = 0; j <= m; j++) minv[j] = (1 << 27);
    do {
      used |= (1 << j0);
      i0 = P[j0], j1 = 0, delta = (1 << 27), x = (used | 1) ^ lim;
      while (x) {
        y = (-x & x);
        j = T[y];
        x ^= y;
        cur = ar[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 (j = 0; j <= m; j++) {
        if (used & (1 << j)) {
          U[P[j]] += delta;
          V[j] -= delta;
        } else
          minv[j] -= delta;
      }
      j0 = j1;
    } while (P[j0] != 0);
    do {
      j1 = way[j0];
      P[j0] = P[j1];
      j0 = j1;
    } while (j0 != 0);
  }
  return -V[0];
}
int fri[21][21], sat[21][21];
int main() {
  int i, j, k, x, res, lim, mask;
  for (i = 0; i < 21; i++) T[1 << i] = i;
  while (scanf("%d", &n) != EOF) {
    for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
        scanf("%d", &fri[i][j]);
      }
    }
    for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) {
        scanf("%d", &sat[i][j]);
      }
    }
    res = 0, lim = 1 << n;
    for (mask = 0; mask < lim; mask++) {
      if (__builtin_popcount(mask) == (n >> 1)) {
        for (i = 0; i < n; i++) {
          for (j = 0; j < n; j++) {
            if (mask & (1 << i))
              ar[i + 1][j + 1] = -fri[i][j];
            else
              ar[i + 1][j + 1] = -sat[i][j];
          }
        }
        x = -hungarian(n, n, ar);
        if (x > res) res = x;
      }
    }
    printf("%d\n", res);
  }
  return 0;
}
