#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
const double EPS = 1e-8;

struct Point {
	double x, y;
	Point() : x(0), y(0) { }
	Point(double x, double y) : x(x), y(y) { }
	Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	Point operator*(double s) const { return Point(x * s, y * s); }
	Point operator/(double s) const { return Point(x / s, y / s); }
	Point &operator+=(const Point &p){ x += p.x; y += p.y; return *this; }
	Point &operator-=(const Point &p){ x -= p.x; y -= p.y; return *this; }
	Point &operator*=(double s){ x *= s; y *= s; return *this; }
	Point &operator/=(double s){ x /= s; y /= s; return *this; }
	bool operator==(const Point &p) const { return x == p.x && y == p.y; }
	bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
	bool operator<(const Point &p) const {
		return (x == p.x) ? (y < p.y) : (x < p.x);
	}
};
inline Point operator*(double s, const Point &p){ return p * s; }

inline double norm(const Point &p){ return p.x * p.x + p.y * p.y; }
inline double abs(const Point &p){ return sqrt(norm(p)); }
inline double arg(const Point &p){ return atan2(p.y, p.x); }
inline Point unit(const Point &p){ return p / abs(p); }
inline Point ortho(const Point &p){ return Point(-p.y, p.x); }
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
inline int ccw(const Point &a, const Point &b, const Point &c){
	const Point d = b - a, e = c - a;
	if(cross(d, e) > 0.0){ return 1; }
	if(cross(d, e) < 0.0){ return -1; }
	if(dot(d, e) < 0.0){ return 2; }
	if(abs(d) < abs(e)){ return -2; }
	return 0;
}

struct Line {
	Point a, b;
	Line() : a(), b() { }
	Line(const Point &a, const Point &b) : a(a), b(b) { }
	bool operator==(const Line &l) const { return a == l.a && b == l.b; }
	bool operator!=(const Line &l) const { return a != l.a || b != l.b; }
	bool operator<(const Line &l) const {
		return (a == l.a) ? (b < l.b) : (a < l.a);
	}
};

inline Point crossing_point(const Line &a, const Line &b){
	const double x = cross(a.b - a.a, b.b - b.a);
	const double y = cross(a.b - a.a, a.b - b.a);
	return Point(b.a + (y / x) * (b.b - b.a));
}

struct Segment : public Line {
	Segment() : Line() { }
	Segment(const Point &a, const Point &b) : Line(a, b) { }
};

inline bool intersect(const Segment &s, const Point &p){
	return abs(s.a - p) + abs(s.b - p) < abs(s.a - s.b) + EPS;
}
inline bool intersect(const Segment &a, const Segment &b){
	if(ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) > 0){ return false; }
	if(ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) > 0){ return false; }
	return true;
}

int main(){
	ios_base::sync_with_stdio(false);
	while(true){
		int n;
		cin >> n;
		if(n == 0){ break; }
		vector<Segment> segments(n);
		for(int i = 0; i < n; ++i){
			int x0, y0, x1, y1;
			cin >> x0 >> y0 >> x1 >> y1;
			segments[i] = Segment(Point(x0, y0), Point(x1, y1));
		}
		int answer = 1;
		for(int i = 0; i < n; ++i){
			vector<Point> ps;
			for(int j = 0; j < i; ++j){
				if(intersect(segments[i], segments[j])){
					ps.push_back(crossing_point(segments[i], segments[j]));
				}
			}
			const int m = ps.size();
			++answer;
			for(int j = 0; j < m; ++j){
				bool accept = true;
				if(max(abs(ps[j].x), abs(ps[j].y)) >= 100.0 - EPS){
					accept = false;
				}
				for(int k = 0; accept && k < j; ++k){
					if(abs(ps[j] - ps[k]) < EPS){ accept = false; }
				}
				if(accept){ ++answer; }
			}
		}
		cout << answer << endl;
	}
	return 0;
}

Measured memory_bytes: 1208