← Home
use std::io;
#[derive(Clone)]
struct Point {
    x: usize,
    y: usize,
}
fn min(x: usize, y: usize) -> usize{
    if x < y {
        x
    }else{
        y
    }
}
fn max(x: usize, y: usize) -> usize{
    if x < y {
        y
    }else{
        x
    }
}
fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let params: Vec<usize> = input
        .trim()
        .split_whitespace()
        .map(|x| x.parse().expect("Not an integer"))
        .collect();
        
    let n = params[0];
    let m = params[1];
    let mut points = vec![Point{x:0,y:0};m];
    for i in 0..m {
        input.clear();
          io::stdin().read_line(&mut input).expect("Failed to read line");
        let params: Vec<usize> = input
            .trim()
            .split_whitespace()
            .map(|x| x.parse().expect("Not an integer"))
            .collect();
        let x = params[0];
        let y = params[1];
        points[i] = Point{x:x,y:y};
    }
    let mut mix = vec![10000000;n+1];
    let mut mxx = vec![0;n+1];
    let mut miy = vec![10000000;n+1];
    let mut mxy = vec![0;n+1];
    let mut mixyx = vec![10000000;2*n+1];
    let mut mxxyx = vec![0;2*n+1];
    let mut mixmyx = vec![10000000;2*n+1];
    let mut mxxmyx = vec![0;2*n+1];
    for i in 0..m {
        mix[points[i].x] = min(mix[points[i].x], points[i].y);
        mxx[points[i].x] = max(mxx[points[i].x], points[i].y);
        miy[points[i].y] = min(miy[points[i].y], points[i].x);
        mxy[points[i].y] = max(mxy[points[i].y], points[i].x);
        mixyx[points[i].x+points[i].y] = min(mixyx[points[i].x+points[i].y], points[i].x);
        mxxyx[points[i].x+points[i].y] = max(mxxyx[points[i].x+points[i].y], points[i].x);
        mixmyx[points[i].x+n-points[i].y] = min(mixmyx[points[i].x+n-points[i].y], points[i].x);
        mxxmyx[points[i].x+n-points[i].y] = max(mxxmyx[points[i].x+n-points[i].y], points[i].x);
    }
    let mut ans = vec![0;9];
    for i in 0..m {
        let mut attacks = 0;
        if points[i].y > mix[points[i].x]  &&  points[i].y < mxx[points[i].x] {
            attacks+= 2;
        }else if  points[i].y > mix[points[i].x]  ||  points[i].y < mxx[points[i].x] {
            attacks += 1;
        } 

        if points[i].x > miy[points[i].y]  &&  points[i].x < mxy[points[i].y] {
            attacks+= 2;
        }else if  points[i].x > miy[points[i].y]  ||  points[i].x < mxy[points[i].y] {
            attacks += 1;
        }
        
        if points[i].x  > mixyx[points[i].x + points[i].y] && points[i].x  < mxxyx[points[i].x + points[i].y] {
            attacks += 2;
        }else if points[i].x  > mixyx[points[i].x + points[i].y] || points[i].x  < mxxyx[points[i].x + points[i].y]{
            attacks += 1;
        }

        if points[i].x   > mixmyx[points[i].x +n - points[i].y ] && points[i].x < mxxmyx[points[i].x+n - points[i].y] {
            attacks += 2;
        }else if points[i].x  > mixmyx[points[i].x +n- points[i].y ] || points[i].x < mxxmyx[points[i].x+n - points[i].y ] {
            attacks += 1;
        }
        // println!("{} has attacks {} x+y {} {} {}",i,attacks, points[i].x  ,mix[points[i].x], mxx[points[i].x]);
        ans[attacks] += 1;
    }
    // println!("{:?}",mix);
    // println!("{:?}",mxx);
    // println!("{:?}",miy);
    // println!("{:?}",mxy);
    //  println!("{:?}",mixyx);
    // println!("{:?}",mxxyx);
    // println!("{:?}",mixmyx);
    // println!("{:?}",mxxmyx);
    for i in 0..9{
        print!("{} ", ans[i]);
    }
    println!();

}