#include <bits/stdc++.h>
using namespace std;
const int MAX = 31;
int maps[MAX][MAX];
int kndir_x[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int kndir_y[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dp[11][11][105][55][3];
class Node {
 public:
  int x, y, dis, id, type, chang;
  Node(int x, int y, int dis, int id, int type, int chang)
      : x(x), y(y), dis(dis), id(id), type(type), chang(chang) {}
};
int n;
bool check(int x, int y) { return x < 0 || x >= n || y < 0 || y >= n; }
int vis[10][10];
int caonima = 0;
void bfs(int sx, int sy) {
  queue<Node> Q;
  for (int i = 0; i < 3; i++) {
    Q.push(Node(sx, sy, 0, 1, i, 0));
  }
  while (!Q.empty()) {
    Node now = Q.front();
    Q.pop();
    caonima = max(caonima, now.id);
    if (now.chang > 50) continue;
    if (now.type == 0) {
      for (int i = 0; i < 8; i++) {
        int nx = now.x + kndir_x[i];
        int ny = now.y + kndir_y[i];
        if (check(nx, ny)) {
          continue;
        }
        Node cnt = now;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
    } else if (now.type == 1) {
      for (int i = 1; i <= n; i++) {
        Node cnt = now;
        int nx = now.x + i;
        int ny = now.y + i;
        if (check(nx, ny)) break;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
      for (int i = 1; i <= n; i++) {
        Node cnt = now;
        int nx = now.x - i;
        int ny = now.y + i;
        if (check(nx, ny)) break;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
      for (int i = 1; i <= n; i++) {
        Node cnt = now;
        int nx = now.x + i;
        int ny = now.y - i;
        if (check(nx, ny)) break;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
      for (int i = 1; i <= n; i++) {
        Node cnt = now;
        int nx = now.x - i;
        int ny = now.y - i;
        if (check(nx, ny)) break;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
    } else {
      for (int i = 0; i < n; i++) {
        Node cnt = now;
        int nx = now.x;
        int ny = i;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
      for (int i = 0; i < n; i++) {
        Node cnt = now;
        int nx = i;
        int ny = now.y;
        if (cnt.id + 1 == maps[nx][ny]) {
          cnt.id++;
        }
        cnt.x = nx, cnt.y = ny;
        cnt.dis++;
        if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
          dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
          Q.push(cnt);
        }
      }
    }
    for (int k = 0; k < 3; k++) {
      if (k == now.type) continue;
      Node cnt = now;
      cnt.chang++;
      cnt.dis++;
      cnt.type = k;
      if (dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] > cnt.dis) {
        dp[cnt.x][cnt.y][cnt.id][cnt.chang][cnt.type] = cnt.dis;
        Q.push(cnt);
      }
    }
  }
}
int main() {
  scanf("%d", &n);
  int sx, sy, tx, ty;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      scanf("%d", &maps[i][j]);
      if (maps[i][j] == 1) {
        sx = i, sy = j;
      }
      if (maps[i][j] == n * n) {
        tx = i, ty = j;
      }
    }
  }
  memset(dp, 127, sizeof dp);
  for (int i = 0; i < 3; i++) dp[sx][sy][0][0][i] = 0;
  bfs(sx, sy);
  int ans1 = 1e9, ans2 = 1e9, tot = 0;
  while (tot < 50) {
    for (int i = 0; i < 3; i++) {
      if (dp[tx][ty][n * n][tot][i] < ans1) {
        ans1 = dp[tx][ty][n * n][tot][i];
        ans2 = tot;
      } else if (dp[tx][ty][n * n][tot][i] == ans1) {
        ans2 = min(ans2, tot);
      }
    }
    tot++;
  }
  cout << ans1 << " " << ans2 << endl;
}
