import java.util.*;
public class Main {
public static Map<Integer, Set<Integer>> map = new HashMap<>();
public static int[][] move = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
public static int[][] countMove = new int[][] {{1, -1}, {-1, 1}, {1, 1}, {-1, -1}};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0; i < n; i++){
int a, b;
a = sc.nextInt();
b = sc.nextInt();
if(map.get(a) == null) map.put(a, new HashSet<>());
Set<Integer> set = map.get(a);
set.add(b);
}
int[] result = new int[] {0, 0, 0, 0, 0};
for(Map.Entry<Integer, Set<Integer>> entry : map.entrySet()){
int x = entry.getKey();
Set<Integer> temp = entry.getValue();
for(Integer y : temp){
if(canBe(x, y)){
result[count(x, y)]++;
}
}
}
for(int num : result){
System.out.println(num);
}
}
public static boolean canBe(int x, int y){
if(!judge(x, y)) return false;
for(int i = 0; i < move.length; i++){
if(!judge(x + move[i][0], y + move[i][1])) return false;
}
return true;
}
public static boolean judge(int x, int y){
Set<Integer> temp = map.get(x);
return temp != null && temp.contains(y);
}
public static int count(int x, int y){
int count = 0;
for(int i = 0; i < countMove.length; i++){
if(judge(x + countMove[i][0], y + countMove[i][1])){
count++;
}
}
return count;
}
}