#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:167772160000")
using namespace std;
bool grid[2100][2100];
bool trueGrid[2100][2100];
bool vis[2100][2100];
pair<long long, long long> ptsSum;
int ptsCount;
vector<pair<int, int> > border;
vector<pair<int, int> > pts;
bool atEdge(int x, int y) {
  int cnt = 0;
  for (int k = -1; k <= 1; k++)
    for (int l = -1; l <= 1; l++)
      if (!trueGrid[x + k][y + l]) cnt++;
  return (cnt > 2);
}
void dfs(pair<int, int> a) {
  int x = a.first;
  int y = a.second;
  if (!trueGrid[x][y] || vis[x][y]) return;
  vis[x][y] = true;
  ptsSum.first += a.first;
  ptsSum.second += a.second;
  ptsCount++;
  if (atEdge(x, y)) border.push_back(a);
  dfs(pair<int, int>(x + 1, y));
  dfs(pair<int, int>(x - 1, y));
  dfs(pair<int, int>(x, y + 1));
  dfs(pair<int, int>(x, y - 1));
  pts.push_back(a);
}
pair<int, int> answer;
double dist(pair<long long, long long> a, pair<long long, long long> b) {
  a.first -= b.first;
  a.second -= b.second;
  return sqrt(a.first * a.first + a.second * a.second);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  for (int i = 1; i <= (n); i++)
    for (int j = 1; j <= (n); j++) {
      int a;
      cin >> a;
      grid[i][j] = (a == 1);
    }
  for (int i = 1; i <= (n); i++)
    for (int j = 1; j <= (n); j++) {
      int cnt = 0;
      for (int k = -1; k <= 1; k++)
        for (int l = -1; l <= 1; l++) cnt += grid[i + k][j + l];
      if (cnt > 4)
        trueGrid[i][j] = true;
      else
        trueGrid[i][j] = false;
    }
  for (int i = 1; i <= (n); i++)
    for (int j = 1; j <= (n); j++) {
      ptsSum = make_pair(0, 0);
      ptsCount = 0;
      border.clear();
      pts.clear();
      dfs(pair<int, int>(i, j));
      if (ptsCount < 50) continue;
      pair<int, int> center;
      center.first = ptsSum.first / ptsCount;
      center.second = ptsSum.second / ptsCount;
      vector<double> distances;
      distances.resize(border.size());
      double averageDist = 0;
      double maxDist = 0, minDist = 1E10;
      for (int k = 0; k < (border.size()); k++) {
        distances[k] = dist(border[k], center);
        averageDist += distances[k];
        maxDist = max(maxDist, distances[k]);
        minDist = min(minDist, distances[k]);
      }
      int outside = 0, inside = 0;
      for (int i = max((double)0, center.first - maxDist - 1);
           i < min((double)n, center.first + maxDist + 1); i++)
        for (int j = max((double)0, center.second - maxDist - 1);
             j < max((double)n, center.second + maxDist + 1); j++) {
          if (dist(pair<int, int>(i, j), center) < maxDist && !trueGrid[i][j])
            inside++;
        }
      if ((double)inside / ptsCount > 0.255)
        answer.second++;
      else
        answer.first++;
    }
  cout << answer.first << " " << answer.second;
  return 0;
}
