#include"bits/stdc++.h"

using namespace std;

#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,m,n) for(int i=(m);i<(n);i++)
#define ALL(x) x.begin(),x.end()
const double EPS = 1e-10;
typedef complex<double> point;
point operator*(const point&p, const double &d) {
	return point(real(p)*d, imag(p)*d);
}
namespace std {
	bool operator < (const point& a, const point& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
//直線or線分
struct Line : public vector<point> {
	Line(const point &a, const point &b) {
		push_back(a); push_back(b);
	}
};
//外積
double cross(const point& a, const point& b) {
	return imag(conj(a)*b);
}
//内積
double dot(const point& a, const point& b) {
	return real(conj(a)*b);
}
int ccw(point a, point b, point 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 intersectLL(const Line &l1, const Line &l2) {
	return abs(cross(l1[1] - l1[0], l2[1] - l2[0])) > EPS || //non-parallel
		abs(cross(l1[1] - l1[0], l2[0] - l1[0])) < EPS; //same line
}
bool intersectLS(const Line &l, const Line &s) {
	return cross(l[1] - l[0], s[0] - l[0])* // s[0] is left of l
		cross(l[1] - l[0], s[1] - l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const Line &l, const point &p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
bool intersectSS(const Line &s, const Line &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 intersectSP(const Line &s, const point &p) { //verified on 2020/04/03 https://onlinejudge.u-aizu.ac.jp/status/users/Mojumbo/submissions/1/1157/judge/4316978/C++14
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS; //triangle inequality
}
//距離,交点
//射影 直線lにpから下した垂線との交点

point projection(const Line &l, const point &p) { //verified on 2020/04/03 https://onlinejudge.u-aizu.ac.jp/status/users/Mojumbo/submissions/1/1157/judge/4316978/C++14
	double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + (l[0] - l[1])*t;
}
//射影 直線lを対象軸としてpと線対称にある点
point reflection(const Line &l, const point &p) {
	return p + (projection(l, p) - p)*2;
}
double distancePP(const point& a, const point& b) {
	return sqrt(norm(a - b));
}
double distanceLP(const Line &l, const point &p) {
	return abs(p - projection(l, p));
}
double distanceLL(const Line&l, const Line &m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const Line &l, const Line &s) {
	if (intersectLS(l, s))return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const Line &s, const point &p) {
	const point r = projection(s, p);
	if (intersectSP(s, r))return abs(r - p);
	return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceSS(const Line &s, const Line &t) { //verified on 2020/04/03 https://onlinejudge.u-aizu.ac.jp/status/users/Mojumbo/submissions/1/1157/judge/4316978/C++14
	if (intersectSS(s, t))return 0;
	return min({ distanceSP(s,t[0]),distanceSP(s,t[1]),distanceSP(t,s[0]),distanceSP(t,s[1]) });
}
point crosspoint(const Line &l, const Line &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS&&abs(B) < EPS)return m[0];//same line
	if (abs(A) < EPS)assert(false); // Precondition not satisfied
	return m[0] + B / A * (m[1] - m[0]);
}
bool isSamePoint (const point &p1,const point &p2){
	return abs(p1-p2)<EPS;
}
clock_t start;
clock_t end_t;
void solve() {
	int N; cin >> N;
	if (N == 0)exit(0);
	int ans = 1 + N;
	vector<Line>ls;
	REP(i, N) {
		double x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		point p1 = { x1,y1 }, p2 = { x2,y2 };
		Line l(p1, p2);

		ls.push_back(l);
	}
	REP(i, N - 1) {
		vector<point>cps;
		FOR(j,i+1, N) {
			if(ls[i][0]==ls[j][0]||ls[i][0]==ls[j][1]||ls[i][1]==ls[j][0]||ls[i][1]==ls[j][1])continue;
			if (intersectSS(ls[i], ls[j])){
				point cp = crosspoint(ls[i],ls[j]);
				bool found = false;
				for(auto p:cps){
					if(isSamePoint(cp,p)){
						found=true;
						break;
					}
				}
				if(!found){
					ans++;
					cps.push_back(cp);
				}
			}
		}
	}
	// sort(ALL(crossPoints));
	int sb = 0;
	// int M=crossPoints.size();
	// for(int l=0;l<M-1;){
	// 	int r=l+1;
	// 	bool found=false;
	// 	if(!isSamePoint(crossPoints[l],crossPoints[r])){
	// 		l++;
	// 	}
	// 	else{
	// 		found=true;
	// 		while(isSamePoint(crossPoints[l],crossPoints[r])){
	// 			r++;
	// 			if(r==M)break;
	// 		}
	// 	}
	// 	if(found)ans--;
	// 	l=r;
	// }

	// REP(i,(int)crossPoints.size()-1){
	// 	if(isSamePoint(crossPoints[i],crossPoints[i+1]))sb++;
	// }
	cout << ans-sb << endl;
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	start = clock();
	while (true)solve();
}


Measured memory_bytes: 3300