Problem:
Score : 400 points

Problem Statement

We have N points in a two-dimensional plane.

The coordinates of the i-th point (1 \leq i \leq N) are (x_i,y_i).

Let us consider a rectangle whose sides are parallel to the coordinate axes that contains K or more of the N points in its interior.

Here, points on the sides of the rectangle are considered to be in the interior.

Find the minimum possible area of such a rectangle.

Constraints

2 \leq K \leq N \leq 50

-10^9 \leq x_i,y_i \leq 10^9 (1 \leq i \leq N)

x_i≠x_j (1 \leq i<j \leq N)

y_i≠y_j (1 \leq i<j \leq N)

All input values are integers. (Added at 21:50 JST)

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1
:
x_{N} y_{N}

Output

Print the minimum possible area of a rectangle that satisfies the condition.

Sample Input 1

4 4
1 4
3 3
6 2
8 1

Sample Output 1

21

One rectangle that satisfies the condition with the minimum possible area has the following vertices: (1,1), (8,1), (1,4) and (8,4).

Its area is (8-1) × (4-1) = 21.

Sample Input 2

4 2
0 0
1 1
2 2
3 3

Sample Output 2

1

Sample Input 3

4 3
-1000000000 -1000000000
1000000000 1000000000
-999999999 999999999
999999999 -999999999

Sample Output 3

3999999996000000001

Watch out for integer overflows.

Solution in Java (OpenJDK 11.0.6) (judge verdict: Runtime Error)

import java.util.*;
import java.util.stream.Collectors;
import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main {
	public static void main(String[] args) throws IOException {
		InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
		BufferedReader in = new BufferedReader(reader);
		Main ins = new Main(in);
		ins.calc();
		ins.showResult();
	}

	int N, K;
	Tuple[] p;
	long result = Long.MAX_VALUE / 2;

	static class Tuple {
		long x, y;

		Tuple(String line) {
			String[] tokens = line.split(" ");
			x = Long.parseLong(tokens[0]);
			y = Long.parseLong(tokens[1]);
		}
	}

	Main(BufferedReader in) throws IOException {
		String[] tokens = in.readLine().split(" ");
		N = Integer.parseInt(tokens[0]);
		K = Integer.parseInt(tokens[1]);
		p = new Tuple[N];
		for (int i = 0; i < N; ++i) {
			p[i] = new Tuple(in.readLine());
		}
		Arrays.parallelSort(p, new Comparator<Tuple>() {
			@Override
			public int compare(Tuple o1, Tuple o2) {
				int result = Long.compare(o1.x, o2.y);
				if (result != 0) {
					return result;
				} else {
					return Long.compare(o1.y, o2.y);
				}
			}
		});
	}

	int count(Tuple p1, Tuple p2, Tuple p3, Tuple p4) {
		Tuple[] array = new Tuple[3];
		array[0] = p2;
		array[1] = p3;
		array[2] = p4;
		long minX = p1.x;
		long minY = p1.y;
		long maxX = p1.x;
		long maxY = p1.y;
		for (int i = 0; i < 3; ++i) {
			minX = Math.min(minX, array[i].x);
			minY = Math.min(minY, array[i].y);
			maxX = Math.max(maxX, array[i].x);
			maxY = Math.max(maxY, array[i].y);
		}
		int c = 0;
		for (int i = 0; i < N; ++i) {
			Tuple point = p[i];
			if (point.x >= minX && point.x <= maxX) {
				if (point.y >= minY && point.y <= maxY) {
					++c;
				}
			}
		}
		return c;
	}

	void calc() {
		for (int i = 0; i < N; ++i) {
			Tuple p1 = p[i];
			for (int j = i; j < N; ++j) {
				Tuple p2 = p[j];
				for (int k = j; k < N; ++k) {
					Tuple p3 = p[k];
					for (int l = k; l < N; ++l) {
						Tuple p4 = p[l];
						int c = count(p1, p2, p3, p4);
						if (c >= K) {
							Tuple[] array = new Tuple[3];
							array[0] = p2;
							array[1] = p3;
							array[2] = p4;
							long minX = p1.x;
							long minY = p1.y;
							long maxX = p1.x;
							long maxY = p1.y;
							for (int m = 0; m < 3; ++m) {
								minX = Math.min(minX, array[m].x);
								minY = Math.min(minY, array[m].y);
								maxX = Math.max(maxX, array[m].x);
								maxY = Math.max(maxY, array[m].y);
							}
							long val = (maxX - minX) * (maxY - minY);
							result = Math.min(result, val);
						}
					}
				}
			}
		}
	}

	void showResult() {
		System.out.println(result);
	}
}