#include <iostream>
#include<set>
using namespace std;
struct node {
int x, y;
node(int _x, int _y) :x(_x), y(_y) { };
bool operator <(const node& a)const {
if (x != a.x)return x < a.x;
else return y < a.y;
}
};
int n;
int num[5] = { 0 };
set<node>a;
bool is(int x, int y)
{
if (a.find(node(x, y)) != a.end())return true;
else return false;
}
int main()
{
cin >> n;
int b, c;
while (n)
{
cin >> b >> c;
a.insert(node(b, c));
n--;
}
set<node>::iterator it;
for (it = a.begin(); it != a.end(); it++)
{
int x = (*it).x, y = (*it).y;
if (is(x, y + 1) && is(x, y - 1) && is(x + 1, y) && is(x - 1, y))
{
int nu = 0;
if (is(x + 1, y + 1))nu++;
if (is(x + 1, y - 1))nu++;
if (is(x - 1, y + 1))nu++;
if (is(x - 1, y - 1))nu++;
num[nu]++;
}
}
for (int i = 0; i < 5; i++)
{
cout << num[i] << endl;
}
return 0;
}
#include <iostream>
using namespace std;
const int MAXV = 1010;
int a[MAXV][2];
int num[5] = { 0 };
int n;
bool exist(int x, int y)
{
for (int i = 0; i < n; i++)
{
if( a[i][0]==x&& a[i][1]==y) return true;
}
return false;
}
bool judge(int n1,int n2){
if (exist(n1, n2 + 1) && exist(n1, n2 - 1) && exist(n1 + 1, n2) && exist(n1 - 1, n2))return true;
else return false;
}
int number(int n3,int n4 ){
int num1 = 0;
if (exist(n3 + 1, n4 + 1))num1++;
if (exist(n3 + 1, n4 - 1))num1++;
if (exist(n3 - 1, n4 + 1))num1++;
if (exist(n3 - 1, n4 - 1))num1++;
return num1;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin>>a[i][0]>>a[i][1];
}
for (int i = 0; i < n; i++)
{
if (judge(a[i][0], a[i][1]))
{
num[number(a[i][0], a[i][1])]++;
}
}
for (int i = 0; i < 5; i++)
{
if (i <= 3)cout << num[i] << endl;
else cout << num[i];
}
return 0;
}