#include <bits/stdc++.h>
using namespace std;
int POWINT(int x, int n) {
  int ret = 1;
  while (n > 0) {
    if (n & 1) ret *= x;
    x *= x;
    n >>= 1;
  }
  return ret;
};
long long POWLL(long long x, int n) {
  long long ret = 1;
  while (n > 0) {
    if (n & 1) ret *= x;
    x *= x;
    n >>= 1;
  }
  return ret;
};
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
};
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
};
void print() { cout << "\n"; };
template <class T>
void print(vector<T> &vec) {
  for (auto &a : vec) {
    cout << a;
    if (&a != &vec.back()) cout << " ";
  }
  cout << "\n";
};
template <class T>
void print(vector<T> &vec, long long k) {
  long long n = vec.size();
  k = min(k, n);
  for (int i = (long long)0; i < (long long)k - 1; i++) cout << vec[i] << " ";
  cout << vec[k - 1] << "\n";
};
template <class T>
void print(vector<vector<T>> &df) {
  for (auto &vec : df) {
    print(vec);
  }
};
template <class T, class U>
void print(pair<T, U> &p) {
  cout << p.first << " " << p.second << "\n";
};
class Dijkstra {
  long long INF = (1ll << 58);
  int WHITE = 0;
  int GRAY = 1;
  int BLACK = 2;

 public:
  int V;
  vector<vector<pair<int, long long>>> graph;
  vector<int> color;
  vector<long long> dist;
  vector<int> parent;
  Dijkstra(int v) : V(v) {
    graph.resize(v);
    color.resize(v);
    dist.resize(v);
    parent.resize(v);
  }
  void add_edge(int from, int to, long long cost) {
    graph[from].push_back(make_pair(to, cost));
  }
  void min_path(int s) {
    priority_queue<pair<long long, int>> PQ;
    for (int i = 0; i < V; i++) {
      dist[i] = INF;
      color[i] = 0;
    }
    dist[s] = 0;
    PQ.push(make_pair(0ll, s));
    color[s] = GRAY;
    while (!PQ.empty()) {
      auto f = PQ.top();
      PQ.pop();
      int u = f.second;
      color[u] = BLACK;
      for (int j = 0; j < graph[u].size(); j++) {
        int v = graph[u][j].first;
        if (color[v] == BLACK) continue;
        if (dist[v] > dist[u] + graph[u][j].second) {
          dist[v] = dist[u] + graph[u][j].second;
          parent[v] = u;
          PQ.push(make_pair(dist[v] * (-1ll), v));
          color[v] = GRAY;
        }
      }
    }
  }
};
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  vector<vector<int>> grid(N, vector<int>(N, 1));
  int NN = N * N;
  vector<int> A(NN);
  for (int i = (long long)0; i < (long long)NN; i++) {
    cin >> A[i];
    A[i]--;
  }
  long long ans = 0;
  for (int i = (long long)0; i < (long long)NN; i++) {
    int a = A[i];
    int ax = a % N;
    int ay = a / N;
    Dijkstra di(NN + 1);
    for (int j = (long long)0; j < (long long)NN; j++) {
      int x = j % N;
      int y = j / N;
      if (x == 0 || x == N - 1 || y == 0 || y == N - 1) di.add_edge(j, NN, 0);
      for (int k = (long long)0; k < (long long)4; k++) {
        int xx = x + dx[k];
        int yy = y + dy[k];
        if (0 <= xx && xx < N && 0 <= yy && yy < N) {
          int nxt = yy * N + xx;
          if (grid[yy][xx]) {
            di.add_edge(j, nxt, 1);
          } else {
            di.add_edge(j, nxt, 0);
          }
        }
      }
    }
    grid[ay][ax] = 0;
    di.min_path(a);
    ans += di.dist[NN];
  }
  cout << ans << "\n";
  return 0;
};
