#include <bits/stdc++.h>
using namespace std;
const int KNIGHT = 0;
const int BISHOP = 1;
const int ROOK = 2;
const vector<int> PIECES = {KNIGHT, BISHOP, ROOK};
const int INF = 1e9;
using Cost = pair<int, int>;
using State = pair<int, pair<int, int>>;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(n));
  vector<pair<int, int>> invA(n * n + 1);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      int v;
      cin >> v;
      a[i][j] = v;
      invA[v] = {i, j};
    }
  }
  auto checkCoord = [&](int i, int j) {
    return 0 <= i && i < n && 0 <= j && j < n;
  };
  map<State, Cost> dist;
  set<pair<Cost, State>> q;
  Cost ans = {INF, INF};
  auto tryUpd = [&](Cost c, State st) {
    if (dist.count(st) == 0 || dist[st] > c) {
      if (st.first == n * n && st.second.first == n * n + 1) {
        ans = min(ans, c);
      } else {
        dist[st] = c;
        q.insert({c, st});
      }
    }
  };
  for (auto pc : PIECES) {
    tryUpd({0, 0}, {1, {2, pc}});
  }
  while (q.size() > 0) {
    auto it = q.begin();
    auto curSt = it->second;
    auto curC = it->first;
    q.erase(it);
    if (curC != dist[curSt]) {
      continue;
    }
    auto pr = invA[curSt.first];
    int curI = pr.first, curJ = pr.second;
    int nxtN = curSt.second.first;
    int curPc = curSt.second.second;
    for (auto pc : PIECES) {
      auto nxtC = curC;
      nxtC.first++;
      nxtC.second++;
      auto nxtSt = curSt;
      nxtSt.second.second = pc;
      tryUpd(nxtC, nxtSt);
    }
    vector<pair<int, int>> nxtPos;
    if (curPc == ROOK) {
      for (int d = 0; d < n; d++) {
        nxtPos.emplace_back(curI, d);
        nxtPos.emplace_back(d, curJ);
      }
    } else if (curPc == BISHOP) {
      for (int di = -1; di <= 1; di += 2) {
        for (int dj = -1; dj <= 1; dj += 2) {
          for (int d = 1; d <= n; d++) {
            int nxtI = curI + di * d, nxtJ = curJ + dj * d;
            if (checkCoord(nxtI, nxtJ)) {
              nxtPos.emplace_back(nxtI, nxtJ);
            }
          }
        }
      }
    } else if (curPc == KNIGHT) {
      for (int di = -2; di <= 2; di++) {
        for (int dj = -2; dj <= 2; dj++) {
          if (abs(di) + abs(dj) == 3) {
            int nxtI = curI + di, nxtJ = curJ + dj;
            if (checkCoord(nxtI, nxtJ)) {
              nxtPos.emplace_back(nxtI, nxtJ);
            }
          }
        }
      }
    } else {
      assert(false);
    }
    for (auto pr : nxtPos) {
      int nxtI = pr.first, nxtJ = pr.second;
      auto nxtSt = curSt;
      if (a[nxtI][nxtJ] == nxtN) {
        nxtSt.second.first = nxtN + 1;
      }
      auto nxtC = curC;
      nxtC.first++;
      nxtSt.first = a[nxtI][nxtJ];
      tryUpd(nxtC, nxtSt);
    }
  }
  cout << ans.first << " " << ans.second << endl;
}
