#include <bits/stdc++.h>
using namespace std;
const int ju = 1;
const int xiang = 2;
const int ma = 3;
const int inf = 1e9 + 7;
const int MAXN = 1e1 + 10;
int arr[MAXN][MAXN];
struct node {
  int x, y;
};
node pos[MAXN * MAXN];
int change[2][4];
int dir[8][2] = {-1, 2, -1, -2, 1, 2, 1, -2, 2, 1, 2, -1, -2, 1, -2, -1};
int ddir[4][2] = {1, 1, 1, -1, -1, -1, -1, 1};
bool valid(int x, int y, int n) {
  if (1 <= x && x <= n && 1 <= y && y <= n)
    return 1;
  else
    return false;
}
struct qnode {
  int status;
  int x, y;
  int steps;
  int change;
  bool operator<(const qnode& x) const {
    if (steps == x.steps) return change > x.change;
    return steps > x.steps;
  }
};
priority_queue<qnode> q;
qnode calc(int si, int sj, int ei, int ej, int s, int e, int n) {
  qnode now, next;
  now.status = s;
  now.x = si, now.y = sj;
  now.steps = 0;
  now.change = 0;
  while (!q.empty()) q.pop();
  q.push(now);
  int ret = 4;
  bool found = false;
  while (found == false && !q.empty()) {
    now = q.top();
    q.pop();
    if (now.x == ei && now.y == ej && now.status == e) {
      return now;
    }
    if (now.steps >= 4) continue;
    for (int i = 1; i <= 3; i++) {
      if (i == now.status) continue;
      next = now;
      next.status = i;
      next.steps++;
      next.change++;
      q.push(next);
    }
    if (now.status == ju) {
      next = now;
      next.x = ei;
      next.steps++;
      q.push(next);
      next = now;
      next.y = ej;
      next.steps++;
      q.push(next);
    } else if (now.status == ma) {
      for (int i = 0; i < 8; i++) {
        next = now;
        next.x = now.x + dir[i][0];
        next.y = now.y + dir[i][1];
        next.steps = now.steps + 1;
        if (valid(next.x, next.y, n)) q.push(next);
      }
    } else {
      for (int i = 0; i < 4; i++) {
        for (int j = 1;; j++) {
          next = now;
          next.steps++;
          next.x += j * ddir[i][0];
          next.y += j * ddir[i][1];
          if (valid(next.x, next.y, n)) {
            q.push(next);
          } else
            break;
        }
      }
    }
  }
  return now;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      scanf("%d", &arr[i][j]);
      pos[arr[i][j]] = node{i, j};
    }
  int ans[2][4];
  int work = 0;
  for (int i = 1; i <= 3; i++) {
    ans[0][i] = inf;
    ans[1][i] = 0;
  }
  for (int i = 2; i <= n * n; i++) {
    for (int j = 1; j <= 3; j++) ans[work][j] = inf, change[work][j] = inf;
    for (int e = 1; e <= 3; e++) {
      for (int s = 1; s <= 3; s++) {
        qnode tmp =
            calc(pos[i - 1].x, pos[i - 1].y, pos[i].x, pos[i].y, s, e, n);
        if (ans[work][e] > ans[!work][s] + tmp.steps) {
          ans[work][e] = min(ans[work][e], ans[!work][s] + tmp.steps);
          change[work][e] = change[!work][s] + tmp.change;
        } else if (ans[work][e] == ans[!work][s] + tmp.steps)
          change[work][e] = min(change[!work][s] + tmp.change, change[work][e]);
      }
    }
    work = 1 - work;
  }
  int out = inf;
  int changeout = inf;
  int index;
  for (int i = 1; i <= 3; i++) {
    if (out > ans[1 - work][i]) {
      out = min(out, ans[1 - work][i]);
      changeout = change[1 - work][i];
    } else if (out == ans[1 - work][i]) {
      changeout = min(changeout, change[1 - work][i]);
    }
  }
  printf("%d %d\n", out, changeout);
  return 0;
}
