#

# 　　  ⋀_⋀　 

#　　  (･ω･)  

# .／ Ｕ ∽ Ｕ＼

#  │＊　合　＊│

#  │＊　格　＊│ 

#  │＊　祈　＊│ 

#  │＊　願　＊│ 

#  │＊　　　＊│ 

#      ￣

#

import sys

input=sys.stdin.readline

from math import floor,ceil,sqrt,factorial,log #log2ないｙｐ

from heapq import heappop, heappush, heappushpop

from collections import Counter,defaultdict

from itertools import accumulate,permutations,combinations,product,combinations_with_replacement

from bisect import bisect_left, bisect_right

from copy import copy

inf=float('inf')

mod = 10**9+7

def INT_(n): return int(n)-1

def MI(): return list(map(int,input().split()))

def MF(): return list(map(float, input().split()))

def MI_(): return list(map(INT_,input().split()))

def LI(): return list(MI())

def LI_(): return [int(x) - 1 for x in input().split()]

def LF(): return list(MF())

def LIN(n:int): return [I() for _ in range(n)]

def LLIN(n: int): return [LI() for _ in range(n)]

def LLIN_(n: int): return [LI_() for _ in range(n)]

def LLI(): return [list(map(int, l.split() )) for l in eval(input())]

def I(): return int(eval(input()))

def F(): return float(eval(input()))

def ST(): return input().replace('\n', '')

def main():



    N = I()

    XY = LLIN(N)

    dic = defaultdict(lambda :-1)

    for i, (x, y) in enumerate(XY):

        dic[(x, y)] = i

    

        



    # UnionFind

    class UnionFind():

        def __init__(self, n):

            self.nodes=[-1] * n  # nodes[x]: 負なら、絶対値が木の要素数



        def get_root(self, x):

            # nodes[x]が負ならxが根

            if self.nodes[x] < 0:

                return x

            # 根に直接つなぎ直しつつ、親を再帰的に探す

            else:

                self.nodes[x]=self.get_root(self.nodes[x])

                return self.nodes[x]



        def unite(self, x, y):

            root_x=self.get_root(x)

            root_y=self.get_root(y)

            # 根が同じなら変わらない

            # if root_x == root_y:

            # pass

            if root_x != root_y:

                # 大きい木の方につないだほうが計算量が減る

                if self.nodes[root_x] < self.nodes[root_y]:

                    big_root=root_x

                    small_root=root_y

                else:

                    small_root=root_x

                    big_root=root_y

                self.nodes[big_root] += self.nodes[small_root]

                self.nodes[small_root]=big_root



    if N == 1:

        print((1))

        exit()

    ans = inf

    for i in range(N):

        for j in range(N):

            if i == j:

                continue

            p = XY[i][0] - XY[j][0]

            q = XY[i][1] - XY[j][1]

            uf = UnionFind(N)

            mini_ans = 0

            for (x, y) in XY:

                if dic[(x - p, y - q)] != -1:

                    uf.unite(dic[(x, y)], dic[(x - p, y - q)])

                if dic[(x + p, y + q)] != -1:

                    uf.unite(dic[(x, y)], dic[(x + p, y + q)])

            for i in range(N):

                if uf.nodes[i] < 0:

                    mini_ans += 1

            ans = min(mini_ans, ans)

    print(ans)

    """pre_exist = set()

    pre_exist.add((XY[i][0], XY[i][1]))

    mini_ans = 1

    for (x, y) in XY:

        found = False

        for (px, py) in pre_exist.copy():

            #print(pre_exist,x,y,px,py,mini_ans,"#",p,q)

            if (x, y) == (px, py):

                found = True

                continue

            dx = px - x

            dy = py - y

            if (dx-p==0 and dy-q==0) or (dx+p==0 and dy+q==0):

                found = True

                break

        pre_exist.add((x,y))

        if not found:

            mini_ans += 1"""

                        

if __name__ == '__main__':

    main()
#

# 　　  ⋀_⋀　 

#　　  (･ω･)  

# .／ Ｕ ∽ Ｕ＼

#  │＊　合　＊│

#  │＊　格　＊│ 

#  │＊　祈　＊│ 

#  │＊　願　＊│ 

#  │＊　　　＊│ 

#      ￣

#

import sys

input=sys.stdin.readline

from math import floor,ceil,sqrt,factorial,log #log2ないｙｐ

from heapq import heappop, heappush, heappushpop

from collections import Counter,defaultdict

from itertools import accumulate,permutations,combinations,product,combinations_with_replacement

from bisect import bisect_left, bisect_right

from copy import copy

inf=float('inf')

mod = 10**9+7

def INT_(n): return int(n)-1

def MI(): return list(map(int,input().split()))

def MF(): return list(map(float, input().split()))

def MI_(): return list(map(INT_,input().split()))

def LI(): return list(MI())

def LI_(): return [int(x) - 1 for x in input().split()]

def LF(): return list(MF())

def LIN(n:int): return [I() for _ in range(n)]

def LLIN(n: int): return [LI() for _ in range(n)]

def LLIN_(n: int): return [LI_() for _ in range(n)]

def LLI(): return [list(map(int, l.split() )) for l in eval(input())]

def I(): return int(eval(input()))

def F(): return float(eval(input()))

def ST(): return input().replace('\n', '')

def main():



    N = I()

    XY = LLIN(N)

    if N == 1:

        print((1))

        exit()

    XY.sort()



    count = defaultdict(int)

    for i, (x1, y1) in enumerate(XY):

        for j, (x2, y2) in enumerate(XY[i+1:]):

            dx, dy = x1 - x2, y1 - y2

            count[(dx, dy)] += 1

    maxim = -inf

    for v in list(count.values()):

        maxim = max(maxim, v)

    print((N - maxim))

    

    

                        

if __name__ == '__main__':

    main()
#
# 　　  ⋀_⋀
# 　　  (･ω･)
# .／ Ｕ ∽ Ｕ＼
#  │＊　合　＊│
#  │＊　格　＊│
#  │＊　祈　＊│
#  │＊　願　＊│
#  │＊　　　＊│
#      ￣
#
import sys

input = sys.stdin.readline
from math import floor, ceil, sqrt, factorial, log  # log2ないｙｐ
from heapq import heappop, heappush, heappushpop
from collections import Counter, defaultdict
from itertools import (
    accumulate,
    permutations,
    combinations,
    product,
    combinations_with_replacement,
)
from bisect import bisect_left, bisect_right
from copy import copy

inf = float("inf")
mod = 10**9 + 7


def INT_(n):
    return int(n) - 1


def MI():
    return list(map(int, input().split()))


def MF():
    return list(map(float, input().split()))


def MI_():
    return list(map(INT_, input().split()))


def LI():
    return list(MI())


def LI_():
    return [int(x) - 1 for x in input().split()]


def LF():
    return list(MF())


def LIN(n: int):
    return [I() for _ in range(n)]


def LLIN(n: int):
    return [LI() for _ in range(n)]


def LLIN_(n: int):
    return [LI_() for _ in range(n)]


def LLI():
    return [list(map(int, l.split())) for l in eval(input())]


def I():
    return int(eval(input()))


def F():
    return float(eval(input()))


def ST():
    return input().replace("\n", "")


def main():
    N = I()
    XY = LLIN(N)
    dic = defaultdict(lambda: -1)
    for i, (x, y) in enumerate(XY):
        dic[(x, y)] = i
    # UnionFind
    class UnionFind:
        def __init__(self, n):
            self.nodes = [-1] * n  # nodes[x]: 負なら、絶対値が木の要素数

        def get_root(self, x):
            # nodes[x]が負ならxが根
            if self.nodes[x] < 0:
                return x
            # 根に直接つなぎ直しつつ、親を再帰的に探す
            else:
                self.nodes[x] = self.get_root(self.nodes[x])
                return self.nodes[x]

        def unite(self, x, y):
            root_x = self.get_root(x)
            root_y = self.get_root(y)
            # 根が同じなら変わらない
            # if root_x == root_y:
            # pass
            if root_x != root_y:
                # 大きい木の方につないだほうが計算量が減る
                if self.nodes[root_x] < self.nodes[root_y]:
                    big_root = root_x
                    small_root = root_y
                else:
                    small_root = root_x
                    big_root = root_y
                self.nodes[big_root] += self.nodes[small_root]
                self.nodes[small_root] = big_root

    if N == 1:
        print((1))
        exit()
    ans = inf
    for i in range(N):
        for j in range(N):
            if i == j:
                continue
            p = XY[i][0] - XY[j][0]
            q = XY[i][1] - XY[j][1]
            uf = UnionFind(N)
            mini_ans = 0
            for (x, y) in XY:
                if dic[(x - p, y - q)] != -1:
                    uf.unite(dic[(x, y)], dic[(x - p, y - q)])
                if dic[(x + p, y + q)] != -1:
                    uf.unite(dic[(x, y)], dic[(x + p, y + q)])
            for i in range(N):
                if uf.nodes[i] < 0:
                    mini_ans += 1
            ans = min(mini_ans, ans)
    print(ans)
    """pre_exist = set()
    pre_exist.add((XY[i][0], XY[i][1]))
    mini_ans = 1
    for (x, y) in XY:
        found = False
        for (px, py) in pre_exist.copy():
            #print(pre_exist,x,y,px,py,mini_ans,"#",p,q)
            if (x, y) == (px, py):
                found = True
                continue
            dx = px - x
            dy = py - y
            if (dx-p==0 and dy-q==0) or (dx+p==0 and dy+q==0):
                found = True
                break
        pre_exist.add((x,y))
        if not found:
            mini_ans += 1"""


if __name__ == "__main__":
    main()

#
# 　　  ⋀_⋀
# 　　  (･ω･)
# .／ Ｕ ∽ Ｕ＼
#  │＊　合　＊│
#  │＊　格　＊│
#  │＊　祈　＊│
#  │＊　願　＊│
#  │＊　　　＊│
#      ￣
#
import sys

input = sys.stdin.readline
from math import floor, ceil, sqrt, factorial, log  # log2ないｙｐ
from heapq import heappop, heappush, heappushpop
from collections import Counter, defaultdict
from itertools import (
    accumulate,
    permutations,
    combinations,
    product,
    combinations_with_replacement,
)
from bisect import bisect_left, bisect_right
from copy import copy

inf = float("inf")
mod = 10**9 + 7


def INT_(n):
    return int(n) - 1


def MI():
    return list(map(int, input().split()))


def MF():
    return list(map(float, input().split()))


def MI_():
    return list(map(INT_, input().split()))


def LI():
    return list(MI())


def LI_():
    return [int(x) - 1 for x in input().split()]


def LF():
    return list(MF())


def LIN(n: int):
    return [I() for _ in range(n)]


def LLIN(n: int):
    return [LI() for _ in range(n)]


def LLIN_(n: int):
    return [LI_() for _ in range(n)]


def LLI():
    return [list(map(int, l.split())) for l in eval(input())]


def I():
    return int(eval(input()))


def F():
    return float(eval(input()))


def ST():
    return input().replace("\n", "")


def main():
    N = I()
    XY = LLIN(N)
    if N == 1:
        print((1))
        exit()
    XY.sort()
    count = defaultdict(int)
    for i, (x1, y1) in enumerate(XY):
        for j, (x2, y2) in enumerate(XY[i + 1 :]):
            dx, dy = x1 - x2, y1 - y2
            count[(dx, dy)] += 1
    maxim = -inf
    for v in list(count.values()):
        maxim = max(maxim, v)
    print((N - maxim))


if __name__ == "__main__":
    main()

-    dic = defaultdict(lambda: -1) -    for i, (x, y) in enumerate(XY): -        dic[(x, y)] = i -    # UnionFind -    class UnionFind: -        def __init__(self, n): -            self.nodes = [-1] * n  # nodes[x]: 負なら、絶対値が木の要素数 - -        def get_root(self, x): -            # nodes[x]が負ならxが根 -            if self.nodes[x] < 0: -                return x -            # 根に直接つなぎ直しつつ、親を再帰的に探す -            else: -                self.nodes[x] = self.get_root(self.nodes[x]) -                return self.nodes[x] - -        def unite(self, x, y): -            root_x = self.get_root(x) -            root_y = self.get_root(y) -            # 根が同じなら変わらない -            # if root_x == root_y: -            # pass -            if root_x != root_y: -                # 大きい木の方につないだほうが計算量が減る -                if self.nodes[root_x] < self.nodes[root_y]: -                    big_root = root_x -                    small_root = root_y -                else: -                    small_root = root_x -                    big_root = root_y -                self.nodes[big_root] += self.nodes[small_root] -                self.nodes[small_root] = big_root - -    ans = inf -    for i in range(N): -        for j in range(N): -            if i == j: -                continue -            p = XY[i][0] - XY[j][0] -            q = XY[i][1] - XY[j][1] -            uf = UnionFind(N) -            mini_ans = 0 -            for (x, y) in XY: -                if dic[(x - p, y - q)] != -1: -                    uf.unite(dic[(x, y)], dic[(x - p, y - q)]) -                if dic[(x + p, y + q)] != -1: -                    uf.unite(dic[(x, y)], dic[(x + p, y + q)]) -            for i in range(N): -                if uf.nodes[i] < 0: -                    mini_ans += 1 -            ans = min(mini_ans, ans) -    print(ans) -    """pre_exist = set() -    pre_exist.add((XY[i][0], XY[i][1])) -    mini_ans = 1 -    for (x, y) in XY: -        found = False -        for (px, py) in pre_exist.copy(): -            #print(pre_exist,x,y,px,py,mini_ans,"#",p,q) -            if (x, y) == (px, py): -                found = True -                continue -            dx = px - x -            dy = py - y -            if (dx-p==0 and dy-q==0) or (dx+p==0 and dy+q==0): -                found = True -                break -        pre_exist.add((x,y)) -        if not found: -            mini_ans += 1""" +    XY.sort() +    count = defaultdict(int) +    for i, (x1, y1) in enumerate(XY): +        for j, (x2, y2) in enumerate(XY[i + 1 :]): +            dx, dy = x1 - x2, y1 - y2 +            count[(dx, dy)] += 1 +    maxim = -inf +    for v in list(count.values()): +        maxim = max(maxim, v) +    print((N - maxim))