import * as fs from "fs"

const judge = (L:number, R:number, d:number) => {
    let ans:number = 0
    for (let i:number = L; i <= R; i ++){
        if (i % d === 0){
            ans ++
        }
    }
    return ans
}

export const main = () => {
    const inp:string[] = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n')
    const data:number[] = inp[0].split(' ').map((val:string) => Number(val))

    const L: number = data[0]
    const R: number = data[1]
    const d: number = data[2]
    return  judge(L, R, d)
}

console.log(main())


import * as fs from "fs";

// inputで受け取り配列化する
const [L, R, d] = fs.readFileSync("/dev/stdin", "utf8").split(" ").map(Number);

let cnt = 0;

for (let index = L; index <= R; index++) {
  if (index % d === 0) {
    cnt++;
  }
}

console.log(cnt);


import { readFileSync } from "fs";

const read = () =>
  readFileSync(0, "utf8")
    .split("\n")
    .map((line) => line.split(" "));

const main = (input: string[][]) => {
  const [L, R, d] = input[0].map(Number);

  let answer = 0;

  for (let i = L; i <= R; i++) {
    if (i % d === 0) {
      answer += 1;
    }
  }

  return answer;
};

console.log(main(read()));


const Main = input => {
  const inputArray = input.split(' ');
  const l = inputArray[0];
  const r = inputArray[1];
  const d = inputArray[2];
  const diff = r - l + 1;
  let result = Math.round(diff / d);
  console.log(result);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const Main = input => {
  const inputArray = input.split(' ');
  const l = inputArray[0];
  const r = inputArray[1];
  const d = inputArray[2];
  const diff = r - l + 1;
  let result = Math.floor(diff / d);
  if(r % d == 0) result++;
  console.log(result);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const Main = input => {
  const inputArray = input.split(' ');
  const l = inputArray[0];
  const r = inputArray[1];
  const d = inputArray[2];
  const diff = r - l + 1;
  const result = Math.floor(diff / d);
  console.log(result);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


r = int(input())

print( 3* r **2 )


r = int(input())
print(3 * r ** 2)


r = int(input())
print(3*r**2)


r = input()
print (3 * r ** 2)


r = input()

print(3*r**2)


r = int(input())
print(r ** 2 * (r - 1))


/*
Stay innocent, be naive.
But still dream big.
Dream big to the point that it is beyond your ability and endeavour to achieve it.
So dream big and don�t lose your innocence.
*/
import java.util.*;
import java.io.*;

   public class Main
   {
      public static void main(String args[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         System.out.println(3*N*N);
      }
      public static void sort(int[] arr)
      {
         //stable heap sort
         PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
         for(int a: arr)
            pq.add(a);
         for(int i=0; i < arr.length; i++)
            arr[i] = pq.poll();
      }
   }


import java.io.*;
import java.util.*;

public class Main{
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));

      //begin
      out.println((int) (Math.pow(sc.nextInt(), 2)) * 3);
      //end
      out.close();
   }

   public static PrintWriter out;

   public static class MyScanner {
      BufferedReader br;
      StringTokenizer st;

      public MyScanner() {
         br = new BufferedReader(new InputStreamReader(System.in));
      }

      String next() {
          while (st == null || !st.hasMoreElements()) {
              try {
                  st = new StringTokenizer(br.readLine());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return st.nextToken();
      }

      int nextInt() {
          return Integer.parseInt(next());
      }
      long nextLong() {
          return Long.parseLong(next());
      }
      double nextDouble() {
          return Double.parseDouble(next());
      }
      String nextLine(){
          String str = "";
	  try {
	     str = br.readLine();
	  } catch (IOException e) {
	     e.printStackTrace();
	  }
	  return str;
      }
   }
}


import java.io.*;
import java.util.*;
class Main{
	static final long MOD = 1_000_000_007; // 10^9+7
    static final int MAX = 2_147_483_646; // intMax
    static final int INF = 1_000_000_000; // 10^9
    public static void main(String[] args) throws Exception {
		hayami saori = new hayami();
		int a = saori.saori_hayami();
		System.out.println(3*a*a);
		saori.close();
    }
}

class hayami implements Closeable {
	private final InputStream in = System.in;
	private final byte[] hayami = new byte[1024];
	private int Hayami = 0;
	private int saori = 0;
	private boolean HayamiSaori() {
		if (Hayami < saori) {
			return true;
		}else{
			Hayami = 0;
			try {
				saori = in.read(hayami);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (saori <= 0) {
				return false;
			}
		}
		return true;
	}
	private int SaoriHayami() {
		if (HayamiSaori()) {
            return hayami[Hayami++];
         }else{
             return -1;
         }
	}
	private static boolean hayami_saori(int hayami) {
		return 33 <= hayami && hayami <= 126;
	}
	public boolean hayamisaori() {
		while(HayamiSaori() && !hayami_saori(hayami[Hayami])) Hayami++; return HayamiSaori();
	}
	public String nextHayami() {
		if (!hayamisaori()) throw new NoSuchElementException();
		StringBuilder hayamin = new StringBuilder();
		int saori = SaoriHayami();
		while(hayami_saori(saori)) {
			hayamin.appendCodePoint(saori);
			saori = SaoriHayami();
		}
		return hayamin.toString();
	}
	public long saorihayami() {//nextLong
		if (!hayamisaori()) throw new NoSuchElementException();
		long hayami = 0;
		boolean misao = false;
		int saori = SaoriHayami();
		if (saori == '-') {
			misao = true;
			saori = SaoriHayami();
		}
		if (saori < '0' || '9' < saori) {
			throw new NumberFormatException();
		}
		while(true){
			if ('0' <= saori && saori <= '9') {
				hayami *= 10;
				hayami += saori - '0';
			}else if(saori == -1 || !hayami_saori(saori)){
				return misao ? -hayami : hayami;
			}else{
				throw new NumberFormatException();
			}
			saori = SaoriHayami();
		}
	}
	public int saori_hayami() {//nextInt
		long hayami = saorihayami();
		if (hayami < Integer.MIN_VALUE || hayami > Integer.MAX_VALUE) throw new NumberFormatException();
		return (int) hayami;
	}
	public double Hayamin() { //nextDouble
		return Double.parseDouble(nextHayami());
	}
	public void close() {
		try {
			in.close();
		} catch (IOException e) {
		}
    }

}


a = []
t = int(input())
for i in range(t):
    a.append(int(input()))

for i in range(t):
    b = a[i]
    del a[i]
    print(max(a))
    a.insert(i,b)


a = []
t = int(input())
s = ""
for i in range(t):
    a.append(int(input()))

for i in range(t):
    b = a[i]
    del a[i]
    print(max(a))
    a.insert(i,b)


import java.util.AbstractMap;
import java.util.Scanner;

public class Main {

     static Scanner scanner;

     public static void main(String[] args) {
         scanner = new Scanner(System.in);

         int N=gi();
         int[] a=new int[N+1];
         int[] b=new int[N+1];

         for(int i=1; i<=N;i++) {
        	 a[i]=gi();
         }

         for (int i=N; i>0; i--) {
        	 int t=0;
        	 for(int j=2*i; j<N;j+=i) {
        		 t+=b[j];
        	 }
        	 if(t%2==a[i]) {
        		 b[i]=0;
        	 } else {
        		 b[i]=1;
        	 }
         }
         int m=0;
         StringBuilder sb=new StringBuilder();
         for(int i=1; i<=N;i++) {
        	 if(b[i]==1) {
        		 if(m!=0)sb.append(" ");
        		 m++;
        		 sb.append(i);
        	 }
         }

         System.out.println(m);
         System.out.println(sb);
     }

     public static class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> implements Comparable<Pair<K, V>> {
    		/** serialVersionUID. */
    	    private static final long serialVersionUID = 6411527075103472113L;

    	    public Pair(final K key, final V value) {
    	        super(key, value);
    	    }

    		@Override
    		public int compareTo(Pair<K, V> o) {

    			Comparable key = (Comparable)this.getKey();
    			Comparable key2 = (Comparable)o.getKey();

    			return key.compareTo(key2);
    		}

    	}

     // 文字列として入力を取得
     public static String gs() {
          return scanner.next();
     }

     // intとして入力を取得
     public static int gi() {
          return Integer.parseInt(scanner.next());
     }

     // longとして入力を取得
     public static long gl() {
          return Long.parseLong(scanner.next());
     }

     // doubleとして入力を取得
     public static double gd() {
          return Double.parseDouble(scanner.next());
     }
}


#include<iostream>
#include<algorithm>
#include <vector>
#include <set>
using namespace std;
long long MOD=1000000007;

int main(){
	int a;
	cin>>a;
	cout<<3*a*a<<endl;
}


#include <iostream>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	cout<<n*n*3<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

int main(){
	int r;
	cin >> r;
	cout << 3*r*r << endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
  int a; cin >> a;
  cout << 3*a*a*a << endl;
}


r=int(input())
print(3*r*r)


#include<bits/stdc++.h>
using namespace std;

#define     fast()              ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define     ll                  long long int
#define     test()              ll t; cin>>t; while(t--)
#define     lp0(i,begin,end)    for(ll i=begin;i<end;i++)
#define     lp1(i,begin,end)    for(ll i=begin;i<=end;i++)
#define     rlp(i,begin,end)    for(ll i=end;i>=begin;i--)
#define     prec(n)             fixed<<setprecision(n)
#define     initial(a,i)        memset(a,i,sizeof(a))
#define     pb                  push_back
#define     PI                  3.1415926535897932384626433832795
#define     MOD                 1000000007
#define     F                   first
#define     S                   second
#define     all(a)              (a).begin(),(a).end()
#define     BPC(x)              __builtin_popcountll(x)
#define     gcd(a,b)            __gcd(a,b)

ll gcd(ll a,ll b) {if (a==0) return b;return gcd(b%a,a);}

ll power(ll x,ll n)
{
    ll result = 1;
    while (n)
    {
        if (n & 1)
            result = result * x;
        n = n / 2;
        x = x * x;
    }
    return result;
}

// Solution Function
void solution(ll compte)
{
    // cout<<compte<<"\n";
    ll n;
    cin >> n;
    cout << 3*n*n << endl;
// Driver Function
int main()
{
    ll compte = 1;
    //test()
    //{
        solution(compte);
        compte++;
    //}
    return 0;
}


#include<stdio.h>
int main(void){
	int r;

	scanf("%d",&r);
	printf("%d\n", 3*r*r);

	return 0;
}


#include <stdio.h>
int main(void){
    int r;
    scanf("%d",&r);
    r=r*r;
    printf("%d",3*r);
    return 0;
}


#include <stdio.h>

int main(){

    int r, s;

    //input
    scanf("%d", &r);

    //calc
    s = 3* r*r;

    //output
    printf("%d\n", s);

    return 0;
}


#include<stdio.h>
int main() {
        int r,ans;
        scanf("%d",&r);
        ans=3*r*r;
        printf("%d",&ans);
        return 0;
}


/*  ex4_1
    kosaq       */

#include <stdio.h>
#include <math.h>

int main(void){
    double n_tree;//N本の林檎の木をn_treeで定義
    double d_range;//一人は、D本先までを監視できるのでDをd_rangeで定義
    double one_observe;//一人が監視できる林檎の木の数
    int people_number;//N本の林檎の木を監視するために必要な人数の最小値

    scanf("%lf %lf", &n_tree, &d_range);//NとDを入力

    one_observe = d_range * 2 + 1;//一人が監視できる林檎の木の数
    people_number = ceil(n_tree / one_observe);//N本の林檎の木を監視するために必要な人数の最小値は(n_tree / one_observ)eの小数値を切り上げた整数
    printf("%d\n", people_number);//N本の林檎の木を監視するために必要な人数の最小値を出力

    return 0;
}


/* ex4_1
   UMAboogie */

#include<stdio.h>
#include<math.h>

int main(void){
  double apple,range;
  scanf("%lf  %lf",&apple,&range); //りんごの個数と監視の幅を入力
  int watchmen = ceil(apple / (range*2 + 1)); //1人の監視員は監視の幅の2倍に１加えた数のりんごを監視できるので、りんごの数をそれで割り小数点以下、切り上げる
  printf("%d",watchmen); //監視員の人数を出力
  return 0;
}


function Main(input) {
  input = input.trim();
  console.log(input*input*3);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
    input = input.trim()
  console.log(input*input*3)
}Main(require("fs").readFileSync("/dev/stdin", "utf8"));


var fs = require('fs');

var input = fs.readFileSync('/dev/stdin', 'utf8');
var inputNumber = Number(input);

console.log(3 * inputNumber * inputNumber);


function Main(input) {
    input = input.trim(
      console.log(input*input*3)
}Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const fs = require('fs');

const input = (fs.readFileSync('/dev/stdin', 'utf8') as string);
const inputNumber = Number(input);

console.log(3 * inputNumber * inputNumber);


// inputに入力データ全体が入る
function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
	input = input.split("\n");
	// input1 = input.split('').map((n) => (parseInt(n)))
	// 配列の最初をのぞく
	var arr = input.map((n) => parseInt(n)).filter((n , i) => (i != 0))
	// var arr = input.map((n) => parseInt(n))
	var ans = 0
	arr.forEach((n, i) => {
		// console.log(Math.max(arr.filter((num, s) => (s != i))))
		console.log(arr.filter((num, index) => (index != i)).reduce((nn, ii) => (Math.max(nn, ii))))
	})

	//出力
	// console.log(ans )
}
// *この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
// Main(require('fs').readFileSync('./input.txt', 'utf-8'));


package main

import (
	"fmt"
)

func pow(x, n, mod int64) int64 {
	if n == 0 {
		return 1
	}
	xx := x * x % mod
	r := pow(xx, n/2, mod)
	if n%2 == 1 {
		r = x * r % mod
	}
	return r
}

const mod = 1e9 + 7

func main() {
	var n int
	fmt.Scan(&n)

	fmt.Println(3 * n * n)

}


package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"math"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		sc.Split(bufio.ScanWords)
		return sc
	}()
)

func main() {
	r := getInt()
	fmt.Println(3 * r * r)
}

type Graph struct {
	n     int
	edges [][]int
}

func NewGraph(n int) *Graph {
	g := &Graph{
		n:     n,
		edges: make([][]int, n),
	}
	return g
}

func (g *Graph) AddEdge(u, v int) {
	g.edges[v] = append(g.edges[v], u)
	g.edges[u] = append(g.edges[u], v)
}

func dfs(c int, edges [][]int, visited map[int]struct{}) {
	visited[c] = struct{}{}

	for _, v := range edges[c] {
		_, flag := visited[v]
		if flag {
			continue
		}
		dfs(v, edges, visited)
	}
}

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getIntArray(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = getInt()
	}
	return array
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

func abs(a int) int {
	return int(math.Abs(float64(a)))
}

func pow(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func powMod(n, p int) int {
	if p == 0 {
		return 1
	} else if p%2 == 0 {
		t := powMod(n, p/2)
		return calcMod(t * t)
	} else {
		return calcMod(n * powMod(n, p-1))
	}
}

func min(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton min() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Min(float64(res), float64(nums[i])))
	}
	return res
}

func max(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton max() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Max(float64(res), float64(nums[i])))
	}
	return res
}

func strSearch(a []string, b string) bool {
	for i := 0; i < len(a); i++ {
		if a[i] == b {
			return true
		}
	}
	return false
}

func printIntArray(array []int) {
	strArray := fmt.Sprint(array)
	fmt.Println(strArray[1 : len(strArray)-1])
}

func calcMod(x int) int {
	return x % mod
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func isPrime(n int) bool {
	if n < 2 {
		return false
	} else if n == 2 {
		return true
	} else if n % 2 == 0 {
		return false
	}

	sqrtN := int(math.Sqrt(float64(n)))
	for i := 3; i <= sqrtN; i += 2 {
		if n % i == 0 {
			return false
		}
	}

	return true
}

func contains(s []int, e int) bool {
	for _, v := range s {
		if e == v {
			return true
		}
	}
	return false
}

func makeRange(min, max int) []int {
	a := make([]int, max-min+1)
	for i := range a {
		a[i] = min + i
	}
	return a
}

func powerset2(nums []int) [][]int {
	length := int(math.Pow(2, float64(len(nums))))
	result := make([][]int, length)

	index := 0
	result[index] = []int{}
	index++

	for _, n := range nums {
		max := index
		for i := 0; i < max; i++ {
			result[index] = copyAndAppend(result[i], n)
			index++
		}
	}

	return result
}

func copyAndAppend(nums []int, n int) []int {
	dst := make([]int, len(nums)+1)
	copy(dst, nums)
	dst[len(nums)] = n
	return dst
}

func calcGcd(x, y int) int {
	if y == 0 {
		return x
	} else if x >= y {
		return calcGcd(y, x % y)
	} else {
		return calcGcd(x, y % x)
	}
}

func getDivisor(n int) []int {
	var divisor []int
	divisor = append(divisor, 1)
	if n != 1 {
		divisor = append(divisor, n)
	}

	sqrt := int(math.Sqrt(float64(n)))
	for i := 2; i <= sqrt; i++ {
		if n % i == 0 {
			divisor = append(divisor, i)
			divisor = append(divisor, n/i)
		}
	}
	return divisor
}

type intHeap []int

func (h intHeap) Len() int {
	return len(h)
}

func (h intHeap) Less(i, j int) bool {
	return h[i] > h[j]
}

func (h intHeap) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func initHeap() *intHeap {
	ih := &intHeap{}
	heap.Init(ih)
	return ih
}

func (h *intHeap) pushHeap(n int) {
	heap.Push(h, n)
}

func (h *intHeap) popHeap() int {
	return heap.Pop(h).(int)
}

func factMod(n int) int {
	value := 1
	for ; n > 1; n-- {
		value = calcMod(value * n)
	}
	return value
}

func combinationMod(n, k int) int {
	factN := factMod(n)
	factK := factMod(k)
	factNK := factMod(n - k)
	factKR := powMod(factK, mod - 2)
	factNKR := powMod(factNK, mod - 2)
	return calcMod(factN * calcMod(factKR * factNKR))
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	read  = bufio.NewReader(os.Stdin)
	write = bufio.NewWriter(os.Stdout)
)

func min(a, b int) int {
	if a <= b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a >= b {
		return a
	}
	return b
}

func yesno(result bool) {
	if result {
		fmt.Fprintln(write, "Yes")
	} else {
		fmt.Fprintln(write, "No")
	}
}

func printansStr(result bool, a, b string) {
	if result {
		fmt.Fprintln(write, a)
	} else {
		fmt.Fprintln(write, b)
	}
}

func printansInt(result bool, a, b int) {
	if result {
		fmt.Fprintln(write, a)
	} else {
		fmt.Fprintln(write, b)
	}
}

func main() {
	defer write.Flush()

	var a int
	fmt.Fscan(read, &a)
	fmt.Fprintln(write, 3*a*a)
}


package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)
	var d int
	fmt.Scan(&d)

	ans := n / ((2 * d) + 1)
	if ans*((2*d)+1) != n {
		fmt.Print(ans + 1)
		return
	}
	fmt.Print(ans)
}


package main

import (
	"fmt"
)

type ll int64

func main() {

	var N int
	fmt.Scan(&N)

	a := make([]int, N+1)
	ans := 0
	ans_slice := make([]int,N+1)

	for i := 0 ; i < N ;i++ {
		//1 origin
		fmt.Scan(&a[i+1])
	}

	ans_flag := 0
	for i:= N; i > 0 ; i--  {//Nから1まで

		k:= i
		j := 1
		ans_flag = 0

		for k <= N  {
			ans_flag += a[k]
			j++
			k = i * j
		}

		if ans_flag % 2 != 0 {//2で割り切れない
			ans++
			ans_slice[i] = 1
		}

	}

	fmt.Println(ans)
	for i:=1;i <=N ;i++  {
		if ans_slice[i] == 1 {
			fmt.Print(i)
			//fmt.Print(" ")
		}
	}
	//fmt.Println("")

}


package main

import "fmt"

func main() {
	var r int
	fmt.Scanf("%d",r)

	fmt.Printf("%d",3 * r * r)
}


r=gets.chomp.to_i
p 3*r*r


r = gets.to_i
puts 3 * r * r


# describe Abc134A do
#   context 'test' do
#     it 'sample' do
#       expect(Abc134A.calc(4)).to be(48)
#       expect(Abc134A.calc(15)).to be(675)
#       expect(Abc134A.calc(80)).to be(19200)
#     end
#   end
# end

class Abc134A
  def self.input()
    password_string = STDIN.gets.to_i
  end

  def self.output(result)
    puts result
  end

  def self.calc(r)
    3 * r * r
  end

  def self.main()
    r = input()
    result = calc(r)
    output(result)
  end
end

if __FILE__ == $0
  Abc134A.main
  exit
end


puts 3*(gets.to_i)**3


N = gets.to_i
A = readlines.map(&:to_i)

tmp = []

N.times do |ai|

	tmp = A.dup
	tmp.delete_at(ai)
	puts tmp.max

end


n,d=gets.split.map(&:to_i)
p (n+2*d)/(2*d+1)


use std::io::*;

fn main() {
    let mut s: String = String::new();
    stdin().read_to_string(&mut s).ok();
    let mut itr = s.trim().split_whitespace();

    let r: usize = itr.next().unwrap().parse().unwrap();
    println!("{}", 3 * r * r);
}


#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn f(s: &Vec<i32>) -> bool{

    return true;
}

use std::iter::Iterator;
use std::cmp;

fn main() {
    input! {
        r : i32,
    }

    println!("{}", 3 * r * r);

}


use std::cmp;

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input! {
    	a:usize,
    }

    println!("{}", 3*a*a);
}


fn main() {
  let r = {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim_end().parse::<i64>().unwrap()
  };

  print!("{}", 3 * r * r);
}


use std::str::FromStr;
use std::fmt::Debug;
use std::cmp;

#[allow(dead_code)]
fn read_as_vec<T>() -> Vec<T>
where T: FromStr, <T as FromStr>::Err : Debug{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|c| T::from_str(c).unwrap()).collect()

}

#[allow(dead_code)]
fn read_as_string() -> String{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

fn main(){
    let n: usize = read_as_vec()[0];
    let a: Vec<i32> = read_as_vec();

    //if status[i] == true, we put a ball into ith box
    let mut status: Vec<bool> = vec![false;n];

    for i in (0..n).rev(){
        //println!("i = {}, a[i] = {}", i, a[i]);
        let mut sum = 0;
        for j in i+1..n{
            if (j+1)%(i+1) == 0 && status[j]{
                sum += 1;
            }
        }

        if (sum%2 == 0 && a[i] == 1) || (sum%2 == 1 && a[i] == 0){
            status[i] = true;
        }
        //println!("{:?}", status);
    }
    let num_balls = status.iter().filter(|x| **x == true).count();
    println!("{}", num_balls);

    if num_balls == 0{
        return;
    }

    for (i, is_ball) in status.iter().enumerate(){
        if *is_ball{
            print!("{} ", i+1);
        }
    }
    println!("");
}


use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: i32 = read();
    let mut vec: Vec<i32> = vec![];
    for _ in 0..n {
        vec.push(read());
    }
    let mut rev_ans = vec![0; vec.len()];
    let mut m = 0;
    let mut ans = vec![];
    for (i_1, _) in vec.iter().enumerate().rev() {
        let i = i_1 + 1;
        let mut sum = 0;
        for j in 1..(vec.len() / i) {
            sum += rev_ans[(i * j) - 1];
        }
        if sum % 2 == vec[i_1] {
            rev_ans[i_1] = 0;
        } else {
            rev_ans[i_1] = 1;
            ans.push(i);
            m += 1;
        }
    }
    println!("{}", m);
    println!(
        "{}",
        ans.iter()
            .map(|i| i.to_string())
            .collect::<Vec<String>>()
            .join(" ")
    );
}


let r=Int(readLine()!)!
print(3*r*r)


let a=(Int)(readLine()!)!
print(a*a*3)


func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func main() {
    let r = Int(readLine()!)!

    print(3 * r * r)
}

main()


let r=Int(readLine()!)
print(3*r*r)


let r=Int(readLine()!)
print(3*pow(r,2))


let r=Int(readLine()!)
print(3*r**2)


import * as fs from 'fs'

//in
// 4
//out
// 48
// 3a2
const main = (inp: string) => {

    const r :number = parseInt(inp);

    console.log(3*r**2);
};

main(fs.readFileSync('/dev/stdin', 'utf8').trim());


'use strict'
const main = (input: string) => {
    const r: number = Number(input)
    console.log( 3 * r ** 2);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


export class Main {
  static main(input): string {
    const tmp: string[] = input.split("\n");
    const t: number = tmp[0].split(" ").map(int => parseInt(int))[0];
    return `${3 * t * t}`;
  }
}
 console.log(Main.main(require("fs").readFileSync("/dev/stdin", "utf8")));


process.stdin.resume();
process.stdin.setEncoding('utf8');

var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
  lines.push(line);
});
reader.on('close', () => {
  const r = Number(lines[0]);
  console.log(2 * (r ** 2));
});


n = int(input())
xy = []
for i in range(n):
    xy.append(list(map(int, input().split())))
xy.sort(key = lambda x: x[1])
xy.sort()
if n == 1:
    print(1)
else:
    dif = []
    for i in range(n):
        for j in range(i + 1, n):
            dif.append((xy[j][0] - xy[i][0], xy[j][1] - xy[i][1]))
    count_dif = {}
    for i in dif:
        count_dif.setdefault(i, 0)
        count_dif[i] += 1
    print(n - max(count_dif.values()))


N = list(map(int, input().split()))
d = {0:0}

pos=[]
for x in range(N[0]):
    a = list(map(int, input().split()))
    for y in pos:
        key = (a[0]-y[0])*(10**11)+(a[1]-y[1])
        if key<0:
            key=-key
        if key not in d.keys():
            d[key] = 0
        d[key] += 1
    pos.append(a)

print(N[0]-max(d.values()))


n=int(input())
if n==1:
	print(1)
	exit()
xy = sorted([list(map(int,input().split())) for i in range(n)])
p=q=0
ans=0
dic={}
for i in range(n-1):
	for j in range(i+1,n):
		p = xy[j][0]-xy[i][0]
		q = xy[j][1]-xy[i][1]
		if (p,q) in dic:
			dic[(p,q)]+=1
		else:
			dic[(p,q)]=1
print(n-max(dic.values()))


n=int(input())
l=[]
if n==1:
  print(1)
else:
  for i in range(n):
    x,y=map(int,input().split())
    l.append([x,y])

  dic={}
  for i in range(n):
    for j in range(i+1,n):
      dx,dy = l[j][0]-l[i][0],l[j][1]-l[i][1]
      if (dx,dy) not in dic:
        dic[dx,dy]=1
      else:
        dic[dx,dy]+=1

  dic=sorted(dic.items(),key=lambda x:x[1],reverse=True)
  print(n-dic[0][1])


import sys, math, re
from itertools import accumulate
sys.setrecursionlimit(10**9)

def input():
    return sys.stdin.readline()[:-1]

def mi():
    return map(int, input().split())

def ii():
    return int(input())

def i2(n):
    tmp = [list(mi()) for i in range(n)]
    return [list(i) for i in zip(*tmp)]

def main():
    N = ii()
    x, y = i2(N)
    d = {}

    for i in range(N):
        for j in range(N):
            if i == j:
                continue

            pair = (x[i]-x[j], y[i]-y[j])
            if not pair in d:
                d[pair] = 0

            d[pair] += 1

    print(N-max(d.values()))

if __name__ == "__main__":
    main()


import sys, math, re
from itertools import accumulate
sys.setrecursionlimit(10**9)

def input():
    return sys.stdin.readline()[:-1]

def mi():
    return map(int, input().split())

def ii():
    return int(input())

def i2(n):
    tmp = [list(mi()) for i in range(n)]
    return [list(i) for i in zip(*tmp)]

def main():
    N = ii()
    x, y = i2(N)
    ans = -1

    s = set()
    for i in range(N):
        for j in range(N):
            if i != j:
                s.add((x[i]-x[j], y[i]-y[j]))

    for p, q in s:
        cnt = 0
        for i in range(N):
            for j in range(N):
                if i == j:
                    continue
                if x[i]-x[j] == p and y[i]-y[j] == q:
                    cnt += 1
        ans = max(ans, cnt)

    print(N-ans)

if __name__ == "__main__":
    main()


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.InputMismatchException;

public class Main {
	static InputStream is;
	static PrintWriter out;
	static String INPUT = "";

	static void solve()
	{
		int n = ni();
		int[][] co = new int[n][];
		for(int i= 0;i < n;i++)co[i] = na(2);
		int[][] chas = new int[n*(n-1)/2][];
		int p = 0;
		for(int i = 0;i < n;i++){
			for(int j = i+1;j < n;j++){
				int[] cs = new int[]{co[i][0]-co[j][0], co[i][1]-co[j][1]};
				if(cs[1] > 0 || cs[1] == 0 && cs[0] < 0){
					cs[0] = -cs[0];
					cs[1] = -cs[1];
				}
				chas[p++] = cs;
			}
		}
		Arrays.sort(chas, new Comparator<int[]>() {
			public int compare(int[] a, int[] b) {
				if(a[0] != b[0])return Integer.compare(a[0], b[0]);
				return Integer.compare(a[1], b[1]);
			}
		});

		int cost = n;
		for(int i = 0;i < p;){
			int j = i;
			while(j < p && Arrays.equals(chas[i], chas[j]))j++;

			cost = Math.min(cost, n-(j-i));

			i = j;
		}
		out.println(cost);
	}

	public static void main(String[] args) throws Exception
	{
		long S = System.currentTimeMillis();
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		solve();
		out.flush();
		long G = System.currentTimeMillis();
		tr(G-S+"ms");
	}

	private static boolean eof()
	{
		if(lenbuf == -1)return true;
		int lptr = ptrbuf;
		while(lptr < lenbuf)if(!isSpaceChar(inbuf[lptr++]))return false;

		try {
			is.mark(1000);
			while(true){
				int b = is.read();
				if(b == -1){
					is.reset();
					return true;
				}else if(!isSpaceChar(b)){
					is.reset();
					return false;
				}
			}
		} catch (IOException e) {
			return true;
		}
	}

	private static byte[] inbuf = new byte[1024];
	static int lenbuf = 0, ptrbuf = 0;

	private static int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private static boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
//	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
	private static int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private static double nd() { return Double.parseDouble(ns()); }
	private static char nc() { return (char)skip(); }

	private static String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private static char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private static char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private static int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private static int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) { if(INPUT.length() != 0)System.out.println(Arrays.deepToString(o)); }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        int n = sc.nextInt();
        long[][] x = new long[n][2];
        for(int i=0; i<n; i++){
            x[i][0] = sc.nextLong();
            x[i][1] = sc.nextLong();
        }

        HashMap<Long, Integer> map = new HashMap<Long, Integer>();

        int maxval = 0;
        long maxtmp = 0;
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                if(i == j) continue;
                long tmp = (x[i][0] - x[j][0]) * 2000000000L + (x[i][1] - x[j][1]);
                int val = 0;
                if(map.containsKey(tmp)){
                    val = map.remove(tmp) + 1;
                    map.put(tmp, val);
                }else{
                    val = 1;
                    map.put(tmp, val);
                }
                if(val > maxval){
                    maxval = val;
                    maxtmp = tmp;
                }
            }
        }

        System.out.println(Math.max(1, n-maxval));
    }

    private static class FastScanner {
        private final InputStream in = System.in;
        private final byte[] buffer = new byte[1024];
        private int ptr = 0;
        private int buflen = 0;

        private boolean hasNextByte() {
            if (ptr < buflen) {
                return true;
            } else {
                ptr = 0;
                try {
                    buflen = in.read(buffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (buflen <= 0) {
                    return false;
                }
            }
            return true;
        }

        private int readByte() {
            if (hasNextByte())
                return buffer[ptr++];
            else
                return -1;
        }

        private static boolean isPrintableChar(int c) {
            return 33 <= c && c <= 126;
        }

        public boolean hasNext() {
            while (hasNextByte() && !isPrintableChar(buffer[ptr]))
                ptr++;
            return hasNextByte();
        }

        public String next() {
            if (!hasNext())
                throw new NoSuchElementException();
            StringBuilder sb = new StringBuilder();
            int b = readByte();
            while (isPrintableChar(b)) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public long nextLong() {
            if (!hasNext())
                throw new NoSuchElementException();
            long n = 0;
            boolean minus = false;
            int b = readByte();
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            if (b < '0' || '9' < b) {
                throw new NumberFormatException();
            }
            while (true) {
                if ('0' <= b && b <= '9') {
                    n *= 10;
                    n += b - '0';
                } else if (b == -1 || !isPrintableChar(b)) {
                    return minus ? -n : n;
                } else {
                    throw new NumberFormatException();
                }
                b = readByte();
            }
        }

        public int nextInt() {
            long nl = nextLong();
            if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
                throw new NumberFormatException();
            return (int) nl;
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }
    }

}


import java.io.*;
import java.util.*;
import java.math.*;
// import java.awt.Point;

public class Main {
    InputStream is;
    PrintWriter out;
    String INPUT = "";

    // static int mod = 1_000_000_007;
    int mod = 998244353;
    // long inf = Long.MAX_VALUE/2;
    int inf = Integer.MAX_VALUE/2;

    void solve(){
        int n = ni();
        long[][] board = new long[n][2];
        for(int i = 0; i < n; i++){
            board[i][0] = nl();
            board[i][1] = nl();
        }
        HashMap<Long,Integer> map = new HashMap<>();
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(i==j) continue;
                long xdif = board[j][0] - board[i][0];
                long ydif = board[j][1] - board[i][1];
                // out.println(xdif+" "+ydif);
                long key = xdif * 10000000000l + ydif;
                map.put(key,map.getOrDefault(key, 0)+1);
            }
        }
        long ans = 0;
        for(long m : map.keySet()){
            ans = Math.max(map.get(m), ans);
        }
        out.println(n-ans);
    }

    void run() throws Exception
    {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        out.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new Main().run(); }

    private byte[] inbuf = new byte[1024];
    private int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b) && b != ' ')){
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }

}


import java.io.*;
import java.math.*;
import java.util.*;
public class Main {
	static int ans = 100;
	static int[][] balls;
	static int N;
	static boolean[] taken;
	public static void main(String[] args) {
		/*Fixate two coordinates in ordered pairs and extend same arithmetic difference for as
		 * long as possible (sort coordinates first)
		 * Make connected graphs of coordinates that can be achieved with set p and q values
		 * */
		FastScanner I = new FastScanner(); //Input
		OutPut O = new OutPut(); //Output
		N = I.nextInt();
		balls = new int[N][2];
		for (int i = 0; i < N; i++) {
			balls[i][0] = I.nextInt();
			balls[i][1] = I.nextInt();
		}
		Arrays.sort(balls,(a,b)->Integer.compare(a[0], b[0]));
		solve();
		for (int i = 0; i < N; i++) {
			int x = balls[i][0];
			int y = balls[i][1];
			balls[i][0]=y;
			balls[i][1]=x;
		}
		Arrays.sort(balls,(a,b)->Integer.compare(a[0], b[0]));
		solve();
		O.pln(ans);
	}
	public static void solve() {
		for (int add = 1; add<N; add++) {
			taken = new boolean[N];
			int p = balls[add][0]-balls[0][0];
			int q = balls[add][1]-balls[0][1]; //Differences
			ans=min(ans,check(p,q));
		}
	}
	public static int check(int p, int q) {
		int ret = 0;
		while (true) {
			boolean added=false;
			int start = 0;
			int x = -1;
			int y = -1; //Coordinates that we want next
			for (int i = 0; i < N; i++) {
				if (!taken[i]) {
					added=true;
					ret++;
					start=i;
					taken[i]=true;
					x=balls[i][0]+p;
					y=balls[i][1]+q;
					break;
				}
			}
			if (!added) break;
			for (int i = start+1; i < N; i++) {
				if (balls[i][0]==x&&balls[i][1]==y) {
					taken[i]=true;
					x+=p;
					y+=q;
				}
			}
		}
		return ret;
	}
	public static double max(double a, double b) {return Math.max(a, b);}
	public static double min(double a, double b) {return Math.min(a, b);}
	public static long min(long a, long b) {return Math.min(a,b);}
	public static long max(long a, long b) {return Math.max(a,b);}
	public static int min(int a, int b) {return Math.min(a,b);}
	public static int max(int a, int b) {return Math.max(a,b);}
	public static long abs(long x) {return Math.abs(x);}
	public static long ceil(long num, long den) {long ans = num/den; if (num%den!=0)
	ans++; return ans;}
	public static long GCD(long a, long b) {
		if (a==0||b==0) return max(a,b);
		return GCD(min(a,b),max(a,b)%min(a,b));
	}
	public static long FastExp(long base, long exp, long mod) {
		long ans=1;
		while (exp>0) {
			if (exp%2==1) ans*=base;
			exp/=2;
			base*=base;
			base%=mod;
			ans%=mod;
		}
		return ans;
	}
	public static long ModInv(long num,long mod) {return FastExp(num,mod-2,mod);}
	public static int pop(long x) { //Returns number of bits within a number
		int cnt = 0;
		while (x>0) {
			if (x%2==1) cnt++;
			x/=2;
		}
		return cnt;
	}
	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}
		int nextInt() {return Integer.parseInt(next());}
		long nextLong() {return Long.parseLong(next());};
		double nextDouble() {return Double.parseDouble(next());}
	}
	static class OutPut{
		PrintWriter w = new PrintWriter(System.out);
		void pln(double x) {w.println(x);w.flush();}
		void pln(boolean x) {w.println(x);w.flush();}
		void pln(int x) {w.println(x);w.flush();}
		void pln(long x) {w.println(x);w.flush();}
		void pln(String x) {w.println(x);w.flush();}
		void pln(char x) {w.println(x);w.flush();}
		void pln(StringBuilder x) {w.println(x);w.flush();}
		void pln(BigInteger x) {w.println(x);w.flush();}
		void p(int x) {w.print(x);w.flush();}
		void p(long x) {w.print(x);w.flush();}
		void p(String x) {w.print(x);w.flush();}
		void p(char x) {w.print(x);w.flush();}
		void p(StringBuilder x) {w.print(x);w.flush();}
		void p(BigInteger x) {w.print(x);w.flush();}
		void p(double x) {w.print(x);w.flush();}
		void p(boolean x) {w.print(x);w.flush();}
	}
}


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		if(N==1) {
			System.out.println(1);
			return ;
		}
		Main main = new Main();
		long x[]= new long[N];
		long y[] = new long[N];
		for (int i=0;i<N;i++) {
			x[i] = sc.nextLong();
			y[i] = sc.nextLong();
		}
		int max =1;
		Map<Point,Integer> map = new HashMap<Point,Integer>();
		for (int i=0;i<N;i++) {
			for (int j=i+1;j<N;j++) {
				if (i!=j) {
					Point t = main.new Point();
					t.p=Math.abs(x[j]-x[i]);
					t.q=Math.abs(y[j]-y[i]);
					if (map.containsKey(t)==false) {
						map.put(t, 1);
					} else {
						Integer in = map.get(t);
						map.put(t, in+1);
						if (in +1>max) {
							max = in +1;
						}
					}
				}

			}
		}
		System.out.println(N-max);
	}

	public class Point extends Object{
		long p;
		long q;

		@Override
		public boolean equals(Object o) {
			Point p = (Point)o;
			if (p.p==this.p&&p.q==this.q) {
				return true;
			}
			return false;
		}

		@Override
		public int hashCode() {
			return (int)(this.p%1000000+this.q%1000000);
		}

	}

}


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		Main main = new Main();
		long x[]= new long[N];
		long y[] = new long[N];
		for (int i=0;i<N;i++) {
			x[i] = sc.nextLong();
			y[i] = sc.nextLong();
		}
		int max =1;
		Map<Point,Integer> map = new HashMap<Point,Integer>();
		for (int i=0;i<N;i++) {
			for (int j=0;j<N;j++) {
				if (i!=j) {
					Point t = main.new Point();
					t.p=x[j]-x[i];
					t.q=y[j]-y[i];
					if (map.containsKey(t)==false) {
						map.put(t, 1);
					} else {
						Integer in = map.get(t);
						map.put(t, in+1);
						if (in +1>max) {
							max = in +1;
						}
					}
				}

			}
		}
		System.out.println(N-max);
	}

	public class Point extends Object{
		long p;
		long q;

		@Override
		public boolean equals(Object o) {
			Point p = (Point)o;
			if (p.p==this.p&&p.q==this.q) {
				return true;
			}
			return false;
		}

		@Override
		public int hashCode() {
			return (int)(this.p%1000000+this.q%1000000);
		}

	}

}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned uint;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldbl;
typedef pair<int, int> pii;
typedef pair<uint, uint> puu;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<uint> vu;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<pii> vpii;
typedef vector<puu> vpuu;
typedef vector<pll> vpll;
typedef vector<pull> vpull;
typedef vector<string> vstr;
typedef vector<double> vdbl;
typedef vector<ldbl> vldbl;
#define pb push_back
#define ppb pop_back
#define pfr push_front
#define ppfr pop_front
#define emp emplace
#define empb emplace_back
#define be begin
#define rbe rbegin
#define all(x) (x).be(), (x).end()
#define rall(x) (x).rbe(), (x).rend()
#define fir first
#define sec second
#define mkp make_pair
#define brif(cond) if (cond) break
#define ctif(cond) if (cond) continue
#define retif(cond) if (cond) return
void canhazfast() {ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);}
template<typename T> T gcd(T a, T b) {return b ? gcd(b, a%b) : a;}
template<typename T> T extgcd(T a, T b, T &x, T &y)
{
    T x0 = 1, y0 = 0, x1 = 0, y1 = 1;
    while (b) {
        T q = a/b; a %= b; swap(a, b);
        x0 -= q*x1; swap(x0, x1);
        y0 -= q*y1; swap(y0, y1);
    }
    x = x0; y = y0; return a;
}
int ctz(uint x) {return __builtin_ctz(x);}
int ctzll(ull x) {return __builtin_ctzll(x);}
int clz(uint x) {return __builtin_clz(x);}
int clzll(ull x) {return __builtin_clzll(x);}
int popcnt(uint x) {return __builtin_popcount(x);}
int popcntll(ull x) {return __builtin_popcountll(x);}
int bsr(uint x) {return 31^clz(x);}
int bsrll(ull x) {return 63^clzll(x);}

#define x fir
#define y sec

pii p[64];

int main()
{
    canhazfast();

    int n, ans = 0;
    map<pii, int> mp;

    cin >> n;
    for (int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y;
    sort(p, p+n);
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            int dx = p[i].x-p[j].x, dy = p[i].y-p[j].y;
            ++mp[{dx, dy}];
        }
    }
    for (const auto &e : mp) ans = max(ans, e.sec);
    ans = n-ans;
    cout << ans << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
typedef long long ll;

int main() {
    int n, x[55], y[55];
    cin >> n;
    for (int i = 0; i < n; i++) cin >> x[i] >> y[i];

    vector<pair<int, int>> v;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            v.emplace_back(x[i] - x[j], y[i] - y[j]);
            v.emplace_back(-x[i] + x[j], -y[i] + y[j]);
        }
    }

    if (n == 1) {
        cout << 1 << endl;
        return 0;
    }

    sort(v.begin(), v.end());

    int tmp = 1, mx = 1;
    for (int i = 0; i < v.size() - 1; i++) {
        if (v[i].first == v[i + 1].first && v[i].second == v[i + 1].second) tmp++;
        else tmp = 1;
        mx = max(mx, tmp);
    }

    cout << n - mx << endl;

}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
	char ch=getchar();ll x=0,f=0;
	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return f?-x:x;
}
int n,x[maxn],y[maxn],ans,dl;
PII d[maxn];
int main(){
	n=read();
	FOR(i,1,n) x[i]=read(),y[i]=read();
	FOR(i,1,n) FOR(j,1,n){
		if(i==j) continue;
		d[++dl]=MP(x[i]-x[j],y[i]-y[j]);
	}
	sort(d+1,d+dl+1);
	FOR(i,1,dl){
		int cnt=0,j=i;
		while(j<=dl && d[i]==d[j]) j++,cnt++;
		ans=max(ans,cnt);
		i=j-1;
	}
	printf("%d\n",n-ans);
}


#include <bits/stdc++.h>
using namespace std;

// ----------- define --------------
#define int long long
#define vi vector<int>
#define ii pair<int,int>
#define fi first
#define sc second
#define stoi stoll
#define popcnt __builtin_popcount
#define getBit(x, k) ((x >> k) & 1)
#define all(x) (x).begin(),(x).end()
// ---------------------------------

void Main() {
  int n; cin >> n;
  vector<ii> a(n);
  for (auto &i : a) cin >> i.fi >> i.sc;
  map<ii, int> mem;
  for (int i = 0; i < n - 1; i++)
  for (int j = i + 1; j < n; j++) {
    mem[ii(a[j].fi - a[i].fi, a[j].sc - a[i].sc)]++;
  }
  int ans = 0;
  for (auto &i : mem) {
    ans = max(ans, i.sc);
  }
  cout << n - ans << '\n';
}

signed main() {
#ifdef _DEBUG
  // freopen("in" , "r", stdin );
  cerr << "- ---- -- ----- <3\n";
#endif
  cin.tie(0)->sync_with_stdio(0);
  int T = 1;
  // cin >> T;
  while (T--) Main();
}


#include <algorithm>
#include <bitset>
#include <tuple>
#include <cstdint>
#include <cctype>
#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <math.h>
#include <cstring>
#include <array>
using namespace std;
using lint = long long;
const int dx[] = { 1,0,-1,0 };
const int dy[] = { 0,1,0,-1 };

const lint INF = 1ll << 60;
const int mod = 1000000007;
const int inf = INT_MAX;
void speed() {
	std::cin.tie(nullptr);
	std::ios::sync_with_stdio(false);
	return;
}

int main(void) {
	speed();
	int n; cin >> n;
	vector<pair<int, int>> d(n);
	map<pair<lint, lint>, lint> m;
	for (int i = 0; i < n; i++) {
		cin >> d[i].first >> d[i].second;
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < i; j++)
			m[make_pair(d[i].first - d[j].first, d[i].second - d[j].second)]++;
	lint ans = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < i; j++) {
			ans = max(ans, m[make_pair(d[i].first - d[j].first, d[i].second - d[j].second)]);
		}
	}
	cout << n - ans << endl;

	return 0;
}


#include <algorithm>
#include <bitset>
#include <tuple>
#include <cstdint>
#include <cctype>
#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <math.h>
#include <cstring>
#include <array>
using namespace std;
using lint = long long;
const int dx[] = { 1,0,-1,0 };
const int dy[] = { 0,1,0,-1 };

const lint INF = 1ll << 60;
const int mod = 1000000007;
const int inf = INT_MAX;
void speed() {
	std::cin.tie(nullptr);
	std::ios::sync_with_stdio(false);
	return;
}

int main(void) {
	speed();
	int n; cin >> n;
	vector<pair<int, int>> d(n);
	map<pair<lint, lint>, lint> m;
	for (int i = 0; i < n; i++) {
		cin >> d[i].first >> d[i].second;
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < i; j++)
			m[make_pair(d[i].first - d[j].first, d[i].second - d[j].second)]++;
	lint ans = 0;
	for (auto p : m) {
		ans = max(ans, m[make_pair(p.first.first, p.first.second)]);
	}
	cout << n - ans  << endl;

	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<stdbool.h>
typedef long long ll;
typedef long double ld;
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define repp(i,l,r,k)for(ll i=(l);i<(r);i+=(k))
#define INF (1LL<<60)
#define MOD1 1000000007
#define MAX_N (1 << 17)

void swap(ll *a, ll *b){ll c;c=*b;*b=*a;*a=c;}
ll max2(ll a,ll b){return a>=b?a:b;}
ll min2(ll a,ll b){return a>=b?b:a;}
ll minn(ll n, ll a[n]){ll b=INF;rep(i,0,n) b=min2(b,a[i]);return b;}
ll maxn(ll n, ll a[n]){ll b=-INF;rep(i,0,n) b=max2(b,a[i]);return b;}
ll ABS(ll a){return a>=0?a:(-a);}
ll POW(ll a, ll b){ll c=1;rep(i,0,b) c*=a;return c;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int upll(const void*a, const void*b){return*(ll*)a<*(ll*)b?-1:*(ll*)a>*(ll*)b?1:0;}
int downll(const void*a, const void*b){return*(ll*)a<*(ll*)b?1:*(ll*)a>*(ll*)b?-1:0;}
void sortup(ll*a,int n){qsort(a,n,sizeof(ll),upll);}
void sortdown(ll*a,int n){qsort(a,n,sizeof(ll),downll);}

typedef struct{
    ll aa;
    ll bb;
}frequent;

// 小大
int cmp1( const void *p, const void *q ) {
    if( ((frequent*)p)->aa == ((frequent*)q)->aa  ) return ((frequent*)p)->bb - ((frequent*)q)->bb;
    return ((frequent*)p)->aa - ((frequent*)q)->aa;
}

int main(void){
    // char ;
    ll n,ans=1;
    scanf("%lld",&n);
    if(n==1){
        printf("1\n");
        return 0;
    }
    ll x[n],y[n];
    rep(i,0,n){
        scanf("%lld%lld",&x[i],&y[i]);
    }
    ll r=0;
    frequent d[n*(n-1)];
    rep(i,0,n){
        rep(j,0,n){
            if(i==j) continue;
            d[r].aa=x[i]-x[j];
            d[r].bb=y[i]-y[j];
            r++;
        }
    }
    qsort(d,r,sizeof(frequent),cmp1);
    ll fff=1,ma=1;
    rep(i,1,r){
        if( d[i].aa==d[i-1].aa  && d[i].bb==d[i-1].bb ){
            fff++;
        }else{
            ma=max2(ma,fff);
            fff=1;
        }
        // printf("%lld f ",fff);
    }
    // rep(i,0,r){
    //     printf("%lld %lld\n",d[i].aa,d[i].bb);
    // }
    ans=n-ma;
    printf("%lld\n",ans);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include <stdlib.h>

typedef struct {
	long long x;
	long long y;
}posi_t;

typedef struct {
	long long p;
	long long q;
}pair_t;

int cmp(const void* a, const void* b) {
	if (((pair_t*)a)->p - ((pair_t*)b)->p != 0)
		return ((pair_t*)a)->p - ((pair_t*)b)->p;
	else
		return ((pair_t*)a)->q - ((pair_t*)b)->q;
}

int main(void) {
	long long n;
	posi_t posi[50] = { 0 };
	pair_t pair[2500] = { 0 };
	int cnt = 0, max = 1;
	int temp = 1;

	scanf("%lld", &n);
	for (int i = 0; i < n; i++)
		scanf("%lld %lld", &posi[i].x,&posi[i].y);

	if (n <= 2)printf("1");
	else {
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				pair[cnt].p = posi[i].x - posi[j].x;
				pair[cnt].q = posi[i].y - posi[j].y;
				if (pair[cnt].p < 0)
					pair[cnt].p *= -1, pair[cnt].q *= -1;
				else if (pair[cnt].p == 0 && pair[cnt].q < 0)
					pair[cnt].q *= -1;
				cnt++;
			}
		}
		qsort(pair, cnt, sizeof(pair_t), cmp);
		for (int i = 0; i <= cnt; i++) {
			if ((pair[i].p != 0 || pair[i].q != 0)&&pair[i].p == pair[i + 1].p &&
					pair[i].q == pair[i + 1].q)
					temp++;
			else {
				if (max < temp) {
					max = temp;
				}
					temp = 1;

			}
		}
		printf("%lld", n - max);
	}
	return 0;
}


#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#define P 1000000007

int comp(const void *a, const void *b){return *(int*)a-*(int*)b;}
int compl(const void *a, const void *b){return (*(long*)a<*(long*)b)-(*(long*)a>*(long*)b);}

int main(void){
	int n, i, j;
	int x[50], y[50];
	scanf("%d", &n);
	if(n==1){
		puts("1");
		return EXIT_SUCCESS;
	}
	for(i=0; i<n; i++){
		scanf("%d%d", x+i, y+i);
	}
	int s[2500][2], S=0;
	for(i=0; i<n; i++){
		for(j=0; j<i; j++){
			int dx=x[i]-x[j];
			int dy=y[i]-y[j];
			if(dy<0){dx=-dx; dy=-dy;}
			if(dy==0 && dx<0){dx=-dx;}
			s[S][0]=dx;
			s[S][1]=dy;
			S++;
		}
	}
	qsort(s, S, sizeof(int)*2, compl);
	int max=0, now=1;
	for(i=1; i<S; i++){
		if(s[i][0]==s[i-1][0] && s[i][1]==s[i-1][1]){
			now++;
		}else{
			if(now>max) max=now;
			now=1;
		}
	}
	if(now>max) max=now;
	printf("%d\n", n-max);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
typedef long long ll;
#define rep(i,n) for(ll i=0; i<(ll)(n); i++)
#define max(l,r) ((l)>(r)?l:r)
#define min(l,r) ((l)<(r)?l:r)
typedef struct{int first, second, pi, pj;} P;
int upcmpllp(const void *a, const void *b){
    if(((P*)a)->first != ((P*)b)->first)
        return (((P*)a)->first > ((P*)b)->first?1:-1);
    else
        return (((P*)a)->second == ((P*)b)->second ? 0 : (((P*)a)->second > ((P*)b)->second ? 1 : -1));
}
void sort_up(P *a, int n){ qsort(a, n, sizeof(P), upcmpllp); }

int main(){
    int n;
    scanf("%d", &n);
    int x[55], y[55];
    P diff[2525];
    rep(i, n) scanf("%d%d", &x[i], &y[i]);

    int ans = 55;
    int idx = 0;
    for(int i = 0; i < n; i++){
        for (int j = i+1; j < n; j++){
            diff[idx].first = x[j] - x[i];
            diff[idx].second = y[j] - y[i];
            diff[idx].pi = i;
            diff[idx].pj = j;
            idx++;
        }
    }
    sort_up(diff, idx);
    int ch[55];
    rep(i, n) ch[i] = 1;
    rep(i, idx){
        ch[diff[i].pj] = 0;
        if(i+1 < idx
           && diff[i].first == diff[i+1].first
           && diff[i].second == diff[i+1].second){
        }else{
            int tmp = 0;
            rep(j, n) tmp += ch[j];
            ans = min(ans, tmp);
            rep(j, n) ch[j] = 1;
        }
    }
    if(n == 1) ans = 1;
    printf("%d\n", ans);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
typedef long long ll;
#define rep(i,n) for(ll i=0; i<(ll)(n); i++)
#define max(l,r) ((l)>(r)?l:r)
#define min(l,r) ((l)<(r)?l:r)
typedef struct{int first, second, i, j;} P;
int upcmpllp(const void *a, const void *b){
    if(((P*)a)->first != ((P*)b)->first)
        return (((P*)a)->first > ((P*)b)->first?1:-1);
    else
        return (((P*)a)->second == ((P*)b)->second ? 0 : (((P*)a)->second > ((P*)b)->second ? 1 : -1));
}
void sort_up(P *a, int n){ qsort(a, n, sizeof(P), upcmpllp); }

int main(){
    int n;
    scanf("%d", &n);
    int x[55], y[55];
    P diff[2525];
    rep(i, n) scanf("%d%d", &x[i], &y[i]);

    int ans = 55;
    int idx = 0;
    for(int i = 0; i < n; i++){
        for (int j = i+1; j < n; j++){
            diff[idx].first = x[i] - x[j];
            diff[idx].second = y[i] - y[j];
            diff[idx].i = i;
            diff[idx].j = j;
            idx++;
        }
    }
    sort_up(diff, idx);
    int ch[55];
    rep(i, n) ch[i] = 1;
    rep(i, idx){
        ch[diff[i].j] = 0;
        if(i+1 < idx
           && diff[i].first == diff[i+1].first
           && diff[i].second == diff[i+1].second){
        }else{
            int tmp = 0;
            rep(j, n) tmp += ch[j];
            ans = min(ans, tmp);
            rep(j, n) ch[j] = 1;
        }
    }
    if(n == 1) ans = 1;
    printf("%d\n", ans);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
typedef long long ll;
#define rep(i,n) for(ll i=0; i<(ll)(n); i++)
#define max(l,r) ((l)>(r)?l:r)
#define min(l,r) ((l)<(r)?l:r)
typedef struct{int first, second, i, j;} P;
int upcmpllp(const void *a, const void *b){
    if(((P*)a)->first != ((P*)b)->first)
        return (((P*)a)->first > ((P*)b)->first?1:-1);
    else
        return (((P*)a)->second == ((P*)b)->second ? 0 : (((P*)a)->second > ((P*)b)->second ? 1 : -1));
}
void sort_up(P *a, int n){ qsort(a, n, sizeof(P), upcmpllp); }

int main(){
    int n;
    scanf("%d", &n);
    int x[55], y[55];
    P diff[2525];
    rep(i, n) scanf("%d%d", &x[i], &y[i]);

    int ans = 55;
    int idx = 0;
    for(int i = 0; i < n; i++){
        for (int j = i+1; j < n; j++){
            diff[idx].first = x[i] - x[j];
            diff[idx].second = y[i] - y[j];
            diff[idx].i = i;
            diff[idx].j = j;
            idx++;
        }
    }
    sort_up(diff, idx);
    int ch[55];
    rep(i, n) ch[i] = 1;
    rep(i, idx){
        ch[diff[i].j] = 0;
        if(i+1 < idx
           && diff[i].first == diff[i+1].first
           && diff[i].second == diff[i+1].second){
        }else{
            int tmp = 0;
            rep(i, n) tmp += ch[i];
            ans = min(ans, tmp);
            rep(i, n) ch[i] = 1;
        }
    }
    if(n == 1) ans = 1;
    printf("%d", ans);
}


module.exports=function(r){var e={};function t(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return r[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=r,t.c=e,t.d=function(r,e,n){t.o(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:n})},t.r=function(r){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},t.t=function(r,e){if(1&e&&(r=t(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var n=Object.create(null);if(t.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var o in r)t.d(n,o,function(e){return r[e]}.bind(null,o));return n},t.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return t.d(e,"a",e),e},t.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},t.p="",t(t.s=0)}([function(r,e,t){t(1)(t(2).readFileSync("/dev/stdin","UTF-8").split("\n"))},function(r,e,t){"use strict";function n(r,e){return function(r){if(Array.isArray(r))return r}(r)||function(r,e){var t=[],n=!0,o=!1,u=void 0;try{for(var i,f=r[Symbol.iterator]();!(n=(i=f.next()).done)&&(t.push(i.value),!e||t.length!==e);n=!0);}catch(r){o=!0,u=r}finally{try{n||null==f.return||f.return()}finally{if(o)throw u}}return t}(r,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}r.exports=function(r){for(var e=Number(r[0]),t=[],o=[],u=0;u<e;u++){var i=n(r[u+1].split(" ").map(function(r){return Number(r)}),2),f=i[0],a=i[1];t.push(f),o.push(a)}for(var l=new Map,c=0;c<e;c++)for(var p=0;p<e;p++)if(c!=p){var s=`${t[c]-t[p]}:${o[c]-o[p]}`;l[s]||(l[s]=0),l[s]++}var d=0;for(var v in l)l[v]>d&&(d=l[v]);var y=e-d;console.log(y)}},function(r,e){r.exports=require("fs")}]);


function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
	input = input.split("\n").filter(Boolean);
    const n = +input[0];

    if (n <= 2) {
      console.log(1);
      return;
    }

    const xy = input.slice(1).map(s => s.split(' ').map(n => +n));

    const map = {};
    xy.forEach(a => {
      xy.forEach(b => {
        if (a === b) return; // 自分自身の場合

        const vec = [b[0] - a[0], b[1] - a[1]];
        const m = vec.join('_');
        map[m] = map[m] == null ? 1 : map[m] + 1;
      });
    });

	const res = Object.keys(map).reduce((r, xystr) => {
		const count = map[xystr];
        return count > r[0] ? [count, xystr] : [r[0], r[1]];
    }, [1, '']);

//    const pq = res[1];

    console.log(n - res[0]);
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


log = console.log;
var stdin = require("fs").readFileSync("/dev/stdin", "UTF-8");
var lines = stdin.split("\n");
var N = lines[0].split(" ").map(Number)[0];
var Points = lines
  .slice(1)
  .filter(v => v !== "")
  .map(v => v.split(" ").map(Number));

var diffList = [];

Points.forEach((pointA, i) => {
  var Ax = pointA[0];
  var Ay = pointA[1];
  diffList[i] = [];
  Points.forEach(pointB => {
    var Bx = pointB[0];
    var By = pointB[1];
    if (Bx === Ax && By === Ay) return;
    diffList[i].push([Bx - Ax, By - Ay]);
  });
});

var dList = [];
var countList = {};
diffList.forEach(diff => {
  diff.forEach(d => {
    countList[d.toString()] = countList[d.toString()]
      ? countList[d.toString()] + 1
      : 1;
  });
});

var max = 0
Object.keys(countList).forEach(key=>{
  if(countList[key] > max) max = countList[key]
})
log(N - max)


//↓見なくていいよ！ここから--------------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
var obj;
var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error("\n");
  var start = new Date();
  Main();
  var end = new Date() - start;
  myerr("time : " + (end) + "ms");
  myerr("memory : " + Math.round(process.memoryUsage().heapTotal / 1024) + "KB");
});
function makeClone(obj){return JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  var returnObj = {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(!this.hasNext()){throw "ArrayIndexOutOfBoundsException これ以上ないよ";}else{var returnInput = this.list[this.index];this.index++;return returnInput;}}
  };
  return returnObj;
}
function myout(s){console.log(s);}
function myerr(s){console.error("debug:" + require("util").inspect(s,false,null));}
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す 1:数値へ変換
//2:半角SPで分割 4:半角SPで分割し、数値配列へ
//6:1文字で分割  7:1文字で分割し、数値配列へ
//8:半角SPで結合 9:改行で結合 0:文字なしで結合
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map(Number);case 6:return i.split("");case 7:return i.split("").map(Number);case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}

//↑見なくていいよ！ここまで--------------------------------------------------
function Main(){
  var N = nextInt();
  var list = new Array(N);
  for(var i = 0; i < N; i++){
    var tmp = nextIntArray();
    list[i] = {
    	x : tmp[0],
      	y : tmp[1]
    };
  }
  var output = 99;
  for(var i = 0; i < N - 1; i++){
    for(var j = i + 1; j < N; j++){
      var diffX = list[i].x - list[j].x;
      var diffY = list[i].y - list[j].y;
      var uf = unionFind(N);
      for(var k = 0; k < N; k++){
        for(var l = 0; l < N; l++){
          if(k == l){continue;}
          if(list[k].x - list[l].x == diffX && list[k].y - list[l].y == diffY){
            uf.doUnion(k, l);
          }
        }
      }
      var count = 0;
      for(var k = 0; k < N; k++){
        if(uf.list[k] < 0){
          count++;
        }
      }
      output = Math.min(output, count);
    }
  }
  myout(output);
}
function unionFind(n){
  var uf = {
    //全てのインデックスは「-X(親、絶対値はグループの大きさ)」「自分が属する親(≒根)」のいずれかを持つ。
    //最初はみんなグループの大きさ1の親
    "list" : new Array(n).fill(-1),

    //同じ親を持つか
    "isSame" : function(mae, ato){
      return this.getRootIndex(mae) == this.getRootIndex(ato);
    },
    //自身の親インデックスをたどって根っこに着く
    //親にたどり終えたら子に帰っていくついでに、子たちに「共通の親を持っている」ことを知らせる
    "getRootIndex" : function(index){
      if(this.list[index] < 0){
        return index;
      }else{
        this.list[index] = this.getRootIndex(this.list[index]);
        return this.list[index];
      }
    },
    //異なる親同士のまとまりを一つにする（同じ親ならスルー）
    //小さいグループの親が大きいグループの親の直下に着く
    //グループの大きさも更新する
    "doUnion" : function(mae, ato){
      var maeRoot = this.getRootIndex(mae);
      var atoRoot = this.getRootIndex(ato);
      if(!this.isSame(maeRoot, atoRoot)){
        if(maeRoot >= atoRoot){
          this.list[maeRoot] += this.list[atoRoot];
          this.list[atoRoot] = maeRoot;
        }else{
          this.list[atoRoot] += this.list[maeRoot];
          this.list[maeRoot] = atoRoot;
        }
      }
    },
    //「-X(親、絶対値はグループの大きさ)」
    //なので、インデックスを指定→親を知る→親の持つグループの大きさがわかる。
    //ただしマイナス値なので、掛け算して返す。
    "getSize" : function(index){
      return -this.list[this.getRootIndex(index)];
    }
  }
  return uf;
}


//↓見なくていいよ！ここから--------------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
var obj;
var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error("\n");
  var start = new Date();
  Main();
  var end = new Date() - start;
  myerr("time : " + (end) + "ms");
  myerr("memory : " + Math.round(process.memoryUsage().heapTotal / 1024) + "KB");
});
function makeClone(obj){return JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  var returnObj = {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(!this.hasNext()){throw "ArrayIndexOutOfBoundsException これ以上ないよ";}else{var returnInput = this.list[this.index];this.index++;return returnInput;}}
  };
  return returnObj;
}
function myout(s){console.log(s);}
function myerr(s){console.error("debug:" + require("util").inspect(s,false,null));}
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す 1:数値へ変換
//2:半角SPで分割 4:半角SPで分割し、数値配列へ
//6:1文字で分割  7:1文字で分割し、数値配列へ
//8:半角SPで結合 9:改行で結合 0:文字なしで結合
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map(Number);case 6:return i.split("");case 7:return i.split("").map(Number);case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}

//↑見なくていいよ！ここまで--------------------------------------------------
function Main(){
  var N = nextInt();
  var list = new Array(N);
  for(var i = 0; i < N; i++){
    var tmp = nextIntArray();
    list[i] = {
    	x : tmp[0],
      	y : tmp[1]
    };
  }
  var output = 99;
  for(var i = 0; i < N - 1; i++){
    for(var j = i + 1; j < N; j++){
      var diffX = list[i].x - list[j].x;
      var diffY = list[i].y - list[j].y;
      var uf = unionFind(N);
      for(var k = 0; k < N - 1; k++){
        for(var l = k + 1; l < N; l++){
          if(list[k].x - list[l].x == diffX && list[k].y - list[l].y == diffY){
            uf.doUnion(k, l);
          }
        }
      }
      var count = 0;
      for(var k = 0; k < N; k++){
        if(uf.list[k] < 0){
          count++;
        }
      }
      output = Math.min(output, count);
    }
  }
  myout(output);
}
function unionFind(n){
  var uf = {
    //全てのインデックスは「-X(親、絶対値はグループの大きさ)」「自分が属する親(≒根)」のいずれかを持つ。
    //最初はみんなグループの大きさ1の親
    "list" : new Array(n).fill(-1),

    //同じ親を持つか
    "isSame" : function(mae, ato){
      return this.getRootIndex(mae) == this.getRootIndex(ato);
    },
    //自身の親インデックスをたどって根っこに着く
    //親にたどり終えたら子に帰っていくついでに、子たちに「共通の親を持っている」ことを知らせる
    "getRootIndex" : function(index){
      if(this.list[index] < 0){
        return index;
      }else{
        this.list[index] = this.getRootIndex(this.list[index]);
        return this.list[index];
      }
    },
    //異なる親同士のまとまりを一つにする（同じ親ならスルー）
    //小さいグループの親が大きいグループの親の直下に着く
    //グループの大きさも更新する
    "doUnion" : function(mae, ato){
      var maeRoot = this.getRootIndex(mae);
      var atoRoot = this.getRootIndex(ato);
      if(!this.isSame(maeRoot, atoRoot)){
        if(maeRoot >= atoRoot){
          this.list[maeRoot] += this.list[atoRoot];
          this.list[atoRoot] = maeRoot;
        }else{
          this.list[atoRoot] += this.list[maeRoot];
          this.list[maeRoot] = atoRoot;
        }
      }
    },
    //「-X(親、絶対値はグループの大きさ)」
    //なので、インデックスを指定→親を知る→親の持つグループの大きさがわかる。
    //ただしマイナス値なので、掛け算して返す。
    "getSize" : function(index){
      return -this.list[this.getRootIndex(index)];
    }
  }
  return uf;
}


module.exports=function(r){var e={};function t(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return r[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=r,t.c=e,t.d=function(r,e,n){t.o(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:n})},t.r=function(r){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(r,"__esModule",{value:!0})},t.t=function(r,e){if(1&e&&(r=t(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var n=Object.create(null);if(t.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var o in r)t.d(n,o,function(e){return r[e]}.bind(null,o));return n},t.n=function(r){var e=r&&r.__esModule?function(){return r.default}:function(){return r};return t.d(e,"a",e),e},t.o=function(r,e){return Object.prototype.hasOwnProperty.call(r,e)},t.p="",t(t.s=0)}([function(r,e,t){t(1)(t(2).readFileSync("/dev/stdin","UTF-8").split("\n"))},function(r,e,t){"use strict";function n(r,e){return function(r){if(Array.isArray(r))return r}(r)||function(r,e){var t=[],n=!0,o=!1,u=void 0;try{for(var i,f=r[Symbol.iterator]();!(n=(i=f.next()).done)&&(t.push(i.value),!e||t.length!==e);n=!0);}catch(r){o=!0,u=r}finally{try{n||null==f.return||f.return()}finally{if(o)throw u}}return t}(r,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}r.exports=function(r){for(var e=Number(r[0]),t=[],o=[],u=0;u<e;u++){var i=n(r[u+1].split(" ").map(function(r){return Number(r)}),2),f=i[0],a=i[1];t.push(f),o.push(a)}for(var l=new Map,c=1;c<e;c++){var p=`${t[c]-t[c-1]}:${o[c]-o[c-1]}`;l[p]||(l[p]=0),l[p]++}var s=0;for(var d in l)l[d]>s&&(s=l[d]);var v=e-s;console.log(v)}},function(r,e){r.exports=require("fs")}]);


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc, wr = bufio.NewScanner(os.Stdin), bufio.NewWriter(os.Stdout)

func scanString() string { sc.Scan(); return sc.Text() }
func scanInt() int { a,_ := strconv.Atoi(scanString()); return a }
func scanInt64() int64 { a,_ := strconv.ParseInt(scanString(),10,64); return a }
func scanFloat64() float64 { a,_ := strconv.ParseFloat(scanString(),64); return a }

func scanInts(n int) []int {
	res := make([]int, n); for i := 0; i < n; i++ { res[i] = scanInt() }; return res
}

func abs(a int) int { if a<0 { return -a }; return a }
func min(a,b int) int { if a<b { return a }; return b }
func max(a,b int) int { if a>b { return a }; return b }

//•*¨*•.¸¸♪Main•*¨*•.¸¸♪(　-ω-)ノ　(　・ω・)

func main() {
	defer wr.Flush()
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 10000), 1001001)

	n := scanInt()

	x := make([]int, n)
	y := make([]int, n)
	for i := 0; i < n; i++ {
		x[i] = scanInt()
		y[i] = scanInt()
	}

	cnt := make(map[point]int)
	ma := 0

	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			if i == j {
				continue
			}

			p := x[i] - x[j]
			q := y[i] - y[j]
			cnt[point{p,q}]++
			ma = max(ma, cnt[point{p,q}])
		}
	}

	fmt.Fprintln(wr, n-ma)
	// fmt.Fprintln(wr, cnt)

}

type point struct {
	x,y int
}


package main

import "fmt"

type point struct {
	x, y int
}

func main() {
	var n int
	fmt.Scan(&n)
	points := make([]point, n)
	for i := range points {
		fmt.Scan(&points[i].x, &points[i].y)
	}
	// 1 <= N <= 50なので、全部の2点間のベクトルを計算できる
	if n <= 1 {
		fmt.Println(1) // 点が2個以下ならコスト1
		return
	}
	vectors := make(map[point]int, 0)
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			if i == j {
				continue
			}
			var v point
			v.x = points[i].x - points[j].x
			v.y = points[i].y - points[j].y
			vectors[v]++
		}
	}
	// fmt.Println("points", points)
	// fmt.Println("vectors", vectors)
	maxv := 0
	for _, v := range vectors {
		maxv = max(maxv, v)
	}
	fmt.Println(n - maxv)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}


package main

import "fmt"

func main() {
	var n int
	fmt.Scan(&n)
	ps := make([]Pair, n)
	var x, y int
	for i := 0; i < n; i++ {
		fmt.Scan(&x, &y)
		ps[i] = Pair{x, y}
	}

	mx := 0
	for i := 1; i < n; i++ {
		p := ps[0].x - ps[i].x
		q := ps[0].y - ps[i].y
		cnt := 0
		for j := 0; j < n; j++ {
			a := ps[j]
			for k := 0; k < n; k++ {
				b := ps[k]
				if j == k {
					continue
				}
				if a.x-b.x == p && a.y-b.y == q {
					cnt++
				}
			}
		}
		if mx < cnt {
			mx = cnt
		}
	}

	fmt.Println(n - mx)
}

// Pair .
type Pair struct {
	x, y int
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var (
	finv, inv, fac [MAX]int
)

func COM(n, k int) int {
	if n < k {
		return 0
	}
	if n < 0 || k < 0 {
		return 0
	}
	return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD
}

func init() {
	fac[0] = 1
	fac[1] = 1
	finv[0] = 1
	finv[1] = 1
	inv[1] = 1
	for i := 2; i < MAX; i++ {
		fac[i] = fac[i-1] * i % MOD
		inv[i] = MOD - inv[MOD%i]*(MOD/i)%MOD
		finv[i] = finv[i-1] * inv[i] % MOD
	}
	//sc.Split(bufio.ScanLines)
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, 500100)
}

const (
	MOD = 1000000007
	MAX = 510000
)

func ModAdd(a, b int64) int64 {
	return (a + b) % MOD
}

func ModMul(a, b int64) int64 {
	return a * b % MOD
}

func ModSub(a, b int64) int64 {
	r := (a%MOD - b%MOD) % MOD
	if r < 0 {
		r += MOD
	}
	return r
}

func ModDiv(a, b int64) int64 {
	return a % MOD * ModInv(b) % MOD
}

func ModPow(a, n int64) int64 {
	var r int64 = 1
	for n > 0 {
		if n&1 == 1 {
			r = r * a % MOD
		}
		a = a * a % MOD
		n >>= 1
	}
	return r
}

func ModInv(a int64) int64 {
	var b, u, v int64 = MOD, 1, 0
	for b > 0 {
		t := a / b
		a -= t * b
		a, b = b, a
		u -= t * v
		u, v = v, u
	}
	u %= MOD
	if u < 0 {
		u += MOD
	}
	return u
}

type Q struct {
	value int
	index int
	A, B  int
}

type QS []*Q

func (p QS) Len() int           { return len(p) }
func (p QS) Less(i, j int) bool { return p[i].value > p[j].value }
func (pq QS) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *QS) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Q)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *QS) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil  // avoid memory leak
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func GCD(a, b int64) int64 {
	if b == 0 {
		return a
	}
	return GCD(b, a%b)
}

func LCM(a, b int64) int64 {
	return a * b / GCD(a, b)
}

type UnionFind struct {
	par  []int
	size []int
}

func NewUnionFind(size int) *UnionFind {
	return new(UnionFind).init(size)
}

func (uf *UnionFind) init(size int) *UnionFind {
	uf.par = make([]int, size)
	uf.size = make([]int, size)

	for i := 0; i < size; i++ {
		uf.par[i] = i
		uf.size[i] = 1
	}
	return uf
}

func (uf *UnionFind) Unite(p int, q int) {
	rp := uf.Root(p)
	rq := uf.Root(q)
	if rp == rq {
		return
	}
	if uf.size[rp] < uf.size[rq] {
		uf.par[rp] = uf.par[rq]
		uf.size[rq] += uf.size[rp]
	} else {
		uf.par[rq] = uf.par[rp]
		uf.size[rp] += uf.size[rq]
	}
}

func (uf *UnionFind) Root(p int) int {
	for uf.par[p] == p {
		return p
	}
	uf.par[p] = uf.Root(uf.par[p])
	return uf.par[p]
}

func (uf *UnionFind) Size(p int) int {
	return uf.size[uf.Root(p)]
}

func (uf *UnionFind) Same(p int, q int) bool {
	return uf.Root(p) == uf.Root(q)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	n, _ := strconv.Atoi(getStr())
	return n
}

func getStr() string {
	sc.Scan()
	return sc.Text()
}

func factor(result map[int]int, num, pnum int) map[int]int {
	if pnum*pnum > num {
		if num != 1 {
			result[num] += 1
		}
		return result
	}

	if num%pnum == 0 {
		num /= pnum
		result[pnum]++
	} else {
		pnum++
	}
	return factor(result, num, pnum)
}

type P struct {
	x, y int
}

func main() {
	N := getInt()
	PS := make([]*P, N)
	for i := 0; i < N; i++ {
		PS[i] = &P{
			x: getInt(), y: getInt(),
		}
	}
	max := 0
	for i := 0; i < N; i++ {
		for j := 0; j < N; j++ {
			p := PS[i].x - PS[j].x
			q := PS[i].y - PS[j].y
			if p == 0 && q == 0 {
				continue
			}
			dup := 0
			for k := 1; k < N; k++ {
				a := PS[k].x
				b := PS[k].y
				if PS[k-1].x-a == p && PS[k-1].y-b == q {
					dup++
				}
			}
			//fmt.Println(p, q, dup)
			if dup > max {
				max = dup
			}
		}
	}
	//fmt.Println(max)
	fmt.Println(N - max)
}

type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
	// Push and Pop use pointer receivers because they modify the slice's length,
	// not just its contents.
	*h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var (
	finv, inv, fac [MAX]int
)

func COM(n, k int) int {
	if n < k {
		return 0
	}
	if n < 0 || k < 0 {
		return 0
	}
	return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD
}

func init() {
	fac[0] = 1
	fac[1] = 1
	finv[0] = 1
	finv[1] = 1
	inv[1] = 1
	for i := 2; i < MAX; i++ {
		fac[i] = fac[i-1] * i % MOD
		inv[i] = MOD - inv[MOD%i]*(MOD/i)%MOD
		finv[i] = finv[i-1] * inv[i] % MOD
	}
	//sc.Split(bufio.ScanLines)
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, 500100)
}

const (
	MOD = 1000000007
	MAX = 510000
)

func ModAdd(a, b int64) int64 {
	return (a + b) % MOD
}

func ModMul(a, b int64) int64 {
	return a * b % MOD
}

func ModSub(a, b int64) int64 {
	r := (a%MOD - b%MOD) % MOD
	if r < 0 {
		r += MOD
	}
	return r
}

func ModDiv(a, b int64) int64 {
	return a % MOD * ModInv(b) % MOD
}

func ModPow(a, n int64) int64 {
	var r int64 = 1
	for n > 0 {
		if n&1 == 1 {
			r = r * a % MOD
		}
		a = a * a % MOD
		n >>= 1
	}
	return r
}

func ModInv(a int64) int64 {
	var b, u, v int64 = MOD, 1, 0
	for b > 0 {
		t := a / b
		a -= t * b
		a, b = b, a
		u -= t * v
		u, v = v, u
	}
	u %= MOD
	if u < 0 {
		u += MOD
	}
	return u
}

type Q struct {
	value int
	index int
	A, B  int
}

type QS []*Q

func (p QS) Len() int           { return len(p) }
func (p QS) Less(i, j int) bool { return p[i].value > p[j].value }
func (pq QS) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *QS) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Q)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *QS) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil  // avoid memory leak
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func GCD(a, b int64) int64 {
	if b == 0 {
		return a
	}
	return GCD(b, a%b)
}

func LCM(a, b int64) int64 {
	return a * b / GCD(a, b)
}

type UnionFind struct {
	par  []int
	size []int
}

func NewUnionFind(size int) *UnionFind {
	return new(UnionFind).init(size)
}

func (uf *UnionFind) init(size int) *UnionFind {
	uf.par = make([]int, size)
	uf.size = make([]int, size)

	for i := 0; i < size; i++ {
		uf.par[i] = i
		uf.size[i] = 1
	}
	return uf
}

func (uf *UnionFind) Unite(p int, q int) {
	rp := uf.Root(p)
	rq := uf.Root(q)
	if rp == rq {
		return
	}
	if uf.size[rp] < uf.size[rq] {
		uf.par[rp] = uf.par[rq]
		uf.size[rq] += uf.size[rp]
	} else {
		uf.par[rq] = uf.par[rp]
		uf.size[rp] += uf.size[rq]
	}
}

func (uf *UnionFind) Root(p int) int {
	for uf.par[p] == p {
		return p
	}
	uf.par[p] = uf.Root(uf.par[p])
	return uf.par[p]
}

func (uf *UnionFind) Size(p int) int {
	return uf.size[uf.Root(p)]
}

func (uf *UnionFind) Same(p int, q int) bool {
	return uf.Root(p) == uf.Root(q)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	n, _ := strconv.Atoi(getStr())
	return n
}

func getStr() string {
	sc.Scan()
	return sc.Text()
}

func factor(result map[int]int, num, pnum int) map[int]int {
	if pnum*pnum > num {
		if num != 1 {
			result[num] += 1
		}
		return result
	}

	if num%pnum == 0 {
		num /= pnum
		result[pnum]++
	} else {
		pnum++
	}
	return factor(result, num, pnum)
}

type P struct {
	x, y int
}

func main() {
	N := getInt()
	PS := make([]*P, N)
	for i := 0; i < N; i++ {
		PS[i] = &P{
			x: getInt(), y: getInt(),
		}
	}
	max := 0
	for i := 0; i < N; i++ {
		for j := i + 1; j < N; j++ {
			p := PS[i].x - PS[j].x
			q := PS[i].y - PS[j].y
			dup := 0
			for k := 1; k < N; k++ {
				a := PS[k].x
				b := PS[k].y
				if PS[k-1].x-a == p && PS[k-1].y-b == q {
					dup++
				}
			}
			//fmt.Println(p, q, dup)
			if dup > max {
				max = dup
			}
		}
	}
	//fmt.Println(max)
	fmt.Println(N - max)
}

type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
	// Push and Pop use pointer receivers because they modify the slice's length,
	// not just its contents.
	*h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	finv, inv, fac [MAX]int
)

func COM(n, k int) int {
	if n < k {
		return 0
	}
	if n < 0 || k < 0 {
		return 0
	}
	return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD
}

func init() {
	fac[0] = 1
	fac[1] = 1
	finv[0] = 1
	finv[1] = 1
	inv[1] = 1
	for i := 2; i < MAX; i++ {
		fac[i] = fac[i-1] * i % MOD
		inv[i] = MOD - inv[MOD%i]*(MOD/i)%MOD
		finv[i] = finv[i-1] * inv[i] % MOD
	}
	//sc.Split(bufio.ScanLines)
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, 500100)
}

const (
	MOD = 1000000007
	MAX = 510000
)

func ModAdd(a, b int64) int64 {
	return (a + b) % MOD
}

func ModMul(a, b int64) int64 {
	return a * b % MOD
}

func ModSub(a, b int64) int64 {
	r := (a%MOD - b%MOD) % MOD
	if r < 0 {
		r += MOD
	}
	return r
}

func ModDiv(a, b int64) int64 {
	return a % MOD * ModInv(b) % MOD
}

func ModPow(a, n int64) int64 {
	var r int64 = 1
	for n > 0 {
		if n&1 == 1 {
			r = r * a % MOD
		}
		a = a * a % MOD
		n >>= 1
	}
	return r
}

func ModInv(a int64) int64 {
	var b, u, v int64 = MOD, 1, 0
	for b > 0 {
		t := a / b
		a -= t * b
		a, b = b, a
		u -= t * v
		u, v = v, u
	}
	u %= MOD
	if u < 0 {
		u += MOD
	}
	return u
}

type Q struct {
	value int
	index int
	A, B  int
}

type QS []*Q

func (p QS) Len() int           { return len(p) }
func (p QS) Less(i, j int) bool { return p[i].value > p[j].value }
func (pq QS) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *QS) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Q)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *QS) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil  // avoid memory leak
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func GCD(a, b int64) int64 {
	if b == 0 {
		return a
	}
	return GCD(b, a%b)
}

func LCM(a, b int64) int64 {
	return a * b / GCD(a, b)
}

type UnionFind struct {
	par  []int
	size []int
}

func NewUnionFind(size int) *UnionFind {
	return new(UnionFind).init(size)
}

func (uf *UnionFind) init(size int) *UnionFind {
	uf.par = make([]int, size)
	uf.size = make([]int, size)

	for i := 0; i < size; i++ {
		uf.par[i] = i
		uf.size[i] = 1
	}
	return uf
}

func (uf *UnionFind) Unite(p int, q int) {
	rp := uf.Root(p)
	rq := uf.Root(q)
	if rp == rq {
		return
	}
	if uf.size[rp] < uf.size[rq] {
		uf.par[rp] = uf.par[rq]
		uf.size[rq] += uf.size[rp]
	} else {
		uf.par[rq] = uf.par[rp]
		uf.size[rp] += uf.size[rq]
	}
}

func (uf *UnionFind) Root(p int) int {
	for uf.par[p] == p {
		return p
	}
	uf.par[p] = uf.Root(uf.par[p])
	return uf.par[p]
}

func (uf *UnionFind) Size(p int) int {
	return uf.size[uf.Root(p)]
}

func (uf *UnionFind) Same(p int, q int) bool {
	return uf.Root(p) == uf.Root(q)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	n, _ := strconv.Atoi(getStr())
	return n
}

func getStr() string {
	sc.Scan()
	return sc.Text()
}

func factor(result map[int]int, num, pnum int) map[int]int {
	if pnum*pnum > num {
		if num != 1 {
			result[num] += 1
		}
		return result
	}

	if num%pnum == 0 {
		num /= pnum
		result[pnum]++
	} else {
		pnum++
	}
	return factor(result, num, pnum)
}

type P struct {
	x, y int
}
type PP []*P

func (h PP) Len() int           { return len(h) }
func (h PP) Less(i, j int) bool { return h[i].x < h[j].x }
func (h PP) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func main() {
	N := getInt()
	PS := make(PP, N)
	for i := 0; i < N; i++ {
		PS[i] = &P{
			x: getInt(), y: getInt(),
		}
	}
	sort.Sort(PS)
	max := 0
	for i := 0; i < N; i++ {
		for j := i + 1; j < N; j++ {
			p := PS[i].x - PS[j].x
			q := PS[i].y - PS[j].y
			dup := 0
			for k := 1; k < N; k++ {
				a := PS[k].x
				b := PS[k].y
				if PS[k-1].x-a == p && PS[k-1].y-b == q {
					dup++
				}
			}
			//fmt.Println(p, q, dup)
			if dup > max {
				max = dup
			}
		}
	}
	//fmt.Println(max)
	fmt.Println(N - max)
}

type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
	// Push and Pop use pointer receivers because they modify the slice's length,
	// not just its contents.
	*h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}


n = gets.to_i
xys = []
xys << [0, 0]
n.times do
  xys << gets.split.map(&:to_i)
end
xys.sort_by! { |x| x }

h = Hash.new(0)
(0..n-1).each do |i|
  x1, y1 = xys[i]
  ((i+1)..n).each do |j|
    x2, y2 = xys[j]
    h["#{x2-x1} #{y2-y1}"] += 1
  end
end
h[xys[1].join(" ")] -= 1

ans = n - h.max_by { |k,v| v }[1]
if h.size == 1
  ans += 1
end
if n == 1
  puts 1
else
  puts ans
end


n = gets.to_i
a = []
n.times do |i|
  x,y = gets.split.map &:to_i
  a << [x,y]
end

dist = []
(0..n-1).to_a.combination(2) do |i,j|
  x = a[i][0]-a[j][0]
  y = a[i][1]-a[j][1]
  if y < 0 || (y == 0 && x < 0)
    y = -y
    x = -x
  end
  dist << [x,y]
end

cnt = dist.group_by(&:itself)
  .values
  .map(&:size)
  .max

cnt ||= 0
puts n - cnt


n = gets.chomp.to_i
xy = []
x = []
y = []

if n == 1
    puts "1"
else

    for i in 1..n do
        input = gets.chomp.split(" ").map(&:to_i)
        xy.push(input)
    end

    xy.sort! {|a,b| (a[0] <=> b[0]).nonzero? || (a[1] <=> b[1])}
    dif = []
    count_max = 1
    for i in 1..n-1 do
        for j in i+1..n do
            x0 = xy[j-1][0] - xy[i-1][0]
            y0 = xy[j-1][1] - xy[i-1][1]
            dif.push([x0,y0])
        end
    end
    dif.sort! {|a,b| (a[0] <=> b[0]).nonzero? || (a[1] <=> b[1])}

    count = 1
    tar = dif[0]
    size = dif.length
    for i in 1..(size -1)
        if dif[i] == tar
            count += 1
        else
            if count_max < count
                count_max = count
            end
            count = 1
            tar = dif[i]
        end
    end
    p n - count_max
end


N=gets.to_i
if N == 1
    puts 0
    exit
end
xys=[]
diffs={}
N.times do
    x,y=gets.chomp.split(" ").map(&:to_i)
    xys.each do |w,t|
        if x>w || x==w && y>t
            diffs["#{x-w}_#{y-t}"] ||= 0
            diffs["#{x-w}_#{y-t}"] += 1
        else
            diffs["#{w-x}_#{t-y}"] ||= 0
            diffs["#{w-x}_#{t-y}"] += 1
        end
    end
    xys.push([x,y])
end
n=diffs.values.sort[-1]
puts N-n


N=gets.to_i
xys=[]
diffs={}
N.times do
    x,y=gets.chomp.split(" ").map(&:to_i)
    xys.each do |w,t|
        if x>w || x==w && y>t
            diffs["#{x-w}_#{y-t}"] ||= 0
            diffs["#{x-w}_#{y-t}"] += 1
        else
            diffs["#{w-x}_#{t-y}"] ||= 0
            diffs["#{w-x}_#{t-y}"] += 1
        end
    end
    xys.push([x,y])
end
n=diffs.values.sort[-1]
puts N-n


require 'set'; require 'prime'; require 'pp'
INF=Float::INFINITY; MOD=10**9+7
n = gets.chomp.to_i
x = []
y = []
n.times do
  xx, yy = gets.chomp.split.map(&:to_i)
  x.push xx
  y.push yy
end

if n == 1
  puts 0
  exit
end

h = Hash.new(0)
n.times do |i|
  n.times do |j|
    next if i == j
    len = [x[i] - x[j], y[i] - y[j]]
    h[len] += 1
  end
end

puts n - h.values.max


pub fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

pub fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

pub fn read_vec2<T: std::str::FromStr>(n: usize) -> Vec<Vec<T>> {
    (0..n).map(|_| read_vec()).collect()
}

pub fn read_col<T: std::str::FromStr>(n: usize) -> Vec<T> {
    (0..n).map(|_| read()).collect()
}

fn main() {
    let n: usize = read();
    let xyv: Vec<Vec<i64>> = read_vec2(n);
    if n == 1 {
        println!("1");
        return;
    }
    let mut v: Vec<(i64, i64)> = vec![];
    for i in 0..n {
        for j in i + 1..n {
            let x = xyv[i][0] - xyv[j][0];
            let y = xyv[i][1] - xyv[j][1];
            if x > 0 || (x == 0 && y > 0) {
                v.push((x, y));
            } else {
                v.push((-x, -y));
            }
        }
    }
    v.sort_by(|p, q| {
        if p.0 != q.0 {
            p.0.partial_cmp(&q.0).unwrap()
        } else {
            p.1.partial_cmp(&q.1).unwrap()
        }
    });
    let mut max: usize = 1;
    let mut cnt: usize = 1;
    for i in 1..v.len() {
        if v[i] == v[i - 1] {
            cnt += 1;
        } else {
            if cnt > max {
                max = cnt;
            }
            cnt = 1;
        }
    }
    if cnt > max {
        max = cnt;
    }
    println!("{}", n - max);
}