Problem:
Score : 300 points

Problem Statement

There are N balls in a two-dimensional plane. The i-th ball is at coordinates (x_i, y_i).

We will collect all of these balls, by choosing two integers p and q such that p \neq 0 or q \neq 0 and then repeating the following operation:

Choose a ball remaining in the plane and collect it. Let (a, b) be the coordinates of this ball. If we collected a ball at coordinates (a - p, b - q) in the previous operation, the cost of this operation is 0. Otherwise, including when this is the first time to do this operation, the cost of this operation is 1.

Find the minimum total cost required to collect all the balls when we optimally choose p and q.

Constraints

1 \leq N \leq 50

|x_i|, |y_i| \leq 10^9

If i \neq j, x_i \neq x_j or y_i \neq y_j.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
:
x_N y_N

Output

Print the minimum total cost required to collect all the balls.

Sample Input 1

2
1 1
2 2

Sample Output 1

1

If we choose p = 1, q = 1, we can collect all the balls at a cost of 1 by collecting them in the order (1, 1), (2, 2).

Sample Input 2

3
1 4
4 6
7 8

Sample Output 2

1

If we choose p = -3, q = -2, we can collect all the balls at a cost of 1 by collecting them in the order (7, 8), (4, 6), (1, 4).

Sample Input 3

4
1 1
1 2
2 1
2 2

Sample Output 3

2

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder.Abc
{
    class QuestionE
    {
        public class XY : IEquatable<XY>
        {
            public int X;
            public int Y;

            public override bool Equals(object obj)
            {
                return this.Equals(obj as XY);
            }

            public bool Equals(XY p)
            {
                if (Object.ReferenceEquals(p, null)) {
                    return false;
                }

                if (Object.ReferenceEquals(this, p)) {
                    return true;
                }

                if (this.GetType() != p.GetType()) {
                    return false;
                }

                return (X == p.X) && (Y == p.Y);
            }

            public static bool operator ==(XY lhs, XY rhs)
            {
                if (Object.ReferenceEquals(lhs, null)) {
                    if (Object.ReferenceEquals(rhs, null)) {
                        return true;
                    }

                    return false;
                }
                return lhs.Equals(rhs);
            }

            public static bool operator !=(XY lhs, XY rhs)
            {
                return !(lhs == rhs);
            }

            public override int GetHashCode()
            {
                return X * 0x1000 + Y;
            }
        }

        public static void Main(string[] args)
        {
            var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);

            //N = 1対策用今回の問題上大きさが0のベクトルはないので問題なし
            var dic = new Dictionary<XY, long> {
                { new XY{ X = 0, Y = 0 }, 0 }
            };

            // 整数の入力
            var n = long.Parse(Console.ReadLine());

            var xy = new XY[n];

            for(int i = 0; i < n; i++) {
                // 整数配列の入力
                var a = Console.ReadLine().Split(' ').Select(q => int.Parse(q)).ToArray();
                xy[i] = new XY { X = a[0], Y = a[1] };
            }

            //N(i)からN(i+1)のベクトルが事前に設定したベクトル(p,q)とどれだけ乖離していようが
            //別ベクトルならコストは1かかる（同じベクトルなら0かかる）
            //つまり各点から各点へのベクトルの分類し、一番多いベクトルを(p,q)とすれば最短コストとなる
            foreach (var q in xy) {
                foreach (var w in xy) {
                    if(q.Equals(w)) {
                        continue;
                    }

                    var aa = q.X - w.X;
                    var bb = q.Y - w.Y;

                    var d = new XY { X = aa, Y = bb };

                    if (dic.ContainsKey(d)) {
                        dic[d]++;
                    } else {
                        dic[d] = 1;
                    }
                }
            }

            var max = dic.Max(x => x.Value);

            var result = n - max;

            Console.WriteLine(result);

            Console.Out.Flush();
        }
    }
}