#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

class Point
{
public:
    int y, x;
    Point(){
        y = x = 0;
    }
    Point(int y0, int x0){
        y = y0;
        x = x0;
    }
    Point operator+(const Point& p) const{
        return Point(y + p.y, x + p.x);
    }
    Point operator-(const Point& p) const{
        return Point(y - p.y, x - p.x);
    }
    Point operator*(int a) const{
        return Point(y * a, x * a);
    }
    int dot(const Point& p) const{
        return y * p.y + x * p.x; // |a|*|b|*cosθ
    }
    int cross(const Point& p) const{
        return x * p.y - y * p.x; // |a|*|b|*sinθ
    }
    bool operator==(const Point& p) const{
        return x == p.x && y == p.y;
    }
};

bool segmentsCollide(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
{
    if(min(a1.x, a2.x) > max(b1.x, b2.x) || min(b1.x, b2.x) > max(a1.x, a2.x) || min(a1.y, a2.y) > max(b1.y, b2.y) || min(b1.y, b2.y) > max(a1.y, a2.y))
        return false;

    return ((long long)(a2-a1).cross(b1-a1) * (a2-a1).cross(b2-a1) <= 0) && ((long long)(b2-b1).cross(a1-b1) * (b2-b1).cross(a2-b1) <= 0);
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<Point> p1(n), p2(n);
        for(int i=0; i<n; ++i)
            cin >> p1[i].x >> p1[i].y >> p2[i].x >> p2[i].y;

        vector<int> ret(10, 0);
        vector<bool> check(n, false);
        for(int i=0; i<n; ++i){
            if(check[i])
                continue;
            check[i] = true;

            vector<int> s(1, i);
            int a = 1; // 線分の数
            int b = 0; // 共有の端点の数
            int c = 0; // 線分上の端点の数
            bool isTwo = true;
            for(unsigned j=0; j<s.size(); ++j){
                int num = 0;
                bool tmp = true;
                for(int k=0; k<n; ++k){
                    if(s[j] == k)
                        continue;
                    if(segmentsCollide(p1[s[j]], p2[s[j]], p1[k], p2[k])){
                        if(p1[s[j]] == p1[k] || p1[s[j]] == p2[k] || p2[s[j]] == p1[k] || p2[s[j]] == p2[k]){
                            ++ b;
                            // 2と5の判別
                            ++ num;
                            Point p3 = p1[s[j]] - p2[s[j]];
                            Point p4 = p1[k] - p2[k];
                            if(p2[s[j]] == p1[k] || p1[s[j]] == p2[k])
                                p4 = p4 * -1;
                            if(p3.cross(p4) < 0)
                                tmp = false;
                        }else
                            ++ c;
                        if(!check[k]){
                            ++ a;
                            s.push_back(k);
                            check[k] = true;
                        }
                    }
                }
                if(num == 1 && !tmp)
                    isTwo = false;
            }
            b /= 2;
            c /= 2;

            if(a == 1){
                ++ ret[1];
            }else if(a == 3){
                if(b == 1)
                    ++ ret[4];
                else
                    ++ ret[7];
            }else if(a == 4){
                if(b == 2)
                    ++ ret[3];
                else if(b == 3)
                    ++ ret[9];
                else
                    ++ ret[0];
            }else{
                if(c == 1)
                    ++ ret[6];
                else if(c == 2)
                    ++ ret[8];
                else if(isTwo)
                    ++ ret[2];
                else
                    ++ ret[5];
            }
        }

        cout << ret[0];
        for(int i=1; i<10; ++i)
            cout << ' ' << ret[i];
        cout << endl;
    }
}

Measured memory_bytes: 1232