### constant

T = 0
R = 1
L = 2
C = 3

BT = 0
TR = 1
TL = 2
TC = 3
BJ = 4

DIGITS = [
  [0, 0, 0, 0, 4], # 0
  [1, 0, 0, 0, 0], # 1
  [0, 2, 0, 0, 3], # 2
  [0, 1, 1, 1, 1], # 3
  [1, 0, 1, 0, 1], # 4
  [0, 0, 2, 0, 3], # 5
  [0, 0, 1, 0, 4], # 6
  [0, 1, 1, 0, 1], # 7
  [0, 0, 0, 0, 5], # 8
  [0, 0, 1, 0, 3]  # 9
]

W = 1001

### classes

class Pt
  attr_accessor :x, :y

  def initialize() end
  def initialize(x, y) @x = x; @y = y end

  def ==(pt) @x == pt.x && @y == pt.y end
  def +(pt) Pt.new(@x + pt.x, @y + pt.y) end
  def -(pt) Pt.new(@x - pt.x, @y - pt.y) end
  def -@() Pt.new(-@x, -@y) end
  def *(t) Pt.new(@x * t, @y * t) end
  def /(t) Pt.new(@x / t, @y / t) end
  def dot(v) @x * v.x + @y * v.y end
  def cross(v) @x * v.y - @y * v.x end
  def d2() @x * @x + @y * @y end
  def d() Math.sqrt(d2()) end
  def to_s() "(#{@x},#{@y})" end
  def hash() @y * W + @x end
end

### subroutines

def root(uft, i)
  ri = i
  while uft[ri] != ri
    ri = uft[ri]
  end
  uft[i] = ri
end

def merge(uft, i, j)
  ri = root(uft, i)
  rj = root(uft, j)
  uft[ri] = rj
end

def on_seg(pt, seg)
  v0 = seg[0] - pt
  v1 = seg[1] - pt
  return v0.cross(seg[2]) == 0 && v0.dot(v1) < 0
end

### main

loop do
  n = gets.to_i
  break if n == 0

  segs = []
  phash = {}
  uft = (0...n).to_a

  for i in (0...n)
    x0, y0, x1, y1 = gets.split.map(&:to_i)
    sp0 = Pt.new(x0, y0)
    sp1 = Pt.new(x1, y1)
    segs << [sp0, sp1, sp1 - sp0]

    sh0 = sp0.hash
    if phash[sh0].nil?
      phash[sh0] = [[i, 0]]
    else
      phash[sh0] << [i, 0]
      merge(uft, phash[sh0][0][0], i)
    end
    
    sh1 = sp1.hash
    if phash[sh1].nil?
      phash[sh1] = [[i, 1]]
    else
      phash[sh1] << [i, 1]
      merge(uft, phash[sh1][0][0], i)
    end
  end

  for i in (0...n)
    sp0, sp1 = segs[i]
    sh0 = sp0.hash
    sh1 = sp1.hash

    for j in (0...n)
      next if i == j
      if phash[sh0].length == 1 && on_seg(sp0, segs[j])
        phash[sh0] << [j, 2]
        merge(uft, phash[sh0][0][0], j)
      end
      if phash[sh1].length == 1 && on_seg(sp1, segs[j])
        phash[sh1] << [j, 2]
        merge(uft, phash[sh1][0][0], j)
      end
    end
  end
  #p segs.map{|seg| "#{seg[0]}-#{seg[1]}"}
  #p phash
  #p uft

  sgrps = {}
  for i in (0...n)
    ri = root(uft, i)
    sgrps[ri] = [] if sgrps[ri].nil?
    sgrps[ri] << i
  end
  #p sgrps.values

  sums = 10.times.map{0}

  for sgrp in sgrps.values
    pat = 5.times.map{0}

    for si in sgrp
      tps = 4.times.map{0}

      for ki in [0, 1]
        spi = segs[si][ki]
        sh = spi.hash
        tp = T
        if phash[sh].length > 1
          sj, kj = (phash[sh][0][0] != si) ? phash[sh][0] : phash[sh][1]
          if kj == 2
            tp = C
          else
            vi = (ki == 0) ? -segs[si][2] : segs[si][2]
            vj = segs[sj][1 - kj] - segs[sj][kj]
            tp = (vi.cross(vj) < 0) ? R : L
          end          
        end
        tps[tp] += 1
      end
      #p tps

      if tps[T] == 2
        pat[BT] += 1
      elsif tps[T] == 1
        if tps[R] == 1
          pat[TR] += 1
        elsif tps[L] == 1
          pat[TL] += 1
        else
          pat[TC] += 1
        end
      else
        pat[BJ] += 1
      end
    end
    #p pat

    d = DIGITS.index(pat)
    sums[d] += 1
  end

  puts sums.join(' ')
end

Measured memory_bytes: 6152