#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <utility>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(ll i=a; i<ll(b); i++)
#define rep(i,b) loop(i,0,b)
#define each(e,c) for(auto&e:c)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#ifdef DEBUG
#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<(DUMP(),__VA_ARGS__).str()<<" ["<<__LINE__<<"]"<<endl)
struct DUMP:ostringstream{template<class T>DUMP &operator,(const T&t){if(this->tellp())*this<<", ";*this<<t;return *this;}};
#else
#define dump(...)
#endif


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

#define curr(g,i) g[i]
#define next(g,i) g[(i+1)%g.size()]
#define self (*this)

// 実数
typedef double R;

// 実定数
const R eps = 1e-8;
const R inf = 1e12;
const R pi = acos(-1);

// 点
typedef complex<R> P;

// A->B->Cの順に廻るときの角ABCの大きさを[0,2*Pi]で求める
R arg(P a, P b, P c) { R th = arg((a - b) / (c - b)); return th > 0 ? th : th+2*pi; }

// 点のx座標優先の比較関数
bool comp_x(P const& a, P const& b) { return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b); }

// 点のy座標優先の比較関数
bool comp_y(P const& a, P const& b) { return imag(a) != imag(b) ? imag(a) < imag(b) : real(a) < real(b); }

// 点の偏角の比較関数
P CENTER = P();
bool comp_arg(P const& a, P const& b) { return arg(a, CENTER, CENTER+1.) < arg(b, CENTER, CENTER+1.); }

// 点のデフォルトの比較関数
namespace std { bool operator < (P const& a, P const& b) { return comp_x(a, b); } }

// 外積
R cross(P const& a, P const& b) { return imag(conj(a)*b); }

// 内積
R dot(P const& a, P const& b) { return real(conj(a)*b); }

// 直線
struct L : public vector<P> {
    L(P const& a = P(), P const& b = P()) { push_back(a); push_back(b); }
    L(R a, R b, R c){ // ax+by+c=0
        if(fabs(a) < eps) self = L(P(0,-c/b),P(1,-c/b));
        else if(fabs(b) < eps) self = L(P(-c/a,0),P(-c/a,1));
        else self = L(P(-c/a,0), P(0,-c/b));
    }
    P vec() const { return self[1] - self[0]; }
};

// 線分
struct S : public vector<P> {
    // A to B
    S(P const& a = P(), P const& b = P()) { push_back(a); push_back(b); }
    L line() const { return L(self[0], self[1]); }
    P vec() const { return line().vec(); }
    R len() const { return abs(vec()); }
};

// 多角形
typedef vector<P> G;

// 円
struct C {
    P p; R r;
    C(P const& p = P(), R r = 0) : p(p), r(r) { }
};

// A->B->C と巡るときの位置関係を調べる
enum { CCW = +1, CW = -1, CAB = +2, ABC = -2, SEG = 0 };
int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return CCW; // a->b->c 反時計回り
    if (cross(b, c) < 0)   return  CW; // a->b->c 時計回り
    if (dot(b, c) < 0)     return CAB; // c--a--b 直線上
    if (norm(b) < norm(c)) return ABC; // a--b--c 直線上
    return SEG; // 線分上にある
}

// 円の面積
R area(C const& c) { return pi*c.r*c.r; }

// 多角形の面積
R area(G const& g) { R res = 0; int n = g.size(); rep(i,n) res += cross(g[i],g[(i+1)%n]); return abs(res)/2; }

// ヘロンの公式
R heron(R a, R b, R c) { R s = (a+b+c)/2; return sqrt(s*(s-a)*(s-b)*(s-c)); }

P biased_center(P const& a, P const& b, P const& c, R wa, R wb, R wc) {
    return (wa*a + wb*b + wc*c)/(wa + wb + wc);
}

// http://www.h6.dion.ne.jp/~ooya/Suugaku/IchiVector5shin.pdf
// 重心
P gravity_center(P const& a, P const& b, P const& c) {
    return biased_center(a,b,c,1,1,1);
}

// 内心
P inner_center(P const& a, P const& b, P const& c) {
    R la = abs(b-c), lb = abs(c-a), lc = abs(a-b);
    return biased_center(a,b,c,la,lb,lc);
}

// 外心
P circumcenter(P const& a, P const& b, P const& c) {
    R sa = sin(2*arg(c,a,b)), sb = sin(2*arg(a,b,c)), sc = sin(2*arg(b,c,a));
    return biased_center(a,b,c,sa,sb,sc);
}

// 垂心
P orthocenter(P const& a, P const& b, P const& c) {
    if(abs(arg(c,a,b))==pi) return a;
    if(abs(arg(a,b,c))==pi) return b;
    if(abs(arg(b,c,a))==pi) return c;
    R ta = tan(arg(c,a,b)), tb = tan(arg(a,b,c)), tc = tan(arg(b,c,a));
    return biased_center(a,b,c,ta,tb,tc);
}

// 傍心(3つのうち頂点Aに対応するものを返す)
P excenter(P const& a, P const& b, P const& c) {
    R sa = sin(arg(c,a,b)), sb = sin(arg(a,b,c)), sc = sin(arg(b,c,a));
    return biased_center(a,b,c,-sa,sb,sc);
}

// 直線と直線の交差判定
bool col(L const& l, L const& m) { return abs(cross(l.vec(), m.vec())) > eps || abs(cross(l.vec(), m[0]-l[0])) < eps; }

// 直線と線分の交差判定
bool col(L const& l, S const& s) { return cross(l.vec(), s[0]-l[0])*cross(l.vec(), s[1]-l[0]) < eps; }
bool col(S const& s, L const& l) { return col(l, s); }

// 直線と点の交差判定
bool col(L const& l, P const& p) { return abs(cross(l[1]-p, l[0]-p)) < eps; }
bool col(P const& p, L const& l) { return col(l, p); }

// 線分と線分の交差判定
bool col(const S &s, const S &t) { return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0; }

// 線分と点の交差判定
bool col(const S &s, const P &p) { return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < eps; }

// 円と円の交差判定
int col(const C& c1, const C& c2){
    double d = abs(c1.p - c2.p), r1 = c1.r, r2 = c2.r;
    if(r1 + r2 < d)                 return 0; // 離れている
    if(abs(r1 + r2 - d) < eps)      return 1; // 外接
    if(abs(d - abs(r1 - r2)) < eps) return -1; // 内接
    if(d < r1 - r2)                 return +3; // c1 が c2 の中にある
    if(d < r2 - r1)                 return -3; // c2 が c1 の中にある
    return 2; // 2つの交点を持つ
}

// 点の射影
P proj(L const& l, P const& p) { double t = dot(p-l[0], l.vec()) / norm(l.vec()); return l[0] + t*(l.vec()); }
P proj(P const& p, L const& l) { return proj(l, p); }

// 点の反射
P refl(L const& l, P const& p) { return p + 2. * (proj(l, p) - p); }
P refl(P const& p, L const& l) { return refl(l, p); }

// 点と点の距離
R dist(P const& p, P const& q) { return abs(p - q); }

// 点と直線の距離
R dist(L const& l, P const& p) { return abs(p - proj(l, p)); }
R dist(P const& p, L const& l) { return dist(l, p); }

// 直線と直線の距離
R dist(L const& l, L const& m) { return col(l, m) ? 0 : dist(l, m[0]); }

// 直線と線分の距離
R dist(L const& l, S const& s) { return col(l, s) ? 0 : min(dist(l, s[0]), dist(l, s[1])); }
R dist(S const& s, L const& l) { return dist(l, s); }

// 線分と点の距離
R dist(S const& s, P const& p) { P const r = proj(s.line(), p); return col(s, r) ? abs(r - p) : min(abs(s[0] - p), abs(s[1] - p)); }
R dist(P const& p, S const& s) { return dist(s,p); }

// 線分と線分の距離
R dist(S const& s, S const& t) { return col(s, t) ? 0 : min(min(min(dist(s, t[0]), dist(s, t[1])), dist(t, s[0])), dist(t, s[1])); }

// 直線と直線の交点
vector<P> hit(L const& l, L const& m) {
    R A = cross(l.vec(), m.vec());
    R B = cross(l.vec(), l[1] - m[0]);
    if (abs(A) < eps && abs(B) < eps) return {m[0]}; // same line
    if (abs(A) < eps) return G(); // parallel
    return {m[0] + B / A * (m.vec())};
}

// 線分と線分の交点
vector<P> hit(S const& s, S const& t) { return col(s,t) ? hit(s.line(),t.line()) : G(); }

// 直線と線分の交点
vector<P> hit(L const& l, S const& s) { return col(l, s) ? hit(l, s.line()) : G(); }
vector<P> hit(S const& s, L const& l) { return hit(l, s); }

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1183
//        : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2045
// 円と直線の交点を求める
vector<P> hit(C const& c, L const& l){
    R d = dist(l,c.p); // 中心と直線の距離
    if(fabs(d-c.r) < eps) return { proj(l, c.p) }; // 触れている
    if(d > c.r) return G(); // 離れている
    P h = proj(l, c.p);
    P u = sqrt(c.r*c.r - d*d) * (l.vec()) / abs(l.vec());
    return {h+u, h-u};
}

// 円と線分の交点を求める
vector<P> hit(C const& c, S const& s) { G cps = hit(c,s.line()), res; for(const P& p : cps) if(col(s,p)) res.push_back(p); return res; }

// 円と円の交点を求める
vector<P> hit(C const& c1, C const& c2) {
    if(abs(c1.p - c2.p) < 0) return G(); // 中心が同じ
    int i = col(c1,c2);
    if(i==0 || abs(i)==3) return G(); // 共通部分なし || 内部
    R r1 = c1.r, r2 = c2.r, d = abs(c1.p - c2.p);
    if(i==1) return { c1.p + (c2.p - c1.p) * r1/d }; // 接する
    P p = c1.p - c2.p;
    R A = -2. * p.real(), B = 2 * p.imag();
    R C = norm(c1.p) - norm(c2.p) - r1*r1 + r2*r2;
    return hit(c1, L(A,B,C)); // 2つの交点を持つ
}

// 円と多角形の交点を求める
vector<P> hit(C const& c, G const& g) {
    vector<P> res; int n = g.size();
    rep(i,n) for(P const& p : hit(c, S(g[i],g[(i+1)%n]))) res.push_back(p);
    return res;
}

// 点が円の内部にあるか判定する
enum { OUT, ON, IN };
int inside(P const& p, C const& c) { double d = abs(p-c.p), r = c.r; return abs(d - r) < eps ? ON : (d > r ? OUT : IN); }

// 点が多角形の内部になるか判定する
int inside(P const& p, G const& g) {
    int n = g.size(), a = 0, b = n;
    P in = (g[0] + g[n/3] + g[2*n/3]) / 3.0; // inner
    while (a+1 < b) { // invariant: c is in fan in-g[a]-g[b]
        int c = (a + b) / 2;
        if (cross(g[a]-in, g[c]-in) > 0) { // angle < 180 deg
            if (cross(g[a]-in, p-in) > 0 && cross(g[c]-in, p-in) < 0) b = c; else a = c;
        } else {
            if (cross(g[a]-in, p-in) < 0 && cross(g[c]-in, p-in) > 0) a = c; else b = c;
        }
    }
    b %= n;
    if (cross(g[a] - p, g[b] - p) < 0) return OUT;
    if (cross(g[a] - p, g[b] - p) > 0) return IN;
    return ON;
}

// 多角形が円の内部にあるか判定する
bool inside(G const& g, C const& c) { for(P const& p : g) if(!inside(p,c)) return false; return true; }

// 円が多角形の内部にあるか判定する(時計回りか半時計回りになっていること)
bool inside(C const& c, G const& g){
    int n = g.size();
    int t = ccw(g[n-1], g[0], c.p);
    rep(i,n-1) if(t != ccw(g[i], g[i+1], c.p)) return false;
    rep(i,n) if(c.r > dist(S(g[i], g[(i+1)%n]), c.p)) return false;
    return true;
}

// 凸多角形を直線で切断する
pair<G,G> convex_cut(G const& g, L const& l) {
    G left, right;
    rep(i,g.size()){
        P A = curr(g, i), B = next(g, i);
        int side = ccw(l[0], l[1], A);
        if (side != CCW) left.push_back(A);
        if (side !=  CW) right.push_back(A);
        if (ccw(l[0], l[1], A)*ccw(l[0], l[1], B) < 0){
            P cp = hit(L(A, B), l)[0];
            left.push_back(cp); right.push_back(cp);
        }
    }
    return make_pair(left,right);
}
pair<G,G> convex_cut(L const& l, G const& g) { return convex_cut(g, l); }

// 凸包を求める
G convex_hull(G ps) {
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    G ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++])
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--])
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    ch.resize(k-1);
    return ch;
}

// 点集合の中から最近点対を求める
pair<P,P> closest_pair(vector<P> p) {
    int n = p.size(), s = 0, t = 1, m = 2, S[n]; S[0] = 0, S[1] = 1;
    sort(all(p)); // "p < q" <=> "p.x < q.x"
    double d = norm(p[s]-p[t]);
    for (int i = 2; i < n; S[m++] = i++) rep(j, m) {
            if (norm(p[S[j]]-p[i])<d) d = norm(p[s = S[j]]-p[t = i]);
            if (real(p[S[j]]) < real(p[i]) - d) S[j--] = S[--m];
        }
    return make_pair( p[s], p[t] );
}


int main(){
    int n;
    while(cin>>n && n){
        vector<S> segs(n);
        rep(i,n){
            rep(j,2){
                int x, y; cin>>x>>y;
                segs[i][j] = P(x,y);
            }
        }

        int ans = 1;
        rep(i,n){
            vector<P> ps;
            rep(j,i){
                for(auto const& cp : hit(segs[i],segs[j])){
                    R t = max(abs(cp.real()),abs(cp.imag()));
                    if(abs(t-100)>eps) ps.push_back(cp);
                }
            }
            sort(ps.begin(),ps.end());
            ps.eb(-1,-1);
            int cnt = 0;
            rep(i,ps.size()-1) if(abs(ps[i]-ps[i+1]) > eps) cnt++;
            ans += cnt+1;
        }
        cout << ans << endl;
    }
}