#define _USE_MATH_DEFINES
#include <iostream>
#include <queue>
#include <vector>
#include <math.h>
#include <algorithm>
#include <iomanip>
#include <string>
#include <stack>
#include <cctype>
#include <cstdlib>
#include <tuple>
using namespace std;

#define INF (1 << 20)
#define EPS (1e-10)
#define EQ(a,b) (fabs((a)-(b)) < EPS)

int main(){
	int x[200], y[200], u[200], v[200];
	int n;
	int result = 0;
	int flg = 0;
	double ta = -1.0;
	cin >> n;
	if (n == 1 || n == 2) {
		cout << n << endl;
		return 0;
	}
	for (int i = 0; i < n; ++i) cin >> x[i] >> y[i] >> u[i] >> v[i];
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < n; ++j) {
			vector<tuple<double, double, double> > txyl;
			int cnt = 0;
			int xa = x[i] - x[j];
			int ya = y[i] - y[j];
			int ua = u[i] - u[j];
			int va = v[i] - v[j];
			if (xa == 0 && ya == 0 && ua == 0 && va == 0) continue;
			flg = 1;
			if (xa * va == ya * va) {
				double tt;
				if (xa != 0) tt = -1.0 * xa / ua;
				else tt = -1.0 * ya / va;
				if (tt >= 0) {
					for (int k = 0; k < n; ++k) {
						if (!EQ(x[0] + tt * u[0],x[k] + tt * u[k]) ||
								!EQ(y[0] + tt * v[0],y[k] + tt * v[k])) break;
						if (k == n-1) {
							cout << n << endl;
							return 0;
						}
					}
				}
			}
			for (int k = 0; k < n; ++k) {
				int flga = 0;
				int xb = x[i] - x[k];
				int yb = y[i] - y[k];
				int ub = u[i] - u[k];
				int vb = v[i] - v[k];
				double a = ua * vb - ub * va;
				double b = xa * vb + ua * yb - xb * va - ub * ya;
				double c = xa * yb - xb * ya;
				if (a == 0 && b == 0) {
					if (c == 0)	++cnt;
				} else if (a == 0) {
					double t = -c/b;
					if (!EQ(xa + t * ua,0) || !EQ(ya + t * va,0))
						txyl.push_back(make_tuple(t, xb + t * ub, yb + t * vb));
				} else {
					if (b * b - 4 * a * c < 0) continue;
					double temp;
					if (4 * a * c == 0) {
						temp = fabs(b);
					} else {
						temp = sqrt(b * b - 4 * a * c);
					}
					if (EQ(temp/a,0)) {
						double t = -b / 2.0 / a;
						if (!EQ(xa + t * ua,0) || !EQ(ya + t * va,0))
							txyl.push_back(make_tuple(t, xb + t * ub, yb + t * vb));
						continue;
					}
					double t = (-b + temp) / 2.0 / a;
					if (!EQ(xa + t * ua,0) || !EQ(ya + t * va,0))
						txyl.push_back(make_tuple(t, xb + t * ub, yb + t * vb));
					t = (-b - temp) / 2.0 / a;
					if (!EQ(xa + t * ua,0) || !EQ(ya + t * va,0))
						txyl.push_back(make_tuple(t, xb + t * ub, yb + t * vb));
				}
			}
			//if (count + cnt == n) result = n;
			sort(txyl.begin(), txyl.end());
			int kk = 0;
			while (kk < txyl.size() && get<0>(txyl[kk]) < 0) ++kk;
			int ccnt = 0;
			while (kk < txyl.size()) {
				double time = get<0>(txyl[kk]);
				int no_line = 0;
				for (int k = kk; k < txyl.size() && EQ(time,get<0>(txyl[k]));++k) {
					if (EQ(get<1>(txyl[k]),0) && EQ(get<2>(txyl[k]),0)) {
						++no_line;
					}
				}
				int max_group = 0;
				for (int l = kk; l < txyl.size() && EQ(time,get<0>(txyl[l])); ++l) {
					int num_group = 0;
					if (EQ(get<1>(txyl[l]),0) && EQ(get<2>(txyl[l]),0)) continue;
					for (int k = kk; k < txyl.size() && EQ(time,get<0>(txyl[k])); ++k) {
						if (EQ(get<1>(txyl[k]),0) && EQ(get<2>(txyl[k]),0)) continue;
						if (EQ(get<1>(txyl[l]) * get<2>(txyl[k]), get<1>(txyl[k]) * get<2>(txyl[l]))) {
							++num_group;
						}
					}
					max_group = max(max_group, num_group);
				}
				ccnt = max(ccnt, no_line + max_group);
				while (EQ(get<0>(txyl[kk]), time)) {
					++kk;
					if (kk == txyl.size()) break;
				}
			}
			//cout << "i:" << i << " j:" << j << " cnt:" << cnt << " ccnt:" << ccnt << " txyl:" << txyl.size() << endl;
			result = max(result, ccnt + cnt);
		}
	}
	if (flg == 0) {
		cout << n << endl;
	} else {
		cout << result << endl;
	}
	return 0;
}

Measured memory_bytes: 3140