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

// * XY座標
#define X real()
#define Y imag()

// * 点の表現
typedef complex<double> P;

// * complex<double> の順序を定義する
namespace std {
	bool operator < (const P& a, const P& b) {
		return (real(a) != real(b))? real(a) < real(b) : imag(a) < imag(b);
	}
}

// * 許容する誤差ε
const double EPS = 1e-10;
// * Infinity
const double INF = 1e12;
// * 円周率
const double PI = acos(-1.0);
// * Infinity 2
const P INF_P(INF,INF);

// * 2乗する
double sq(double x) {
	return x * x;
}

// * 2点間の距離
double dist(P p1, P p2) {
	return abs(p1 - p2);
}

// * 2つのスカラーが等しいかどうか
bool equal(double a, double b) {
	return ( fabs( a - b ) < EPS );
}
// * 2つのベクトルが等しいかどうか
bool eq_v(P a, P b) {
	return ( equal( a.X, b.X ) && equal( a.Y, b.Y ) );
}

// * 内積 (dot product) : a・b = |a||b|cosΘ
double dot(P a, P b) {
	return real( conj(a) * b );
}

// * 外積 (cross product) : a×b = |a||b|sinΘ
double cross(P a, P b) {
	return imag( conj(a) * b ) ;
}

// CCW : 反時計回り (Counter Clock Wise)
// CW : 時計回り (Clock Wise)
enum {CCW=1, CW=-1, ON=0};
// * 3点がどちら回りであるか返す, 3点が1直線に乗っているときは ON を返す
int ccw(const P &a, P b, P c) {
	b-=a, c-=a;
	if( cross(b,c) >  EPS ) return CCW; // CCW : 反時計回り
	if( cross(b,c) < -EPS ) return CW;  // CW : 時計回り
	if(dot(b, c) < -EPS )   return +2;  // c--a--b on line
	if(dot(b, b) + EPS < dot(c, c) ) return -2; // a--b--c on line ???
	return ON;
}

// 直線の表現 ((*this)[0]) と ((*this)[1]) を通る直線
struct Line : public vector<P> {
	Line(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
	Line(vector<P> v){
		push_back(v[0]); push_back(v[1]);
	}
	Line(){}
	// 2直線の平行判定
	bool parallel(const Line& l) {
		return equal( cross( (*this)[0] - (*this)[1] , l[0] - l[1] ), 0.0 );
	}
	// 点 p が直線上に乗っているか
	bool contain(P p) {
		return equal( cross( (*this)[1] - (*this)[0] , p - (*this)[0] ) , 0.0 );
	}
	// 直線の交差判定
	bool is_intersection(const Line& l) {
		return !equal( cross( (*this)[0] - (*this)[1], l[0] - l[1] ) , 0.0 );
	}
	// 直線の交差判定と交点計算
	bool intersection(Line l, P& p) {
		bool result = this->is_intersection( l );
		if( result ) {
			P a = (*this)[1] - (*this)[0];
			P b = l[1] - l[0];
			p = (*this)[0] + a * cross(b, l[0] - (*this)[0]) / cross(b, a);
		}else {
			p = INF_P;
		}
		return result;
	}
};

int main(){
	int n;
	while( cin >> n , n ){
		int ans = 1;
		vector<Line> v;
		for(int i=0 ; i < n ; i++ ){
			int x1, y1, x2, y2;
			cin >> x1 >> y1 >> x2 >> y2;
			v.push_back( Line( P(x1,y1) , P(x2,y2) ) );
		}
		for(int i=0 ; i < v.size() ; i++ ){
			Line l = v[i];
			vector<P> vp;
			// (増加する領域数) = (交差する線分数) - (重複交点数) + 1
			int cnt=0;
			for(int j=0 ; j < i ; j++ ){
				// 平行かどうかチェック
				if( v[j].parallel( l ) ) continue;
				P p;
				// 交点計算
				if( v[j].intersection(l, p) ){
					// (-100,-100) - (100,100) の矩形の領域に交点があるかチェック
					// 交点が境界のときは交差していない扱い
					if( abs(p.X) > 100.0 - EPS ) continue; 
					if( abs(p.Y) > 100.0 - EPS ) continue;
					
					// 交点 p と重なる交点があるかチェック
					bool flag = false;
					for(int k=0 ; k < vp.size() ; k++ ){
						if( eq_v(p,vp[k]) ){
							flag = true;
							break;
						}
					}
					// 交点が重複しない線分の個数を数える
					if( !flag ){
						cnt++;
						vp.push_back( p );
					}
				}
			}
			ans += cnt + 1;
		}
		cout << ans << endl;
	}
}

Measured memory_bytes: 932