#include <bits/stdc++.h>
#pragma comment(linker, "/stack:64000000")
using namespace std;
template <typename X>
inline X abs(const X& a) {
  return a < 0 ? -a : a;
}
template <typename X>
inline X sqr(const X& a) {
  return a * a;
}
const int INF = int(1e9);
const long long INF64 = long long(1e18);
const long double EPS = 1e-9, PI = 3.1415926535897932384626433832795;
const int N = 2000 + 3;
int n;
int a[N][N];
inline bool read() {
  if (scanf("%d", &n) != 1) return false;
  for (int i = 0; i < int(n); i++)
    for (int j = 0; j < int(n); j++) assert(scanf("%d", &a[i][j]) == 1);
  return true;
}
inline bool val(int first, int second) {
  int cnt0 = 0, cnt1 = 0;
  for (int dx = -4; dx <= 4; dx++)
    for (int dy = -4; dy <= 4; dy++) {
      int xx = first + dx, yy = second + dy;
      if (!(0 <= (xx) && (xx) < (n) && 0 <= (yy) && (yy) < (n)) ||
          a[xx][yy] == 0)
        cnt0++;
      else
        cnt1++;
    }
  return cnt1 - 10 > cnt0;
}
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
vector<pair<long double, long double> > border;
int used[N][N];
int cnt;
long double minx, maxx;
long double miny, maxy;
void dfs(int first, int second) {
  bool is = false;
  used[first][second] = true;
  cnt++;
  minx = min(minx, (long double)first), maxx = max(maxx, (long double)first);
  miny = min(miny, (long double)second), maxy = max(maxy, (long double)second);
  for (int i = 0; i < int(8); i++) {
    int xx = first + dx[i], yy = second + dy[i];
    if (!(0 <= (xx) && (xx) < (n) && 0 <= (yy) && (yy) < (n)) ||
        val(xx, yy) == 0) {
      is = true;
      continue;
    }
    if (used[xx][yy]) continue;
    dfs(xx, yy);
  }
  if (is) border.push_back(make_pair((first), (second)));
}
inline long double dist(const pair<long double, long double>& a,
                        const pair<long double, long double>& b) {
  return sqrt(sqr(a.first - b.first) + sqr(a.second - b.second));
}
inline bool checkCircle() {
  long double first = 0.0, second = 0.0;
  for (int i = 0; i < int(int((border).size())); i++) {
    first += border[i].first;
    second += border[i].second;
  }
  first /= int((border).size());
  second /= int((border).size());
  long double d1 = 1e18;
  long double d2 = -1e18;
  for (int i = 0; i < int(int((border).size())); i++) {
    d1 = min(d1, dist(make_pair((first), (second)), border[i]));
    d2 = max(d2, dist(make_pair((first), (second)), border[i]));
  }
  long double v1 =
      long double(cnt) / (long double(maxx - minx) * long double(maxy - miny));
  long double v2 = PI / 4;
  long double ave = min(d1, d2);
  cerr << abs(d1 - d2) / ave << endl;
  return (abs(d1 - d2) / ave) < 0.33;
}
inline void solve() {
  int ans1 = 0, ans2 = 0;
  for (int i = 0; i < int(n); i++)
    for (int j = 0; j < int(n); j++)
      if (val(i, j) != 0 && !used[i][j]) {
        cnt = 0;
        minx = 1e18, maxx = -1e18;
        miny = 1e18, maxy = -1e18;
        border.clear();
        dfs(i, j);
        if (checkCircle())
          ans1++;
        else
          ans2++;
      }
  cout << ans1 << ' ' << ans2 << endl;
}
int main() {
  assert(read());
  solve();
  return 0;
}
