def take2(i):
    while True:
        yield next(i),next(i)
def main(f):
    _ = int(f.readline())
    xyuv = [[x+y*1j for x,y in take2(map(int, line.split()))] for line in f]

    print(solve(xyuv))
def is_all_same_attime(xyuv):
    xy0, uv0 = xyuv[0]
    for i in range(len(xyuv)):
        if xyuv[0] == xyuv[i]:
            continue
        xyi,uvi = xyuv[i]

        t = get_cross_time(xy0 - xyi, uv0 - uvi)

        if t is None or t < 0:
            return False

        p0 = xy0 + uv0 * t
        for j in range(i + 1,len(xyuv)):
            xyj, uvj = xyuv[j]
            pj = xyj + uvj * t
            if is_zero(pj - p0):
                continue
            return False
        break
    return True
def get_cross_time(xy,uv):
     denominator = uv.real - uv.imag
     return (xy.imag - xy.real) / denominator if denominator else None

def is_all_same(xyuv):
    for xyuvi in xyuv:
        if xyuvi != xyuv[0]:
            return False
    return True

def is_zero(a):
    return abs(a) < 0.00001

def get_t(xy1,uv1,xy2,uv2):
    a = uv1.real * uv2.imag - uv1.imag * uv2.real
    b = xy1.real * uv2.imag - xy1.imag * uv2.real + uv1.real * xy2.imag - uv1.imag * xy2.real
    c = xy1.real * xy2.imag - xy1.imag * xy2.real
    if a:
        d = b * b - 4 * a * c
        if d < 0:
            return []
        elif d == 0:
            return [-b / (2 * a)]
        else:
            d = d ** 0.5 / (2 * a)
            b /= 2 * a
            return [-b + d, -b - d]
    if b:
        return [-c / b]
    if not c:
        global always_lined_point
        always_lined_point += 1
    return []

from itertools import combinations
from itertools import groupby
from collections import Counter
def solve(xyuv):
    global always_lined_point
    if len(xyuv) <= 2 or is_all_same(xyuv) or is_all_same_attime(xyuv):
        return len(xyuv)
    max_ij = 0
    for i, j in combinations(range(len(xyuv)), 2):
        if xyuv[i] == xyuv[j]:
            continue
        xyi,uvi = xyuv[i]
        xyj,uvj = xyuv[j]
            
        always_lined_point = 0
        t = []
        for indeces in (range(i),range(i + 1,j),range(j + 1,len(xyuv))):
            for k in indeces:
                xyk,uvk = xyuv[k]
                t.extend(get_t(xyi - xyk, uvi - uvk, xyj - xyk, uvj - uvk))

        t = [ti for ti in t if 0 <= ti] #t<0?????????
        t = [round(ti, 10) for ti in t] #?????????
        t = Counter(t)

        group_lengths = []
        for k, c in t.most_common(2):
            group_length = 1 if is_zero(xyi + uvi * k) else c
            group_lengths.append(group_length)
             
        max_ij = max(max_ij, max(group_lengths) + always_lined_point + 2)
    return max_ij

import sys
f = sys.stdin

main(f)

### FIXED CODE ###

def take2(i):
    while True:
        yield next(i),next(i)
def main(f):
    _ = int(f.readline())
    xyuv = [[x+y*1j for x,y in take2(map(int, line.split()))] for line in f]

    print(solve(xyuv))
def is_all_same_attime(xyuv):
    xy0, uv0 = xyuv[0]
    for i in range(len(xyuv)):
        if xyuv[0] == xyuv[i]:
            continue
        xyi,uvi = xyuv[i]

        t = get_cross_time(xy0 - xyi, uv0 - uvi)

        if t is None or t < 0:
            return False

        p0 = xy0 + uv0 * t
        for j in range(i + 1,len(xyuv)):
            xyj, uvj = xyuv[j]
            pj = xyj + uvj * t
            if is_zero(pj - p0):
                continue
            return False
        break
    return True
def get_cross_time(xy,uv):
     denominator = uv.real - uv.imag
     return (xy.imag - xy.real) / denominator if denominator else None

def is_all_same(xyuv):
    for xyuvi in xyuv:
        if xyuvi != xyuv[0]:
            return False
    return True

def is_zero(a):
    return abs(a) < 0.00001

def get_t(xy1,uv1,xy2,uv2):
    a = uv1.real * uv2.imag - uv1.imag * uv2.real
    b = xy1.real * uv2.imag - xy1.imag * uv2.real + uv1.real * xy2.imag - uv1.imag * xy2.real
    c = xy1.real * xy2.imag - xy1.imag * xy2.real
    if a:
        d = b * b - 4 * a * c
        if d < 0:
            return []
        elif d == 0:
            return [-b / (2 * a)]
        else:
            d = d ** 0.5 / (2 * a)
            b /= 2 * a
            return [-b + d, -b - d]
    if b:
        return [-c / b]
    if not c:
        global always_lined_point
        always_lined_point += 1
    return []

from itertools import combinations
from itertools import groupby
from collections import Counter
#@profile
def solve(xyuv):
    global always_lined_point
    if len(xyuv) <= 2 or is_all_same(xyuv) or is_all_same_attime(xyuv):
        return len(xyuv)
    max_ij = 0
    for i, j in combinations(range(len(xyuv)), 2):
        if xyuv[i] == xyuv[j]:
            continue
        xyi,uvi = xyuv[i]
        xyj,uvj = xyuv[j]
            
        always_lined_point = 0
        t = []
        for indeces in (range(i),range(i + 1,j),range(j + 1,len(xyuv))):
            for k in indeces:
                xyk,uvk = xyuv[k]
                t.extend(get_t(xyi - xyk, uvi - uvk, xyj - xyk, uvj - uvk))

        t = [ti for ti in t if 0 <= ti] #t<0?????????
        t = [round(ti, 10) for ti in t] #?????????
        t = Counter(t)

        xyi -= xyj
        uvi -= uvj

        group_lengths = [0]
        for k, c in t.most_common(2):
            group_length = 1 if is_zero(xyi + uvi * k) else c
            group_lengths.append(group_length)
             
        max_ij = max(max_ij, max(group_lengths) + always_lined_point + 2)
    return max_ij

import sys
f = sys.stdin

main(f)