#include <bits/stdc++.h>
using namespace std;
const int kdx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
const int kdy[8] = {2, -2, 2, -2, 1, -1, 1, -1};
const int rdx[8] = {1, 0, -1, 0};
const int rdy[8] = {0, 1, 0, -1};
const int bdx[8] = {1, 1, -1, -1};
const int bdy[8] = {1, -1, 1, -1};
struct Edge {
  int ux, uy, uk;
  int vx, vy, vk;
  int S, C;
  int nex;
} edge[1000005];
int head[15][15][5], cur;
int fstep[15][15][5], frepl[15][15][5];
int N, ch[15][15];
int L[105], R[105];
int ansS[5], ansR[5], ans1, ans2;
void SPFA(int sx, int sy);
void AddEdge(int sx, int sy, int sk, int gx, int gy, int gk, int ss, int rr);
void BuildGraph(int qx, int qy);
void Input();
int main() {
  Input();
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= N; j++) BuildGraph(i, j);
  for (int i = 1; i <= N * N - 1; i++) {
    SPFA(L[i], R[i]);
    for (int k = 0; k <= 2; k++)
      ansS[k] = fstep[L[i + 1]][R[i + 1]][k],
      ansR[k] = frepl[L[i + 1]][R[i + 1]][k];
  }
  ans1 = ans2 = 0x3f3f3f3f;
  for (int k = 0; k <= 2; k++)
    if (ansS[k] < ans1 || ansS[k] == ans1 && ansR[k] < ans2)
      ans1 = ansS[k], ans2 = ansR[k];
  printf("%d %d\n", ans1, ans2);
  return 0;
}
int Que[1000005], Qhead, Qtail, Qmod = 1000000;
bool DurQ[15][15][5];
void SPFA(int sx, int sy) {
  memset(fstep, 0x3f, sizeof(fstep));
  memset(frepl, 0x3f, sizeof(frepl));
  memset(DurQ, false, sizeof(DurQ));
  for (int sk = 0; sk <= 2; sk++)
    fstep[sx][sy][sk] = ansS[sk], frepl[sx][sy][sk] = ansR[sk];
  for (int sk = 0; sk <= 2; sk++) {
    Qhead = Qtail = 1;
    Que[(Qtail++) % Qmod] = sx * 1000 + sy * 10 + sk;
    DurQ[sx][sy][sk] = true;
    while (Qhead != Qtail) {
      int m = Que[(Qhead++) % Qmod];
      int mk = m % 10;
      m /= 10;
      int my = m % 100;
      m /= 100;
      int mx = m;
      DurQ[mx][my][mk] = false;
      for (int e = head[mx][my][mk]; e; e = edge[e].nex) {
        int nx = edge[e].vx, ny = edge[e].vy, nk = edge[e].vk;
        if (fstep[mx][my][mk] + edge[e].S < fstep[nx][ny][nk] ||
            (fstep[mx][my][mk] + edge[e].S == fstep[nx][ny][nk] &&
             frepl[mx][my][mk] + edge[e].C < frepl[nx][ny][nk])) {
          fstep[nx][ny][nk] = fstep[mx][my][mk] + edge[e].S;
          frepl[nx][ny][nk] = frepl[mx][my][mk] + edge[e].C;
          if (!DurQ[nx][ny][nk]) {
            Que[(Qtail++) % Qmod] = nx * 1000 + ny * 10 + nk;
            DurQ[nx][ny][nk];
          }
        }
      }
    }
  }
  return;
}
void AddEdge(int sx, int sy, int sk, int gx, int gy, int gk, int ss, int rr) {
  edge[++cur].nex = head[sx][sy][sk];
  edge[cur].ux = sx;
  edge[cur].uy = sy;
  edge[cur].uk = sk;
  edge[cur].vx = gx;
  edge[cur].vy = gy;
  edge[cur].vk = gk;
  edge[cur].S = ss;
  edge[cur].C = rr;
  head[sx][sy][sk] = cur;
  return;
}
void BuildGraph(int qx, int qy) {
  for (int d = 0; d < 8; d++) {
    int nx = qx + kdx[d], ny = qy + kdy[d];
    if (nx < 1 || N < nx || ny < 1 || N < ny) continue;
    AddEdge(qx, qy, 0, nx, ny, 0, 1, 0);
  }
  for (int d = 0; d < 4; d++)
    for (int i = 1; i <= N; i++) {
      int nx = qx + rdx[d] * i, ny = qy + rdy[d] * i;
      if (nx < 1 || N < nx || ny < 1 || N < ny) break;
      AddEdge(qx, qy, 1, nx, ny, 1, 1, 0);
    }
  for (int d = 0; d < 4; d++)
    for (int i = 1; i <= N; i++) {
      int nx = qx + bdx[d] * i, ny = qy + bdy[d] * i;
      if (nx < 1 || N < nx || ny < 1 || N < ny) break;
      AddEdge(qx, qy, 2, nx, ny, 2, 1, 0);
    }
  AddEdge(qx, qy, 0, qx, qy, 1, 1, 1);
  AddEdge(qx, qy, 0, qx, qy, 2, 1, 1);
  AddEdge(qx, qy, 1, qx, qy, 2, 1, 1);
  AddEdge(qx, qy, 1, qx, qy, 0, 1, 1);
  AddEdge(qx, qy, 2, qx, qy, 0, 1, 1);
  AddEdge(qx, qy, 2, qx, qy, 1, 1, 1);
  return;
}
void Input() {
  scanf("%d", &N);
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= N; j++) {
      scanf("%d", &ch[i][j]);
      L[ch[i][j]] = i;
      R[ch[i][j]] = j;
    }
  return;
}
