// includes #include using namespace std; // macros #define pb emplace_back #define mk make_pair #define FOR(i, a, b) for(int i=(a);i<(b);++i) #define rep(i, n) FOR(i, 0, n) #define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--) #define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr) #define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr) #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end()) #define bit(n) (1LL<<(n)) // functions template bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;} template bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;} template istream &operator>>(istream &is, vector &vec){for(auto &v: vec)is >> v; return is;} template ostream &operator<<(ostream &os, const vector& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;} template ostream &operator<<(ostream &os, const set& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;} template ostream &operator<<(ostream &os, const unordered_set& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;} template ostream &operator<<(ostream &os, const multiset& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;} template ostream &operator<<(ostream &os, const unordered_multiset& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;} template ostream &operator<<(ostream &os, const pair &p){os << p.first << " " << p.second; return os;} template ostream &operator<<(ostream &os, const map &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;} template ostream &operator<<(ostream &os, const unordered_map &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;} // types using ll = long long int; using P = pair; // constants const int inf = 1e9; const ll linf = 1LL << 50; const double EPS = 1e-10; const int mod = 1000000007; const int dx[4] = {-1, 0, 1, 0}; const int dy[4] = {0, -1, 0, 1}; // io struct fast_io{ fast_io(){ios_base::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(20);} } fast_io_; struct point2d{ double x, y; point2d(){} point2d(double x, double y): x(x), y(y){} point2d operator+(const point2d &r) const{ return point2d(x + r.x, y + r.y); } point2d operator-(const point2d &r) const{ return point2d(x - r.x, y - r.y); } point2d& operator+=(const point2d &r){ *this = *this + r; return *this; } point2d& operator-=(const point2d &r){ *this = *this - r; return *this; } bool operator==(const point2d &r) const{ return abs(x - r.x) < EPS && abs(y - r.y) < EPS; } bool operator!=(const point2d &r) const{ return !(*this == r); } bool operator<(const point2d &r) const{ if(abs(x - r.x) >= EPS)return x < r.x; return y < r.y; } }; point2d operator*(double x, const point2d &p){ return point2d(x * p.x, x * p.y); } point2d operator/(const point2d &p, double x){ return point2d(p.x / x, p.y / x); } double norm(const point2d &a){ return sqrt(a.x * a.x + a.y * a.y); } double dis(const point2d &a, const point2d &b){ point2d c = a - b; return norm(c); } double inner_product(const point2d &a, const point2d &b){ return a.x * b.x + a.y * b.y; } double outer_product(const point2d &a, const point2d &b){ return a.x * b.y - a.y * b.x; } double cosine(const point2d &a, const point2d &b){ return inner_product(a, b) / norm(a) / norm(b); } double cross(const point2d &o, const point2d &a, const point2d &b){ return outer_product(a - o, b - o); } struct plane2d{ double a, b, c; double norm; plane2d(){} plane2d(double a, double b, double c): a(a), b(b), c(c){} plane2d(const point2d &p, const point2d &q){ point2d l = p - q; a = l.y, b = - l.x; c = - a * p.x - b * p.y; build(); } void build(){ norm = sqrt(a * a + b * b); } double dis(const point2d &p){ return abs(a * p.x + b * p.y + c) / norm; } double val(const point2d &p){ return a * p.x + b * p.y + c; } }; bool parallel(const plane2d &p, const plane2d &q){ return abs(p.a * q.b - p.b * q.a) < EPS; } bool orthogonal(const plane2d &p, const plane2d &q){ return abs(p.a * q.a + p.b * q.b) < EPS; } bool intersection(const point2d &p1, const point2d &p2, const point2d &p3, const point2d &p4){ plane2d pl1(p1, p2), pl2(p3, p4); if(abs(pl1.val(p3)) < EPS && min(p1.x, p2.x) <= p3.x && p3.x <= max(p1.x, p2.x) && min(p1.y, p2.y) <= p3.y && p3.y <= max(p1.y, p2.y))return true; if(abs(pl1.val(p4)) < EPS && min(p1.x, p2.x) <= p4.x && p4.x <= max(p1.x, p2.x) && min(p1.y, p2.y) <= p4.y && p4.y <= max(p1.y, p2.y))return true; if(abs(pl2.val(p1)) < EPS && min(p3.x, p4.x) <= p1.x && p1.x <= max(p3.x, p4.x) && min(p3.y, p4.y) <= p1.y && p1.y <= max(p3.y, p4.y))return true; if(abs(pl2.val(p2)) < EPS && min(p3.x, p4.x) <= p2.x && p2.x <= max(p3.x, p4.x) && min(p3.y, p4.y) <= p2.y && p2.y <= max(p3.y, p4.y))return true; return pl1.val(p3) * pl1.val(p4) <= - EPS && pl2.val(p1) * pl2.val(p2) <= - EPS; } double a[101], b[101], c[101], d[101]; int main(int argc, char const* argv[]) { int n; cin >> n; rep(i, n)cin >> a[i] >> b[i] >> c[i] >> d[i]; int res = 1; rep(i, n){ FOR(j, i + 1, n){ plane2d pl(point2d(a[i], b[i]), point2d(a[j], b[j])); int tmp = 0; rep(k, n){ if(pl.val(point2d(a[k], b[k])) * pl.val(point2d(c[k], d[k])) <= EPS)tmp++; } res = max(res, tmp); pl = plane2d(point2d(a[i], b[i]), point2d(c[j], d[j])); tmp = 0; rep(k, n){ if(pl.val(point2d(a[k], b[k])) * pl.val(point2d(c[k], d[k])) <= EPS)tmp++; } res = max(res, tmp); pl = plane2d(point2d(c[i], d[i]), point2d(a[j], b[j])); tmp = 0; rep(k, n){ if(pl.val(point2d(a[k], b[k])) * pl.val(point2d(c[k], d[k])) <= EPS)tmp++; } res = max(res, tmp); pl = plane2d(point2d(c[i], d[i]), point2d(c[j], d[j])); tmp = 0; rep(k, n){ if(pl.val(point2d(a[k], b[k])) * pl.val(point2d(c[k], d[k])) <= EPS)tmp++; } res = max(res, tmp); } } cout << res << endl; return 0; }