#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int DX[] = {-1, -1, -1, 0, 0, 1, 1, 1};
const int DY[] = {-1, 0, 1, -1, 1, -1, 0, 1};
struct Point {
  int x, y;
  Point(int x = 0, int y = 0) : x(x), y(y) {}
  bool operator<(const Point& p) const {
    return x < p.x || (x == p.x && y < p.y);
  }
};
int n;
int a[2000][2000];
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      scanf("%d", &a[i][j]);
    }
  }
  int squareN = 0, circleN = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (a[i][j] == 1) {
        int count = 0;
        queue<Point> q;
        q.push(Point(i, j));
        a[i][j] = 0;
        Point p1(INF, INF);
        Point p2(-INF, -INF);
        while (!q.empty()) {
          Point t = q.front();
          q.pop();
          ++count;
          p1 = min(p1, t);
          p2 = max(p2, t);
          for (int k = 0; k < 8; ++k) {
            int nr = t.x + DX[k];
            int nc = t.y + DY[k];
            if (nr >= 0 && nr < n && nc >= 0 && nc < n && a[nr][nc] == 1) {
              a[nr][nc] = 0;
              q.push(Point(nr, nc));
            }
          }
        }
        double d = hypot(p1.x - p2.x, p1.y - p2.y);
        if (count > d * d * 3.0 / 4) {
          ++circleN;
        } else {
          ++squareN;
        }
      }
    }
  }
  printf("%d %d\n", circleN, squareN);
  return 0;
}
