#include <bits/stdc++.h>
using namespace std;
using pairint = pair<int, int>;
using queIntDijkstra =
    priority_queue<pairint, vector<pairint>, greater<pairint>>;
int main(void) {
  int N, Pbuf;
  vector<int> P;
  cin >> N;
  for (int i = 0; i < N * N; i++) {
    cin >> Pbuf;
    Pbuf--;
    P.push_back(Pbuf);
  }
  vector<vector<int>> Graph(N * N);
  vector<bool> Exitable(N * N, false);
  for (int i = 0; i < N * N; i++) {
    if (i % N == 0) {
      Exitable[i] = true;
    } else
      Graph[i].push_back(i - 1);
    if (i % N == N - 1) {
      Exitable[i] = true;
    } else
      Graph[i].push_back(i + 1);
    if (i < N) {
      Exitable[i] = true;
    } else
      Graph[i].push_back(i - N);
    if (i >= N * N - N) {
      Exitable[i] = true;
    } else
      Graph[i].push_back(i + N);
  }
  vector<bool> Occupied(N * N, true);
  int res = 0;
  for (int i = 0; i < N * N; i++) {
    vector<bool> Visited(N * N, false);
    queIntDijkstra que;
    que.push(pairint(0, P[i]));
    Occupied[P[i]] = false;
    if (Exitable[P[i]]) {
      for (int around : Graph[P[i]]) {
        Exitable[around] = true;
      }
    }
    int hated = 0;
    while (!que.empty()) {
      pairint curStatus = que.top();
      que.pop();
      if (Visited[curStatus.second]) continue;
      if (Exitable[curStatus.second]) {
        hated = curStatus.first;
        break;
      }
      Visited[curStatus.second] = true;
      for (int nxtPoint : Graph[curStatus.second]) {
        if (Visited[nxtPoint]) continue;
        if (Occupied[nxtPoint]) {
          que.push(pairint(curStatus.first + 1, nxtPoint));
        } else
          que.push(pairint(curStatus.first, nxtPoint));
      }
    }
    res += hated;
  }
  cout << res << endl;
  return 0;
}
