#include <bits/stdc++.h>
using namespace std;
void desperate_optimization(int precision) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cout.setf(ios::fixed);
  cout.setf(ios::showpoint);
  cout.precision(precision);
}
const int N = 500;
int seq[N * N + 5];
int arr[N + 5][N + 5];
int not_empty[N + 5][N + 5];
pair<int, int> pos[N * N + 5];
int ST[2][2 * N + 5][4 * N + 5];
int sz[2][2 * N + 5];
int sudah[N + 5][N + 5];
pair<int, int> idx[N * N + 5];
void update(int t, int k, int idx, int l, int r, int tar, int v) {
  if (l == r) {
    ST[t][k][idx] = v;
    return;
  }
  int mid = (l + r) / 2;
  if (tar <= mid)
    update(t, k, 2 * idx, l, mid, tar, v);
  else
    update(t, k, 2 * idx + 1, mid + 1, r, tar, v);
  ST[t][k][idx] = min(ST[t][k][2 * idx], ST[t][k][2 * idx + 1]);
}
int query(int t, int k, int idx, int l, int r, int le, int ri) {
  if (ri < l || r < le) return 1000;
  if (le <= l && r <= ri) return ST[t][k][idx];
  int mid = (l + r) / 2;
  return min(query(t, k, 2 * idx, l, mid, le, ri),
             query(t, k, 2 * idx + 1, mid + 1, r, le, ri));
}
int py[] = {1, 0, -1, 0};
int px[] = {0, 1, 0, -1};
void dfs(int y, int x, int n) {
  update(0, y + x, 1, 0, sz[0][y + x], idx[arr[y][x]].first, 0);
  update(1, y - x + n, 1, 0, sz[1][y - x + n], idx[arr[y][x]].second, 0);
  sudah[y][x] = 0;
  not_empty[y][x] = 0;
  for (int i = 0; i < 4; i++) {
    int ny = y + py[i];
    int nx = x + px[i];
    if (sudah[ny][nx] == 1) dfs(ny, nx, n);
  }
}
void hora(int tc) {
  int n;
  cin >> n;
  int ctr = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      arr[i][j] = ++ctr;
      sz[0][i + j]++;
      sz[1][i - j + n]++;
      idx[arr[i][j]] = {sz[0][i + j], sz[1][i - j + n]};
      not_empty[i][j] = 1;
      pos[ctr] = {i, j};
      cin >> seq[ctr];
    }
  }
  for (int i = 0; i <= 2 * n; i++) {
    sz[0][i]++, sz[1][i]++;
    for (int j = 0; j <= sz[0][i]; j++) {
      int val = 1000;
      if (j == 0 || j == sz[0][i]) val = 0;
      update(0, i, 1, 0, sz[0][i], j, val);
    }
    for (int j = 0; j <= sz[1][i]; j++) {
      int val = 1000;
      if (j == 0 || j == sz[1][i]) val = 0;
      update(1, i, 1, 0, sz[1][i], j, val);
    }
  }
  int tot = 0;
  for (int i = 1; i <= ctr; i++) {
    int val = seq[i];
    int y = pos[val].first;
    int x = pos[val].second;
    int iter = min(min(y, n - y + 1), min(x, n - x + 1));
    int res = iter;
    for (int j = 1; j <= iter; j++) {
      int uy = y - j;
      int by = y + j;
      int lx = x - j;
      int rx = x + j;
      int l = 0, r = sz[0][lx + y];
      if (uy != 0) l = idx[val - j * n].first;
      if (lx != 0) r = idx[val - j].first;
      res = min(res, query(0, lx + y, 1, 0, sz[0][lx + y], l, r) + j - 1);
      l = 0, r = sz[0][rx + y];
      if (rx != n + 1) l = idx[val + j].first;
      if (by != n + 1) r = idx[val + j * n].first;
      res = min(res, query(0, rx + y, 1, 0, sz[0][rx + y], l, r) + j - 1);
      l = 0, r = sz[1][y - lx + n];
      if (lx != 0) l = idx[val - j].second;
      if (by != n + 1) r = idx[val + j * n].second;
      res =
          min(res, query(1, y - lx + n, 1, 0, sz[1][y - lx + n], l, r) + j - 1);
      l = 0, r = sz[1][uy - x + n];
      if (uy != 0) l = idx[val - j * n].second;
      if (rx != n + 1) r = idx[val + j].second;
      res =
          min(res, query(1, uy - x + n, 1, 0, sz[1][uy - x + n], l, r) + j - 1);
    }
    tot += res;
    update(0, y + x, 1, 0, sz[0][y + x], idx[arr[y][x]].first, res);
    update(1, y - x + n, 1, 0, sz[1][y - x + n], idx[arr[y][x]].second, res);
    sudah[y][x] = 1;
    bool bisa = false;
    for (int j = 0; j < 4; j++) {
      int ny = y + py[j];
      int nx = x + px[j];
      if (not_empty[ny][nx] == 0) bisa = true;
    }
    if (bisa) dfs(y, x, n);
  }
  cout << tot << '\n';
}
int main() {
  desperate_optimization(10);
  int ntc = 1;
  for (int tc = 1; tc <= ntc; tc++) hora(tc);
  return 0;
}
