#include <bits/stdc++.h>
struct UnionFind {
  std::vector<int> par;
  std::vector<bool> b;
  int N;
  UnionFind(int N) {
    for (int i = 0; i < N * N + 1; i++) {
      par.push_back(i);
      b.push_back(false);
    }
    this->N = N;
  }
  void deleted(int x) { b[x] = true; }
  int root(int x) {
    if (par[x] == x) return x;
    return par[x] = root(par[x]);
  }
  bool rootb(int x) {
    int rx = root(x);
    if (rx == 1 || rx == N || rx == N * N || rx == N * N - N + 1) return true;
    return false;
  }
  void unite(int x, int y, bool o) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) return;
    if (o) {
      if (b[y]) {
        par[ry] = rx;
      } else {
        par[y] = rx;
      }
    } else {
      if (!rootb(y)) {
        par[ry] = rx;
      }
    }
  }
  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  void display() {
    for (int i = 0; i <= N * N; i++) {
      std::cout << root(i) << " ";
    }
    std::cout << std::endl;
  }
};
int main(void) {
  int N;
  int cnt = 0;
  std::cin >> N;
  UnionFind uf(N);
  for (int i = 0; i < N * N; i++) {
    int P;
    std::cin >> P;
    bool isDisliked = uf.rootb(P);
    if ((P - 1) / N != 0) uf.unite(P, P - N, isDisliked);
    if ((P - 1) % N != 0) uf.unite(P, P - 1, isDisliked);
    if (P % N != 0) uf.unite(P, P + 1, isDisliked);
    if (P + N <= N * N) uf.unite(P, P + N, isDisliked);
    if (!isDisliked) cnt++;
    uf.deleted(P);
  }
  std::cout << cnt << std::endl;
  return 0;
}
