#include <bits/stdc++.h>
using namespace std;
inline int read() {
  char ch = getchar();
  int nega = 1;
  while (!isdigit(ch)) {
    if (ch == '-') nega = -1;
    ch = getchar();
  }
  int ans = 0;
  while (isdigit(ch)) {
    ans = ans * 10 + ch - 48;
    ch = getchar();
  }
  if (nega == -1) return -ans;
  return ans;
}
void print(vector<int> x) {
  for (int i = 0; i < (int)x.size(); i++)
    printf("%d%c", x[i], " \n"[i == (int)x.size() - 1]);
}
namespace Flow {
struct Edge {
  int v, cap, nxt;
};
Edge edge[205 * 205 * 14];
int ss = 1, first[205 * 205], cur[205 * 205], s, t;
void init(int _s, int _t) {
  s = _s, t = _t, ss = 1;
  memset(first, 0, sizeof(first));
}
void add(int u, int v, int w) {
  edge[++ss] = (Edge){v, w, first[u]};
  first[u] = ss;
  edge[++ss] = (Edge){u, 0, first[v]};
  first[v] = ss;
}
int dep[205 * 205], q[205 * 205];
bool bfs() {
  memset(dep, 0, sizeof(dep));
  int l = 1, r = 1;
  q[1] = s, dep[s] = 1;
  while (l <= r) {
    int u = q[l++];
    for (int i = first[u]; i != 0; i = edge[i].nxt) {
      if (!edge[i].cap) continue;
      int v = edge[i].v;
      if (!dep[v]) dep[v] = dep[u] + 1, q[++r] = v;
      if (v == t) return 1;
    }
  }
  return dep[t];
}
int dfs(int u, int flow) {
  if (u == t || flow == 0) return flow;
  int ans = 0;
  for (int &i = cur[u]; i != 0; i = edge[i].nxt) {
    if (!edge[i].cap) continue;
    int v = edge[i].v;
    if (dep[v] != dep[u] + 1) continue;
    int go = dfs(v, min(flow, edge[i].cap));
    if (go) {
      flow -= go, ans += go;
      edge[i].cap -= go, edge[i ^ 1].cap += go;
    }
    if (!flow) return ans;
  }
  return ans;
}
int dinic(int _s, int _t) {
  s = _s, t = _t;
  int ans = 0;
  while (bfs()) {
    memcpy(cur, first, sizeof(cur));
    ans += dfs(s, 0x3f3f3f3f);
  }
  return ans;
}
};  // namespace Flow
using namespace Flow;
int a[205][205], id[205 * 4], eid[205][205], n, m, cnt, tim;
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
long long ans = 0;
int getid(int x, int y) { return (x - 1) * m + y; }
bool valid(int x, int y) { return 1 <= x && x <= n && 1 <= y && y <= m; }
signed main() {
  cin >> n;
  m = n;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      a[i][j] = read();
      if (a[i][j] >= 1) id[++cnt] = a[i][j];
    }
  sort(id + 1, id + cnt + 1);
  int siz = unique(id + 1, id + cnt + 1) - id - 1;
  vector<pair<int, int> > nd;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (a[i][j] == 0) nd.emplace_back(i, j);
  int curflow = 0;
  int s = n * m + 1, t = n * m + 2;
  for (int j = 1; j <= n; j++)
    for (int k = 1; k <= m; k++) {
      if (a[j][k] == -1) continue;
      for (int t = 0; t < 4; t++) {
        int tx = j + dx[t], ty = k + dy[t];
        if (!valid(tx, ty)) continue;
        if (a[tx][ty] != -1) add(getid(j, k), getid(tx, ty), 1);
      }
      if (a[j][k] != 0) eid[j][k] = ss + 1, add(getid(j, k), t, 0x3f3f3f3f);
    }
  int tmp = n * m + 3;
  for (int i = 1; i < siz; i++) {
    for (int j = 1; j <= n; j++)
      for (int k = 1; k <= m; k++) {
        if (a[j][k] == id[i]) {
          int ed = eid[j][k];
          if (edge[ed ^ 1].cap) {
            curflow -= edge[ed ^ 1].cap;
            add(tmp, getid(j, k), edge[ed ^ 1].cap);
            assert(dinic(tmp, getid(j, k)) == edge[ed ^ 1].cap);
          }
          edge[ed].cap = edge[ed ^ 1].cap = 0;
          add(s, getid(j, k), 0x3f3f3f3f);
        }
      }
    int r = dinic(s, t);
    curflow += r;
    ans += 1LL * curflow * (id[i + 1] - id[i]);
  }
  cout << ans << endl;
  return 0;
}
