#include <bits/stdc++.h>
using namespace std;
struct queen {
  int row, column, attacks;
  queen() { row = column = attacks = 0; }
  queen(int _row, int _column) {
    row = _row;
    column = _column;
    attacks = 0;
  }
};
const int maxn = 100005;
queen queens[maxn];
bool cmpTopDown(queen a, queen b) {
  return a.row < b.row || a.row == b.row && a.column < b.column;
}
bool cmpBottomUp(queen a, queen b) {
  return a.row > b.row || a.row == b.row && a.column > b.column;
}
int value1(queen a) { return a.column; }
int value2(queen a) { return a.row; }
int value3(queen a) { return a.row + a.column; }
int value4(queen a) { return a.row - a.column; }
int numOfQueens;
map<int, queen*> m;
void goThroughQueens(int (*getKey)(queen a)) {
  m.clear();
  for (int i = 1; i <= numOfQueens; i++) {
    int key = getKey(queens[i]);
    if (m.find(key) != m.end()) {
      m[key]->attacks++;
    }
    m[key] = &queens[i];
  }
}
void solve() {
  int tableSize;
  cin >> tableSize >> numOfQueens;
  for (int i = 1; i <= numOfQueens; i++) {
    int r, c;
    scanf("%d%d", &r, &c);
    queens[i] = queen(r, c);
  }
  sort(queens + 1, queens + numOfQueens + 1, cmpTopDown);
  goThroughQueens(value1);
  goThroughQueens(value2);
  goThroughQueens(value3);
  goThroughQueens(value4);
  sort(queens + 1, queens + numOfQueens + 1, cmpBottomUp);
  goThroughQueens(value1);
  goThroughQueens(value2);
  goThroughQueens(value3);
  goThroughQueens(value4);
  int t[10];
  memset(t, 0, sizeof(t));
  for (int i = 1; i <= numOfQueens; i++) {
    t[queens[i].attacks]++;
  }
  for (int i = 0; i <= 8; i++) {
    printf("%d ", t[i]);
  }
  cout << endl;
}
int main() {
  clock_t starttime = clock();
  solve();
  clock_t endtime = clock();
  ;
  return 0;
}
