#include <bits/stdc++.h>
using namespace std;
const int MAX_POINT = numeric_limits<int>::max();
struct Seat {
  int point;
  bool exist_flag;
};
using Position = pair<int, int>;
int N;
Seat field[505][505];
int route_search(Position start_position) {
  for (int h = 0; h < N; h++) {
    for (int w = 0; w < N; w++) {
      field[h][w].point = MAX_POINT;
    }
  }
  field[start_position.first][start_position.second].exist_flag = false;
  field[start_position.first][start_position.second].point = 0;
  deque<Position> que_for_bfs;
  que_for_bfs.push_back(start_position);
  while (!que_for_bfs.empty()) {
    Position present_position = que_for_bfs.front();
    int present_point =
        field[present_position.first][present_position.second].point;
    que_for_bfs.pop_front();
    if (present_position.first + 1 < N && present_position.second < N &&
        field[present_position.first + 1][present_position.second].point >
            present_point +
                field[present_position.first + 1][present_position.second]
                    .exist_flag) {
      field[present_position.first + 1][present_position.second].point =
          present_point +
          field[present_position.first + 1][present_position.second].exist_flag;
      que_for_bfs.push_back(
          {present_position.first + 1, present_position.second});
    }
    if (present_position.first - 1 >= 0 && present_position.second < N &&
        field[present_position.first - 1][present_position.second].point >
            present_point +
                field[present_position.first - 1][present_position.second]
                    .exist_flag) {
      field[present_position.first - 1][present_position.second].point =
          present_point +
          field[present_position.first - 1][present_position.second].exist_flag;
      que_for_bfs.push_back(
          {present_position.first - 1, present_position.second});
    }
    if (present_position.first < N && present_position.second + 1 < N &&
        field[present_position.first][present_position.second + 1].point >
            present_point +
                field[present_position.first][present_position.second + 1]
                    .exist_flag) {
      field[present_position.first][present_position.second + 1].point =
          present_point +
          field[present_position.first][present_position.second + 1].exist_flag;
      que_for_bfs.push_back(
          {present_position.first, present_position.second + 1});
    }
    if (present_position.first < N && present_position.second - 1 >= 0 &&
        field[present_position.first][present_position.second - 1].point >
            present_point +
                field[present_position.first][present_position.second - 1]
                    .exist_flag) {
      field[present_position.first][present_position.second - 1].point =
          present_point +
          field[present_position.first][present_position.second - 1].exist_flag;
      que_for_bfs.push_back(
          {present_position.first, present_position.second - 1});
    }
  }
  int result = MAX_POINT;
  for (int i = 0; i < N; i++) {
    result = min(result, field[0][i].point);
    result = min(result, field[i][0].point);
    result = min(result, field[N - 1][i].point);
    result = min(result, field[i][N - 1].point);
  }
  return result;
}
int main() {
  vector<Position> person;
  cin >> N;
  person.resize(pow(N, 2));
  for (int i = 0; i < pow(N, 2); i++) {
    int P;
    cin >> P;
    person[i].first = (P - 1) / N;
    person[i].second = (P - 1) % N;
  }
  for (int h = 0; h < N; h++) {
    for (int w = 0; w < N; w++) {
      field[h][w].exist_flag = true;
    }
  }
  int result = 0;
  for (auto &&i : person) {
    result += route_search(i);
  }
  cout << result << endl;
  return 0;
}
