#include <bits/stdc++.h>
using namespace std;
template <typename T>
double DIS(T va, T vb) {
  return sqrt((double)(va.x - vb.x) * (va.x - vb.x) +
              (double)(va.y - vb.y) * (va.y - vb.y));
}
template <class T>
inline T INTEGER_LEN(T v) {
  int len = 1;
  while (v /= 10) ++len;
  return len;
}
template <typename T>
inline T square(T va, T vb) {
  return va * va + vb * vb;
}
#pragma comment(linker, "/STACK:1024000000,1024000000")
const double S = 1 - 2. / acos(-1.);
const int der[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct P {
  int r, c;
} p[4];
queue<P> Q;
int g[2012][2012];
bool vis[2012][2012], see[2012][2012];
int N;
template <typename T>
inline double det(T a, T b, T c) {
  return (b.c - a.c) * (c.r - a.r) - (b.r - a.r) * (c.c - a.c);
}
void update(P *u, P &v) {
  if (u[0].r > v.r) u[0] = v;
  if (u[0].r == v.r && u[0].c > v.c) u[0] = v;
  if (u[1].c > v.c) u[1] = v;
  if (u[1].c == v.c && u[1].r < v.r) u[1] = v;
  if (u[2].r < v.r) u[2] = v;
  if (u[2].r == v.r && u[2].c < v.c) u[2] = v;
  if (u[3].c < v.c) u[3] = v;
  if (u[3].c == v.c && u[3].r > v.r) u[3] = v;
}
int bfs(bool vis[][2012], int n, int m, int R, int C) {
  int sum = 0;
  P u, v;
  vis[R][C] = true;
  u.r = R;
  u.c = C;
  Q.push(u);
  update(p, u);
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    for (int i = 0; i < 4; ++i) {
      int r = u.r + der[i][0];
      int c = u.c + der[i][1];
      if (r >= 0 && r < n && c >= 0 && c < m && !vis[r][c] && g[r][c]) {
        vis[r][c] = true;
        v.r = r;
        v.c = c;
        Q.push(v);
        sum++;
        update(p, v);
      }
    }
  }
  return sum;
}
int bfs2(bool vis[][2012], int n, int m, int R, int C) {
  int sum = 0;
  P u, v;
  vis[R][C] = true;
  u.r = R;
  u.c = C;
  Q.push(u);
  update(p, u);
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    for (int i = 0; i < 4; ++i) {
      int r = u.r + der[i][0];
      int c = u.c + der[i][1];
      if (r >= 0 && r < n && c >= 0 && c < m && !vis[r][c] && g[r][c]) {
        vis[r][c] = true;
        v.r = r;
        v.c = c;
        Q.push(v);
        if (det(v, p[0], p[1]) > 0) sum++;
        update(p, v);
      }
    }
  }
  return sum;
}
void init(P *po) {
  po[0].r = 2012, po[0].c = 2012;
  po[1].r = -1, po[1].c = 2012;
  po[2].r = -1, po[2].c = -1;
  po[3].r = 2012, po[3].c = -1;
}
void input(int n, int m) {
  int i, j;
  memset(vis, false, sizeof(vis));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      scanf("%d", &g[i][j]);
    }
  }
}
void solve(int n, int m) {
  int rec = 0, cir = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (g[i][j] && !vis[i][j]) {
        init(p);
        int sum = bfs(vis, n, m, i, j);
        int up = p[0].r, down = p[2].r, lt = p[1].c, rt = p[3].c;
        for (int k = up; k <= down; ++k) {
          for (int L = lt; L <= rt; ++L) {
            see[k][L] = false;
          }
        }
        int area = bfs2(see, n, m, i, j);
        double tmp = 4. * area / sum;
        if (fabs(tmp - S) <= 0.1)
          cir++;
        else
          rec++;
      }
    }
  }
  printf("%d %d\n", cir, rec);
}
int main(void) {
  while (~scanf("%d", &N)) {
    input(N, N);
    solve(N, N);
  }
  return 0;
}
