#include <bits/stdc++.h>
using namespace std;
inline int read() {
  char ch = getchar();
  int x = 0, f = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
namespace KM {
int n;
int A[25], B[25];
int w[25][25];
int link[25];
bool vis[25], vis1[25];
int mn;
int ans;
inline void init() { memset(w, 0, sizeof(w)); }
inline bool find(int x) {
  vis[x] = true;
  for (int i = 1; i <= n; i++) {
    if (vis1[i]) continue;
    int t = A[x] + B[i] - w[x][i];
    if (!t) {
      vis1[i] = true;
      if (!~link[i] || find(link[i])) {
        link[i] = x;
        return true;
      }
    } else
      mn = min(mn, t);
  }
  return false;
}
inline void km() {
  memset(link, -1, sizeof(link));
  memset(A, 0, sizeof(A));
  memset(B, 0, sizeof(B));
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      A[i] = max(A[i], w[i][j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    while (1) {
      memset(vis, 0, sizeof(vis));
      memset(vis1, 0, sizeof(vis1));
      mn = 214748364;
      if (find(i)) break;
      int res = 0;
      for (int j = 1; j <= n; j++) {
        if (vis[j]) A[j] -= mn;
        if (vis1[j]) B[j] += mn;
        res += A[j];
        res += B[j];
      }
      if (res < ans) return;
    }
  }
}
inline int getsum() {
  int ret = 0;
  for (int i = 1; i <= n; i++) ret += A[i], ret += B[i];
  return ret;
}
}  // namespace KM
int a[25][25];
int b[25][25];
inline int num1(int x) {
  int ret = 0;
  while (x) {
    ret += (x & 1);
    x >>= 1;
  }
  return ret;
}
int main() {
  int start = clock();
  int n = read();
  KM::n = n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      a[i][j] = read();
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      b[i][j] = read();
    }
  }
  int tot;
  for (int i = (1 << n) - 1; i >= 0; i--) {
    if (__builtin_popcount(i) == (n >> 1)) {
      KM::init();
      tot = 0;
      for (int j = 0; j < n; j++) {
        if (i & (1 << j)) {
          tot++;
          for (int k = 1; k <= n; k++) {
            KM::w[j + 1][k] = a[j + 1][k];
          }
        } else {
          tot++;
          for (int k = 1; k <= n; k++) {
            KM::w[j + 1][k] = b[j + 1][k];
          }
        }
      }
      KM::km();
      int res = KM::getsum();
      KM::ans = max(KM::ans, res);
      if (clock() - start > 1970) break;
    }
  }
  printf("%d\n", KM::ans);
  return 0;
}
