#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:60777216")
using namespace std;
int n;
int a[22][22];
int b[22][22];
int c[22][22];
int w[22][22];
int mw[22], wm[22];
int rr[22], cc[22];
bool u[22], U[22];
bool dfs(int v) {
  if (v < 0) return true;
  if (u[v]) return false;
  u[v] = true;
  if (mw[v] != -1) U[mw[v]] = true;
  for (int i = (0); i < (n); i++)
    if (!w[v][i] && dfs(wm[i])) return mw[v] = i, wm[i] = v, true;
  return false;
}
bool iteration() {
  int maxp = 0;
  for (int i = (0); i < (n); i++)
    if (mw[i] != -1 || (memset(u, false, sizeof u), dfs(i))) maxp++;
  if (maxp == n) return true;
  int mn = 1e9;
  memset(u, false, sizeof u), memset(U, false, sizeof U);
  for (int i = (0); i < (n); i++)
    if (mw[i] == -1) dfs(i);
  for (int i = (0); i < (n); i++)
    for (int j = (0); j < (n); j++)
      if (u[i] && !U[j]) mn = min(mn, w[i][j]);
  for (int i = (0); i < (n); i++)
    if (u[i]) rr[i] -= mn;
  for (int j = (0); j < (n); j++)
    if (U[j]) cc[j] += mn;
  for (int i = (0); i < (n); i++)
    for (int j = (0); j < (n); j++) {
      if (u[i]) w[i][j] -= mn;
      if (U[j]) w[i][j] += mn;
    }
  return false;
}
void egervary() {
  memcpy(w, c, sizeof c);
  memset(mw, -1, sizeof mw), memset(wm, -1, sizeof wm);
  while (!iteration())
    ;
}
int main() {
  cin >> 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]);
  vector<int> tt;
  for (int i = (0); i < (1 << n); i++) {
    int nb = 0;
    for (int j = (0); j < (n); j++)
      if (i & (1 << j)) nb++;
    if (nb == n / 2) tt.push_back(i);
  }
  int res = 0;
  for (int mask_index = (0); mask_index < (tt.size()); mask_index++) {
    int mask = tt[mask_index];
    if (mask_index == 0) {
      for (int i = (0); i < (n); i++)
        for (int j = (0); j < (n); j++)
          c[i][j] = 1000000 - ((mask & (1 << j)) ? b[i][j] : a[i][j]);
      egervary();
    } else {
      int prev_mask = tt[mask_index - 1];
      int diff = prev_mask ^ mask;
      for (int j = (0); j < (n); j++)
        if (diff & (1 << j)) {
          mw[wm[j]] = -1;
          wm[j] = -1;
          int mn = 1e9;
          for (int i = (0); i < (n); i++) {
            c[i][j] = 1000000 - ((mask & (1 << j)) ? b[i][j] : a[i][j]);
            w[i][j] = c[i][j] + rr[i];
            mn = min(mn, w[i][j]);
          }
          for (int i = (0); i < (n); i++) w[i][j] -= mn;
        }
      while (!iteration())
        ;
    }
    int cost = 0;
    for (int i = (0); i < (n); i++) cost += 1000000 - c[i][mw[i]];
    res = max(res, cost);
  }
  cout << res << endl;
  return 0;
}
