#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300 + 10;
const int MAX_NODE = MAXN * MAXN;
const int MAX_EDGE = 4 * MAXN * MAXN;
const int INF = INT_MAX;
struct MaxFlow {
  struct Edge {
    int v, f, n;
    bool disabled;
    Edge(int v = 0, int f = 0, int n = 0) : v(v), f(f), n(n), disabled(false) {}
  };
  vector<Edge> g[MAX_NODE];
  void add_edge(int u, int v, int f) {
    g[u].push_back(Edge(v, f, (int)g[v].size()));
    g[v].push_back(Edge(u, 0, (int)g[u].size() - 1));
  }
  int S, T;
  bool vis[MAX_NODE];
  int64_t ans;
  int dfs(int u, int a) {
    if (u == T || a == 0) return a;
    int flow = 0;
    vis[u] = true;
    for (auto& e : g[u]) {
      if (!e.disabled && e.f && !vis[e.v]) {
        int f = dfs(e.v, min(a, e.f));
        e.f -= f;
        g[e.v][e.n].f += f;
        flow += f;
        a -= f;
        if (a <= 0) break;
      }
    }
    return flow;
  }
  int idfs(int u, int a, int x) {
    if (u == S || a == 0) return a;
    int flow = 0;
    vis[u] = true;
    for (auto& e : g[u]) {
      if (!e.disabled && e.f && !vis[e.v] && (u != T || e.v == x)) {
        int f = idfs(e.v, min(a, e.f), x);
        e.f -= f;
        g[e.v][e.n].f += f;
        flow += f;
        a -= f;
        if (a <= 0) break;
      }
    }
    return flow;
  }
  void shrink(int u) {
    int f;
    do {
      memset(vis, 0, sizeof(vis));
      f = idfs(T, INF, u);
      ans -= f;
    } while (f);
    for (auto& e : g[u]) {
      if (e.v == T) {
        e.disabled = g[e.v][e.n].disabled = true;
      }
    }
    add_edge(S, u, INF);
    do {
      memset(vis, 0, sizeof(vis));
      f = dfs(S, INF);
      ans += f;
    } while (f);
  }
  void init(int s, int t) { S = s, T = t; }
} flow;
int a[MAXN][MAXN];
int b[MAXN * MAXN];
int n;
vector<int> V;
bool cmp(int x, int y) { return b[x] < b[y]; }
inline int id(int x, int y) { return (x - 1) * n + y; }
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      cin >> a[i][j];
      b[id(i, j)] = a[i][j];
    }
  int S = n * n + 1, T = n * n + 2;
  flow.init(S, T);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j < n; j++)
      if (~a[i][j] && ~a[i][j + 1]) {
        flow.add_edge(id(i, j), id(i, j + 1), 1);
        flow.add_edge(id(i, j + 1), id(i, j), 1);
      }
  for (int i = 1; i < n; i++)
    for (int j = 1; j <= n; j++)
      if (~a[i][j] && ~a[i + 1][j]) {
        flow.add_edge(id(i, j), id(i + 1, j), 1);
        flow.add_edge(id(i + 1, j), id(i, j), 1);
      }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (a[i][j] > 0) {
        V.push_back(id(i, j));
        flow.add_edge(id(i, j), T, INF);
      }
  sort(V.begin(), V.end(), cmp);
  int64_t ans = 0;
  int pre = 0;
  for (int u : V) {
    ans += 1LL * (b[u] - pre) * flow.ans;
    flow.shrink(u);
    pre = b[u];
  }
  cout << ans << endl;
}
