#include <cassert>
#include <array>
#include <algorithm>
#include <iostream>
#include <complex>
#include <vector>
using namespace std;

const double EPS = 1e-10;
template<class T>
bool eq(const T& a, const T& b) {return abs(a - b) < EPS;}

typedef complex<double> point;

namespace std {
	bool operator==(const point &a, const point &b){
		return eq(a, b);
	}
	bool operator<(const point& a, const point& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(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);
}

typedef array<point, 2> line;

bool intersectLL(const line& l, const line& m) {
	return !eq(cross(l[1]-l[0], m[1]-m[0]), 0.) || // non-parallel
			eq(cross(l[1]-l[0], m[0]-l[0]), 0.);   // same line
}

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]);
}

vector<line> lines;

int hitCount(const line& s) {
	vector<point> hits;
	for (const auto& t : lines) {
		if (intersectLL(s, t)) {
			point p = crosspoint(s, t);
			if (-100 < p.real() && p.real() < 100 && -100 < p.imag() && p.imag() < 100) {
				hits.push_back(p);
			}
		}
	}
	sort(hits.begin(), hits.end());
	auto it = unique(hits.begin(), hits.end());
	return it - hits.begin();
}

int main() {
	int n;
	while (cin >> n, n) {
		int cnt = 1;
		lines.clear();
		for (int i = 0; i < n; i++) {
			line l;
			for (auto& p : l) {
				int x, y;
				cin >> x >> y;
				p = point(x, y);
			}
			cnt += hitCount(l) + 1;
			lines.push_back(l);
		}
		cout << cnt << endl;
	}
	return 0;
}