#include <bits/stdc++.h>
using namespace std;
namespace FLOW {
const int maxn = 40010;
int V, cnt, head[maxn], lev[maxn];
struct edge {
  int to, cap, nxt;
} e[maxn * 10];
void init(int _V) {
  V = _V, cnt = 0;
  fill(head, head + V + 1, -1);
}
void add_edge(int u, int v, int cap, bool dir = 0) {
  e[cnt] = (edge){v, cap, head[u]}, head[u] = cnt++;
  e[cnt] = (edge){u, dir * cap, head[v]}, head[v] = cnt++;
}
bool bfs(int s, int t) {
  fill(lev, lev + V + 1, 0);
  queue<int> Q;
  Q.push(s), lev[s] = 1;
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (int i = head[v]; ~i; i = e[i].nxt) {
      if (e[i].cap && !lev[e[i].to]) {
        Q.push(e[i].to), lev[e[i].to] = lev[v] + 1;
      }
    }
  }
  return lev[t];
}
int dfs(int v, int t, int f) {
  if (v == t) return f;
  int inc = 0;
  for (int i = head[v]; ~i && inc < f; i = e[i].nxt) {
    if (e[i].cap && lev[e[i].to] == lev[v] + 1) {
      int d = dfs(e[i].to, t, min(e[i].cap, f - inc));
      if (d)
        e[i].cap -= d, e[i ^ 1].cap += d, inc += d;
      else
        lev[e[i].to] = -1;
    }
  }
  return inc;
}
int dinic(int s, int t) {
  int f = 0;
  while (bfs(s, t)) f += dfs(s, t, INT_MAX);
  return f;
}
vector<bool> get(int s) {
  vector<bool> vis(V + 1);
  queue<int> Q;
  Q.push(s), vis[s] = 1;
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (int i = head[v]; ~i; i = e[i].nxt) {
      if (e[i].cap && !vis[e[i].to]) {
        Q.push(e[i].to), vis[e[i].to] = 1;
      }
    }
  }
  return vis;
}
}  // namespace FLOW
const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
int n, a[210][210], id[210][210];
int main() {
  scanf("%d", &n);
  vector<int> val;
  vector<pair<int, int>> V;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      scanf("%d", &a[i][j]);
      if (!a[i][j]) V.emplace_back(i, j);
      if (a[i][j] > 0) val.push_back(a[i][j]);
    }
  }
  sort(val.begin(), val.end());
  val.resize(unique(val.begin(), val.end()) - val.begin());
  memset(id, -1, sizeof(id));
  function<void(vector<pair<int, int>>, int, int)> solve =
      [&](vector<pair<int, int>> V, int l, int r) {
        if (V.empty() || l == r) {
          for (auto p : V) {
            a[p.first][p.second] = val[l];
          }
          return;
        }
        int mid = (l + r) >> 1;
        for (int i = 0; i < V.size(); i++) {
          id[V[i].first][V[i].second] = i;
        }
        FLOW::init(V.size() + 1);
        int S = V.size(), T = V.size() + 1;
        for (auto p : V) {
          int x = p.first, y = p.second, f1 = 0, f2 = 0;
          for (int k = 0; k < 4; k++) {
            int nx = x + dx[k], ny = y + dy[k];
            if (~id[nx][ny]) {
              if (k & 1) continue;
              FLOW::add_edge(id[x][y], id[nx][ny], 1, 1);
            } else if (~a[nx][ny]) {
              a[nx][ny] <= val[mid] ? f1++ : f2++;
            }
          }
          if (f1 > f2) FLOW::add_edge(S, id[x][y], f1 - f2);
          if (f1 < f2) FLOW::add_edge(id[x][y], T, f2 - f1);
        }
        for (auto p : V) {
          id[p.first][p.second] = -1;
        }
        vector<pair<int, int>> pL, pR;
        FLOW::dinic(S, T);
        auto vis = FLOW::get(S);
        for (int i = 0; i < V.size(); i++) {
          int x = V[i].first, y = V[i].second;
          if (vis[i])
            pL.push_back(V[i]), a[x][y] = val[mid];
          else
            pR.push_back(V[i]), a[x][y] = val[mid + 1];
        }
        solve(pL, l, mid), solve(pR, mid + 1, r);
      };
  solve(V, 0, val.size() - 1);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++)
      if (~a[i][j]) {
        if (i < n && ~a[i + 1][j]) ans += abs(a[i][j] - a[i + 1][j]);
        if (j < n && ~a[i][j + 1]) ans += abs(a[i][j] - a[i][j + 1]);
      }
  }
  printf("%lld\n", ans);
  return 0;
}
