#include <bits/stdc++.h>

using namespace std;

template<typename T>
struct Point2D {
  T x, y;

  Point2D(T x = 0, T y = 0) : x(x), y(y) {}

  bool operator==(const Point2D &p) const { return x == p.x && y == p.y; }
  bool operator!=(const Point2D &p) const { return x != p.x || y != p.y; }

  Point2D  operator+ (const Point2D &p) const { return Point2D(x + p.x, y + p.y); }
  Point2D  operator- (const Point2D &p) const { return Point2D(x - p.x, y - p.y); }
  Point2D& operator+=(const Point2D &p) const { x += p.x; y += p.y; return *this; }
  Point2D& operator-=(const Point2D &p) const { x -= p.x; y -= p.y; return *this; }

  Point2D  operator* (T k) const { return Point2D(x * k, y * k); }
  Point2D  operator/ (T k) const { return Point2D(x / k, y / k); }
  Point2D& operator*=(T k) const { x *= k; y *= k; return *this; }
  Point2D& operator/=(T k) const { x /= k; y /= k; return *this; }

  T operator*(const Point2D &p) const { return x * p.x + y * p.y; }

  T dist_pow2() const { return x * x + y * y; }

  bool operator< (const Point2D &p) const {
    return dist_pow2() == p.dist_pow2() 
         ? ( y == p.y
             ? x < p.x
             : y < p.y )
         : dist_pow2() <  p.dist_pow2();
  }
  bool operator> (const Point2D &p) const {
    return dist_pow2() == p.dist_pow2()
         ? ( y == p.y
             ? x > p.x
             : y > p.y )
         : dist_pow2() >  p.dist_pow2();
  }
  bool operator<=(const Point2D &p) const { return (*this == p) || (*this < p); }
  bool operator>=(const Point2D &p) const { return (*this == p) || (*this > p); }
};

template<typename T>
std::istream& operator>>(std::istream &is, Point2D<T> &p)
{
  is >> p.x >> p.y;
  return is;
}

template<typename T>
std::ostream& operator<<(std::ostream &os, const Point2D<T> &p)
{
  os << '(' << p.x << ", " << p.y << ')';
  return os;
}

typedef Point2D<int64_t> Point;

uint64_t cost(uint64_t N, const vector<Point> &points, const Point &d)
{
  map<uint64_t, set<uint64_t>> edges;
  for (uint64_t n = 0; n < N; ++n) {
    edges[n] = set<uint64_t>();
  }
  
  for (uint64_t k = 0; k < N; ++k) {
    Point s = points[k] - d;
    
    auto itr = find(points.begin(), points.end(), s);
    if (itr != points.end()) {
      uint64_t src_index = distance(points.begin(), itr);
      edges[src_index].insert(k);
      edges[k].insert(src_index);
    }
  }
  
  uint64_t count = 0;
  vector<bool> flag(N, false);
  
  for (uint64_t k = 0; k < N; ++k) {
    if (flag[k]) { continue; }
    
    flag[k] = true;
    ++count;
    
    queue<uint64_t> q;
    q.push(k);
    while (!q.empty()) {
      uint64_t s = q.front(); q.pop();
      
      for (uint64_t d : edges[s]) {
        if (flag[d]) { continue; }
        
        flag[d] = true;
        q.push(d);
      }
    }
  }
  
  return count;
}

int main()
{
  uint64_t N;
  cin >> N;
  
  vector<Point> points(N);
  for (uint64_t n = 0; n < N; ++n) {
    cin >> points[n];
  }
  
  if (N == 1) {
    cout << 1 << endl;
    return 0;
  }
  
  uint64_t ans = 1e+12;
  
  for (uint64_t i = 0; i < N; ++i) {
    for (uint64_t j = 0; j < N; ++j) {
      if (i == j) { continue; }
      
      Point d = points[j] - points[i];
      
      ans = min(ans, cost(N, points, d));
    }
  }
  
  cout << ans << endl;
  
  return 0;
}

Measured memory_bytes: 384