#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
const int N = 30;
int dx[N], dy[N], b[N], v[N][N], a[N][N], B[N][N], n, T, tot, slack[N], f[N],
    g[N], ret, tot2, opt[N];
pair<int, int> perm[N];
int state[185000], val[185000];
bool hungary(int x) {
  if (x == -1) return 1;
  f[x] = 1;
  for (int i = 0; i < n; i++) {
    if (g[i]) continue;
    int t = dx[x] + dy[i] - v[x][i];
    if (!t) {
      g[i] = 1;
      if (hungary(b[i])) {
        b[i] = x;
        return 1;
      }
    } else
      slack[i] = min(slack[i], t);
  }
  return 0;
}
void dfs(int d, int s1, int s2) {
  int s = 0, u = perm[d].second;
  for (int i = 0; i < n; i++) s += dx[i] + dy[i];
  if (s + opt[d] <= ret) return;
  if (d == n) {
    int r = 0;
    for (int i = 0; i < n; i++) r += dx[i] + dy[i];
    ret = max(ret, r);
  }
  int pdx[30], pdy[30], p[30];
  for (int i = 0; i < n; i++) pdx[i] = dx[i], pdy[i] = dy[i], p[i] = b[i];
  if (s1 != n / 2) {
    for (int j = 0; j < n; j++) v[u][j] = a[u][j];
    for (int i = 0; i < n; i++) dx[u] = max(dx[u], v[u][i]);
    memset(slack, 0x20, sizeof(slack));
    for (int i = 0; i < n; i++) f[i] = g[i] = 0;
    while (!hungary(u)) {
      int d = 0x20202020;
      for (int j = 0; j < n; j++)
        if (!g[j]) d = min(d, slack[j]);
      for (int j = 0; j < n; j++) {
        if (f[j]) dx[j] -= d;
        if (g[j]) dy[j] += d;
      }
      for (int j = 0; j < n; j++) f[j] = g[j] = 0;
    }
    dfs(d + 1, s1 + 1, s2);
    for (int i = 0; i < n; i++) dx[i] = pdx[i], dy[i] = pdy[i], b[i] = p[i];
  }
  if (s2 != n / 2) {
    for (int j = 0; j < n; j++) v[u][j] = B[u][j];
    for (int i = 0; i < n; i++) dx[u] = max(dx[u], v[u][i]);
    memset(slack, 0x20, sizeof(slack));
    for (int i = 0; i < n; i++) f[i] = g[i] = 0;
    while (!hungary(u)) {
      int d = 0x20202020;
      for (int j = 0; j < n; j++)
        if (!g[j]) d = min(d, slack[j]);
      for (int j = 0; j < n; j++) {
        if (f[j]) dx[j] -= d;
        if (g[j]) dy[j] += d;
      }
      for (int j = 0; j < n; j++) f[j] = g[j] = 0;
    }
    dfs(d + 1, s1, s2 + 1);
    for (int i = 0; i < n; i++) dx[i] = pdx[i], dy[i] = pdy[i], b[i] = p[i];
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) scanf("%d", &a[i][j]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) scanf("%d", &B[i][j]);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) v[i][j] = max(a[i][j], B[i][j]);
    perm[i] = make_pair(*max_element(v[i], v[i] + n), i);
  }
  sort(perm, perm + n);
  reverse(perm, perm + n);
  for (int i = 0; i < n; i++) b[i] = -1;
  for (int d = n - 1; d >= 0; d--) {
    int u = perm[d].second;
    for (int i = 0; i < n; i++) dx[u] = max(dx[u], v[u][i]);
    memset(slack, 0x20, sizeof(slack));
    for (int i = 0; i < n; i++) f[i] = g[i] = 0;
    while (!hungary(u)) {
      int d = 0x20202020;
      for (int j = 0; j < n; j++)
        if (!g[j]) d = min(d, slack[j]);
      for (int j = 0; j < n; j++) {
        if (f[j]) dx[j] -= d;
        if (g[j]) dy[j] += d;
      }
      for (int j = 0; j < n; j++) f[j] = g[j] = 0;
    }
    opt[d] = 0;
    for (int i = 0; i < n; i++) opt[d] += dx[i] + dy[i];
  }
  for (int i = 0; i < n; i++) b[i] = -1, dx[i] = dy[i] = 0;
  dfs(0, 0, 0);
  printf("%d\n", ret);
}
