#include <bits/stdc++.h>
using namespace std;
const uint64_t seed =
    std::chrono::system_clock::now().time_since_epoch().count();
mt19937_64 rnd(seed);
const int MOD = 998244353;
struct Dinic {
  struct Edge {
    int from, to;
    long long cap, flow;
    Edge(int u, int v, long long c) : from(u), to(v), cap(c), flow(0) {}
  };
  int n, m, s, t;
  vector<vector<int>> g;
  vector<Edge> edges;
  vector<int> dis;
  vector<int> cur;
  int curFlow;
  vector<bool> cut;
  Dinic(int n, int s, int t)
      : n(n), s(s), t(t), g(n), dis(n), cur(n), cut(n, false) {
    curFlow = 0;
    cut[0] = true;
  }
  void addEdge(int from, int to, long long cap) {
    edges.push_back(Edge(from, to, cap));
    edges.push_back(Edge(to, from, 0));
    m = edges.size();
    g[from].push_back(m - 2);
    g[to].push_back(m - 1);
  }
  bool bfs() {
    fill(dis.begin(), dis.end(), n);
    dis[s] = 0;
    queue<int> qq;
    qq.push(s);
    int cnt = 0;
    while (!qq.empty()) {
      cnt++;
      int len = qq.size();
      while (len--) {
        int p = qq.front();
        qq.pop();
        for (int a : g[p]) {
          Edge &e = edges[a];
          if (e.flow >= e.cap) continue;
          if (dis[e.to] == n) {
            dis[e.to] = cnt;
            qq.push(e.to);
          }
        }
      }
    }
    return dis[t] != n;
  }
  long long dfs(int x, long long a) {
    if (x == t || a == 0) return a;
    long long flow = 0, f;
    for (; cur[x] < g[x].size(); cur[x]++) {
      Edge &e = edges[g[x][cur[x]]];
      if (e.cap > e.flow && dis[x] + 1 == dis[e.to] &&
          (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) {
        flow += f;
        e.flow += f;
        edges[g[x][cur[x]] ^ 1].flow -= f;
        a -= f;
        if (a == 0) break;
      }
    }
    return flow;
  }
  long long maxFlow() {
    long long flow = 0;
    while (bfs()) {
      fill(cur.begin(), cur.end(), 0);
      flow += dfs(s, INT_MAX);
    }
    return flow;
  }
  long long dfs2(int x, long long limit, vector<bool> &vis) {
    vis[x] = true;
    if (x == t) return limit;
    for (int ne : g[x]) {
      Edge &e = edges[ne];
      if (e.cap > e.flow && !vis[e.to] && !cut[e.to]) {
        int r = dfs2(e.to, min(limit, e.cap - e.flow), vis);
        if (r > 0) {
          e.flow += r;
          edges[ne ^ 1].flow -= r;
          return r;
        }
      }
    }
    return 0;
  }
  long long work(int node) {
    int e1, e2;
    for (int i = 0; i < g[t].size(); i++) {
      if (edges[g[t][i]].to == node) {
        e1 = g[t][i];
        break;
      }
    }
    for (int i = 0; i < g[node].size(); i++) {
      if (edges[g[node][i]].to == t) {
        e2 = g[node][i];
        break;
      }
    }
    g[t].erase(find(g[t].begin(), g[t].end(), e1));
    g[s].push_back(e1);
    edges[e1].from = s;
    edges[e1].cap = 1e9;
    edges[e2].to = s;
    curFlow -= edges[e2].flow;
    do {
      vector<bool> vis(n, false);
      vis[s] = 0;
      long long f = dfs2(node, edges[e2].cap - edges[e2].flow, vis);
      edges[e2].flow += f;
      edges[e2 ^ 1].flow -= f;
      curFlow += f;
      if (f == 0) {
        swap(cut, vis);
        break;
      }
    } while (true);
    return curFlow;
  }
};
void solve(int caseNum) {
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(n));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      cin >> a[i][j];
    }
  }
  int dd[][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  Dinic dinic(n * n + 2, n * n, n * n + 1);
  vector<pair<int, int>> nodes;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (a[i][j] == -1) continue;
      int n1 = i * n + j;
      if (a[i][j] > 0) {
        dinic.addEdge(n1, n * n + 1, 1e9);
        nodes.push_back({a[i][j], n1});
      }
      for (int k = 0; k < 4; k++) {
        int ii = i + dd[k][0];
        int jj = j + dd[k][1];
        if (ii < 0 || ii >= n || jj < 0 || jj >= n) continue;
        int n2 = ii * n + jj;
        dinic.addEdge(n1, n2, 1);
      }
    }
  }
  sort(nodes.begin(), nodes.end());
  int p = 0;
  long long ans = 0;
  int last = 0;
  long long lastF = 0;
  while (p < nodes.size()) {
    int q = p;
    ans += (nodes[p].first - last) * lastF;
    while (q < nodes.size() && nodes[q].first == nodes[p].first) {
      int node = nodes[q].second;
      dinic.work(node);
      q++;
    }
    lastF = dinic.curFlow;
    last = nodes[p].first;
    p = q;
  }
  cout << ans << "\n";
}
int main() {
  std::ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.precision(10);
  int T = 1;
  for (int i = 1; i <= T; i++) {
    solve(i);
  }
  cout.flush();
  return 0;
}
