#include<bits/stdc++.h>
using namespace std;
#define MAX_N 1005
typedef complex<double> P;
double eps=1e-6;

P calc(P a,P b,P c,P d){
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

bool isParallel(P a,P b,P c,P d){
  return ( abs( imag( (a-b)*conj(c-d) ) ) < eps );
}

bool eq(P a,P b){
  return ( abs(a-b) < eps );
}

int n;
P A[MAX_N],B[MAX_N];
int G[MAX_N][MAX_N];
int ans[10];
bool visited[MAX_N];
vector<int> vec;

int solve(){
  if(vec.size()==1)return 1;
  int cnt1=0,cnt2=0,size=vec.size();
  for(int i=0;i<size;i++){
    for(int j=0;j<i;j++){
      if(G[vec[i]][vec[j]]==1)cnt1++;
      if(G[vec[i]][vec[j]]==2)cnt2++;
    }
  }

  //  cout<<cnt1<<' '<<cnt2<<' '<<size<<endl;
  P g= A[vec[0]];
  for(int i=0;i<size;i++){
    int id=vec[i];
    //    cout<<A[id]-g<<' '<<B[id]-g<<endl;
  }
  if(size==3){
    if(cnt1==2&&cnt2==0)return 7;
    return 4;
    
    //    if(cnt1==1&&cnt2==1)return 4;
    //    assert(0);
  }
  if(size==4){
    if(cnt1==4&&cnt2==0)return 0;
    if(cnt1==3&&cnt2==1)return 9;
    if(cnt1==2&&cnt2==1)return 3;
    return 3;
    //    assert(0);
  }
  if(size==5){
    if(cnt1==4&&cnt2==1)return 6;
    if(cnt1==4&&cnt2==2)return 8;
    if(cnt1==4&&cnt2==0){
      for(int i=0;i<size;i++){
        int C=0,D;
        for(int j=0;j<size;j++){
          if(i!=j&&G[vec[i]][vec[j]]){
            C++;
            D=j;
          }
        }
        

        if(C==1){
          P cp=calc(A[vec[i]],B[vec[i]],A[vec[D]],B[vec[D]]);

          P from,to,prev;
          if(eq(cp,A[vec[i]]))prev=B[vec[i]],from=A[vec[i]];
          else if(eq(cp,B[vec[i]]))prev=A[vec[i]],from=B[vec[i]];
          //else assert(0);
          
          if(eq(cp,A[vec[D]]))to=B[vec[D]];
          else if(eq(cp,B[vec[D]]))to=A[vec[D]];
          //          else assert(0);

          P base=from-prev,target=to-prev;
          if( imag(target*conj(base)) < -eps )return 2;
          else if( imag(target*conj(base)) >  eps )return 5;
          //          else assert(0);
        }
      }
    }
    return 2;
    assert(0);
  }
  return -1;
}

void dfs(int pos){
  if(visited[pos])return;
  visited[pos]=true;
  vec.push_back(pos);
  for(int i=0;i<n;i++)
    if(G[pos][i]!=0)dfs(i);
}
bool eq(double a,double b){
  return (-eps < a-b && a-b < eps );
}
bool onSegment(P a,P b,P c){
  return eq( abs(a-b) , abs(a-c) + abs(b-c) );
}

int check(int si,int ti){
  if( isParallel(A[si],B[si],A[ti],B[ti]) )return 0;
  P k=calc(A[si],B[si],A[ti],B[ti]);
  int count=3;
  if( eq(k,A[si]) || eq(k,B[si]) )count--;
  if( eq(k,A[ti]) || eq(k,B[ti]) )count--;
  if( onSegment(A[si],B[si],k) && onSegment(A[ti],B[ti],k) )return count;
  return 0;
}

int main(){
  while(1){
    cin>>n;
    if(n==0)break;
    memset(G,0,sizeof(G));
    for(int i=0;i<n;i++){
      double ax,ay,bx,by;
      cin>>ax>>ay>>bx>>by;
      A[i]=P(ax,ay);
      B[i]=P(bx,by);
      for(int j=0;j<i;j++){
        G[i][j]=G[j][i]=check(i,j);
      }
    }
    memset(ans,0,sizeof(ans));
    memset(visited,false,sizeof(visited));
    for(int i=0;i<n;i++){
      if(visited[i])continue;
      vec.clear();
      dfs(i);
      
      ans[ solve() ]++;
    }
    for(int i=0;i<10;i++){
      if(i)cout<<' ';
      cout<<ans[i];
    }
    cout<<endl;
  }
  return 0;
}