#include <bits/stdc++.h>
using namespace std;
inline long long rd() {
  long long x = 0;
  int ch = getchar(), f = 1;
  while (!isdigit(ch) && (ch != '-') && (ch != EOF)) ch = getchar();
  if (ch == '-') {
    f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void rt(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10)
    rt(x / 10), putchar(x % 10 + '0');
  else
    putchar(x + '0');
}
const int maxn = 22;
int ans = 0, n, a[maxn][maxn], b[maxn][maxn];
int slack, link[maxn], lx[maxn], ly[maxn], mp[maxn][maxn], suf[maxn], tim;
int visx[maxn], visy[maxn], cnt;
bool find(int u) {
  if (visx[u] == tim) return 0;
  visx[u] = tim;
  cnt++;
  for (int i = 1; i <= (int)n; i++) {
    if (visy[i] == tim) continue;
    int tmp = lx[u] + ly[i] - mp[u][i];
    if (!tmp) {
      visy[i] = tim;
      if (!link[i] || find(link[i])) {
        link[i] = u;
        return 1;
      }
    } else
      slack = min(slack, tmp);
  }
  return 0;
}
int KM(int s) {
  for (int i = 1; i <= (int)n; i++) {
    int now = 0;
    for (int j = 1; j <= (int)n; j++) now += mp[link[j]][j];
    if (now + suf[i] <= ans) return 0;
    for (int j = 1; j <= (int)n; j++)
      mp[i][j] = ((s >> i - 1) & 1) ? a[i][j] : b[i][j];
    for (;;) {
      ++tim, slack = (1 << 29);
      if (find(i)) break;
      for (int j = 1; j <= (int)i; j++)
        if (visx[j] == tim) lx[j] -= slack;
      for (int j = 1; j <= (int)n; j++)
        if (visy[j] == tim) ly[j] += slack;
    }
  }
  int ret = 0;
  for (int i = 1; i <= (int)n; i++) ret += mp[link[i]][i];
  return ret;
}
int main() {
  n = rd();
  for (int i = 1; i <= (int)n; i++)
    for (int j = 1; j <= (int)n; j++)
      a[i][j] = rd(), a[i][0] = max(a[i][0], a[i][j]);
  for (int i = 1; i <= (int)n; i++)
    for (int j = 1; j <= (int)n; j++)
      b[i][j] = rd(), b[i][0] = max(b[i][0], b[i][j]);
  int sx = (1 << n) - 1;
  for (int _ = 0; _ <= (int)sx; _++) {
    int t = 0;
    for (int i = 1; i <= (int)n; i++)
      if ((_ >> i - 1) & 1) t++;
    if (t != n / 2) continue;
    for (int i = 1; i <= (int)n; i++)
      suf[i] = lx[i] = ((_ >> i - 1) & 1) ? a[i][0] : b[i][0],
      ly[i] = link[i] = 0;
    for (int i = n - 1; i >= (int)1; i--) suf[i] += suf[i + 1];
    ans = max(ans, KM(_));
    if (clock() / (double)(CLOCKS_PER_SEC) >= 1.9) break;
  }
  rt(ans);
}
