#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<complex>
#include<cmath>
using namespace std;

#define REP(i,N) for(int i = 0; i < (int)(N); ++i)
#define ALL(v) (v).begin(), (v).end()
typedef long long Int;
template<class T> void pv(T a, T b){for(T i=a;i!=b;++i)cout<<*i<<" ";cout<<endl;}

typedef complex<int> P;
namespace std {
  bool operator < (const P& a, const P& b) {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
}

inline int dot(P a, P b) {return real( conj(a)*b);}
inline int cross(P a, P b) {return imag( conj(a)*b);}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0 )   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}
bool IsIntersectSS(P a1, P a2, P b1, P b2) {
  return ccw(a1,a2,b1) * ccw (a1,a2,b2) <= 0 &&
    ccw(b1,b2,a1) * ccw(b1,b2,a2) <= 0;
}

P IntersectionLL(P a1, P a2, P b1, P b2) {
  P a = a2 - a1; P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}

P seg[1000][2];

bool connect[1000][1000];
bool done[1000];

int solve(vector<int> v) {
        if( v.size() == 1 ) return 1;
        
        vector<P> crs;
        vector<P> end;
        REP(i, v.size()) {
                end.push_back( seg[v[i]][0] );
                end.push_back( seg[v[i]][1] );
                
                REP(j, i) {
                        if( connect[v[i]][v[j]] ) {
                                P m = IntersectionLL( seg[v[i]][0], seg[v[i]][1], seg[v[j]][0], seg[v[j]][1] );
                                end.push_back(m);
                                crs.push_back(m);
                        }
                }
        }
        
        sort(ALL(crs));
        sort(ALL(end));
        crs.erase(unique(ALL(crs)), crs.end());
        end.erase(unique(ALL(end)), end.end());
        
        int N = v.size();
        int C = crs.size();
        int E = end.size();
        //cout << N << ' ' << C << ' ' << E << endl;
        if ( N == 3 ) {
                if( E == 5 ) return 4;
                if( E == 4 ) return 7;
        }
        if( N == 4 ) {
                if( E == 4 ) return 0;
                if( E == 6 ) return 3;
                if( E == 5 ) return 9;
        }
        if( N == 5 ) {
                if( C == 5 ) return 6;
                if( C == 6 ) return 8;
        }
        
        int start = 0;
        int next = 0;
        REP(i, N) {
                int count = 0;
                REP(j, N) {
                        if( connect[ v[i] ][ v[j] ] ) {
                                count++;
                                next = v[j];
                        }
                }
                if( count == 1 ) {
                        start = v[i];
                        break;
                }
        }
        
        P a = seg[start][0];
        P b = seg[start][1];
        P c = seg[next][0];
        P d = seg[next][1];
        if( abs(a - c) == 0 || abs(a - d) == 0 ) {
                swap(a, b);
        }
        if( abs(d - b) == 0 ) swap(c, d);
        // a--b == c--d

        if( ccw(a, b, d) == 1 ) return 5;
        return 2;
}

void dfs(int p, int N, vector<int>&out) {
        if( done[p] ) return;
        done[p] = true;
        out.push_back(p);
        REP(i, N) if( connect[p][i] ) dfs(i, N, out);
}

int main() {
        for(int N; cin >> N && N; ) {
                memset( connect, 0, sizeof(connect) );
        
                REP(i, N) {
                        REP(j, 2) {
                                int x, y; cin >> x >> y;
                                seg[i][j] = P(x * 2, y * 2);
                        }
                }

                REP(i, N) REP(j, i) {
                        if( IsIntersectSS( seg[i][0], seg[i][1], seg[j][0], seg[j][1] ) )
                                connect[i][j] = connect[j][i] = 1;
                }

                memset(done, 0, sizeof(done));
                int bucket[10] = {};
                REP(i, N) if( !done[i] ) {
                        vector<int> v;
                        dfs(i, N, v);
                        //pv(ALL(v));
                        int d = solve(v);
                        //cout << d << endl;
                        ++bucket[d];
                }
                cout << bucket[0];
                for(int i = 1; i <= 9; i++) cout << ' ' << bucket[i];
                cout << endl;           
        }
        return 0;
}

Measured memory_bytes: 1908