import std.stdio, std.algorithm, std.conv, std.array, std.string, std.math, std.typecons, std.numeric; /// enum EPS = 1e-10; /// double add(double a, double b) { if (abs(a + b) < EPS * (abs(a) + abs(b))) return 0; return a + b; } /// struct P { double x, y; this(double x, double y) { this.x = x; this.y = y; } P opBinary(string op)(P p) { static if (op == "+") return P(add(x, p.x), add(y, p.y)); else static if (op == "-") return P(add(x, -p.x), add(y, -p.y)); else static assert(0, "Operator '"~op~"' not implemented"); } P opBinary(string op)(double d) { static if (op == "*") return P(x * d, y * d); else static if (op == "/") return P(x / d, y / d); else static assert(0, "Operator '"~op~"' not implemented"); } // dot product double dot(P p) { return add(x * p.x, y * p.y); } // cross product double det(P p) { return add(x * p.y, -y * p.x); } double dist(P p) { return sqrt((x - p.x)^^2 + (y - p.y)^^2); } P middle(P p) { return P((x + p.x)/2, (y + p.y)/2); } P rotate(double th) { return P(add(x * cos(th), -y * sin(th)), add(x * sin(th), y * cos(th))); } P rotate(P p, double th) { auto q = P(x - p.x, y - p.y).rotate(th); return P(q.x + p.x, q.y + p.y); } } // 線分p1-p2上に点qがあるか判定 bool on_seg(P p1, P p2, P q) { return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0; } void main() { auto N = readln.chomp.to!int; P[] ps; foreach (_; 0..N) { auto xy = readln.split.to!(double[]); ps ~= P(xy[0], xy[1]); } int r; foreach (i; 0..N-1) { foreach (j; i+1..N) { int rr; foreach (p; ps) if (on_seg(ps[i], ps[j], p)) ++rr; r = max(r, rr); } } writeln(r); }