#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(c) (c).begin(),(c).end()
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define MINF(a) memset(a,0x3f,sizeof(a))
#define POW(n) (1LL<<(n))
#define IN(i,a,b) (a <= i && i <= b)
using namespace std;
template <typename T> inline bool CHMIN(T& a,T b) { if(a>b) { a=b; return 1; } return 0; }
template <typename T> inline bool CHMAX(T& a,T b) { if(a<b) { a=b; return 1; } return 0; }
template <typename T> inline void SORT(T& a) { sort(ALL(a)); }
template <typename T> inline void REV(T& a) { reverse(ALL(a)); }
template <typename T> inline void UNI(T& a) { sort(ALL(a)); a.erase(unique(ALL(a)),a.end()); }
const int MOD = 1000000007;
// const int INF = 0x3f3f3f3f3f3f3f3f;
// const double EPS = 1e-10;
/* ---------------------------------------------------------------------------------------------------- */

using D = double; // 座標値の型 doubleかlong double
using P = complex<D>; // Point
using L = pair<P,P>;  // Line
using VP = vector<P>;
const double EPS = 1e-8;  // 許容誤差
const double INF = 1e12;
#define X real()
#define Y imag()
#define LT(n,m) ((n)+EPS<(m)) // n < m ?
#define LE(n,m) ((n)-EPS<(m)) // n <= m ?
#define GT(n,m) LT(m,n) // n > m ?
#define GE(n,m) LE(m,n) // n >= m ?
#define EQ(n,m) (abs((n)-(m))<EPS)
#define NE(n,m) !EQ(n,m)
#define rep(i,n) for (int i=0;i<(n);++i)

namespace std {
  istream& operator >> (istream& is, P& p) {
    int F, S;
    is >> F >> S;
    p = P(F,S);
    return is;
  }
  bool operator < (const P a, const P b) {
    return NE(a.X,b.X) ? LT(a.X,b.X) : LT(a.Y,b.Y);
  }
  bool operator > (const P a, const P b) {
    return NE(a.X,b.X) ? GT(a.X,b.X) : GT(a.Y,b.Y);
  }
  bool sort_y(const P a, const P b) {
    return LT(a.Y,b.Y);
  }
  void swap(P& a, P& b) {
    P c = a; a = b; b = c;
  }
}

// 内積
D dot(P a, P b) {
  return (conj(a)*b).X;
}
// 外積
D cross(P a, P b) {
  return (conj(a)*b).Y;
}
// 点aから見た、点bから点cへの方向
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (GT(cross(b,c),0)) return +1;  // counter clockwise
  if (LT(cross(b,c),0)) return -1;  // clockwise
  if (LT(dot(b,c),0)) return +2;  // c--a--b on line
  if (LT(norm(b),norm(c))) return -2; // a--b--c on line or a==b
  return 0;                     // a--c--b on line or a==c or b==c
}

// 直線と点
bool isecLP(P a1, P a2, P b) {
  return NE(abs(ccw(a1,a2,b)),1);
}
// 直線と直線
bool isecLL(P a1, P a2, P b1, P b2) {
  return !isecLP(a2-a1,b2-b1,0) || isecLP(a1,b1,b2);
}

// ２直線の交点
P crosspointLL(P a1, P a2, P b1, P b2) {
  D d1 = cross(b2-b1,b1-a1);
  D d2 = cross(b2-b1,a2-a1);
  if (EQ(d1,0) && EQ(d2,0)) return a1;  // same line
  if (EQ(d2,0)) throw "kouten ga nai";  // 交点がない
  return a1 + d1/d2 * (a2-a1);
}

int n;
P p[110],q[110];

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  while (cin >> n, n) {
    vector<pair<P,P>> v;
    REP(i,n) cin >> p[i] >> q[i];
    v.emplace_back(P(-100,-100),P(100,-100));
    v.emplace_back(P(-100,-100),P(-100,100));
    v.emplace_back(P(100,100),P(100,-100));
    v.emplace_back(P(100,100),P(-100,100));
    int ans = 1;
    REP(i,n) {
      set<P> st;
      for (auto vv : v) {
        if (isecLL(p[i],q[i],vv.first,vv.second)) {
          P cp = crosspointLL(p[i],q[i],vv.first,vv.second);
          if (IN(cp.X,-100,100) && IN(cp.Y,-100,100)) {
            st.insert(cp);
          }
        }
      }
      ans += st.size()-1;
      v.emplace_back(p[i],q[i]);
    }
    cout << ans << endl;
  }

  return 0;
}


Measured memory_bytes: 3052