#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 1010;
int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0}; // 8方向偏移量
int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
int n;
int h[N][N];
queue<PII> q;
bool st[N][N];
void bfs(int x, int y, bool& f1, bool& f2)
{
q.push({x, y}); // 起点入队
st[x][y] = 1; // 起点被遍历过
while (q.size())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 8; i ++ ) // 8方向扩展
{
int xx = t.x + dx[i], yy = t.y + dy[i];
if (xx < 0 || xx >= n || yy < 0 || yy >= n) continue; // 如果出界就继续
if (h[xx][yy] != h[t.x][t.y]) // 如果扩展出的和现在的高度不相等
{
if (h[xx][yy] > h[t.x][t.y]) f1 = 1; // 高的话是山峰
else f2 = 1; // 否则是山谷
}
else if (!st[xx][yy]) // 如果没被遍历过
{
st[xx][yy] = 1;
q.push({xx, yy}); // 入队
}
}
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
scanf("%d", &h[i][j]);
int r1 = 0, r2 = 0;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
if (!st[i][j]) // 遍历整个图
{
bool f1 = 0, f2 = 0;
bfs(i, j, f1, f2);
if (!f1) r1 ++ ; // 山峰
if (!f2) r2 ++ ; // 山谷
}
printf("%d %d\n", r1, r2);
return 0;
}