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 PyPy3 (7.3.0) (judge verdict: Wrong Answer)

import itertools
import sys
sys.setrecursionlimit(10**9)

def mi(): return map(int,input().split())
def ii(): return int(input())
def isp(): return input().split()
def deb(text): print("-------\n{}\n-------".format(text))

INF=10**20
def main():
    N,K=mi()
    G = []
    maxX,maxY,minX,minY = -INF,-INF,INF,INF
    for i in range(N):
        x,y = mi()
        G.append((x,y))
        maxX=max(maxX,x)
        maxY=max(maxY,y)
        minX=max(minX,x)
        minY=max(minY,y)


    def c(downx,upx,downy,upy):
        return count(downx,upx,downy,upy) >= K
       

    def count(downx,upx,downy,upy):
        _count = 0
        for i in range(N):
            x,y = G[i]
            if downx<=x<=upx and downy<=y<=upy:
                _count += 1
        
        return _count

    

    ans = INF
    for v in itertools.combinations(G, 2):
        u = list(v)
        u.sort()
        (x1,y1),(x2,y2) = u

        new_ans = 0
        if y1 < y2:
            #p1を角, p2のx採用: x1<=x<=x2, y1<=y<= newy, y2 <= newy 
            l = y2
            r = maxY
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,x2,y1,mid):
                    r = mid
                else:
                    l = mid
            
            newy = r
            if count(x1,x2,y1,newy) >= K:
                new_ans = min(ans,abs(x1-x2) * abs(y1-newy))
            
            # p2のy採用:  x1<=x<=newx, y1<=y<=y2 
            l = x2
            r = maxX
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,mid,y1,y2):
                    r = mid
                else:
                    l = mid
            
            newx = r
            if count(x1,newx,y1,y2) >= K:
                new_ans = min(ans,abs(x1-newx) * abs(y1-y2))

            #p2を角, p1のx採用
            l = minY
            r = y1
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,x2,mid,y2):
                    r = mid
                else:
                    l = mid
            
            newy = r
            if count(x1,x2,newy,y2) >= K:
                new_ans = min(ans,abs(x1-x2) * abs(y2-newy))
            
            # p2を角, y採用
            l = minX
            r = x2
            while r-l > 1:
                mid = (l+r)//2
                if c(mid,x2,y2,y1):
                    r = mid
                else:
                    l = mid
            
            newx = r
            if count(newx,x2,y2,y1) >= K:
                new_ans = min(ans,abs(x2-newx) * abs(y1-y2))

        if y1 >= y2:
            #p2のx採用: x1<=x<=x2, y2<=y<= newy, y2 <= newy 
            l = y1
            r = maxY
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,x2,mid,y2):
                    r = mid
                else:
                    l = mid
            
            newy = r
            if count(x1,x2,newy,y2) >= K:
                new_ans = min(ans,abs(x1-x2) * abs(y2-newy))
            
            # p2のy採用:  x1<=x<=newx, y2<=y<=y1
            l = x2
            r = maxX
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,mid,y2,y1):
                    r = mid
                else:
                    l = mid
            
            newx = r
            if count(x1,newx,y2,y1) >= K:
                new_ans = min(ans,abs(x1-newx) * abs(y1-y2))


            #p2を角, p1のx採用
            l = y1
            r = maxY
            while r-l > 1:
                mid = (l+r)//2
                if c(x1,x2,y2,mid):
                    r = mid
                else:
                    l = mid
            
            newy = r
            if count(x1,x2,y2,newy) >= K:
                new_ans = min(ans,abs(x1-x2) * abs(y2-newy))
            
            # p1のy採用
            l = minY
            r = x1
            while r-l > 1:
                mid = (l+r)//2
                if c(mid,x2,y1,y2):
                    r = mid
                else:
                    l = mid
            
            newx = r
            if count(newx,x2,y1,y2) >= K:
                new_ans = min(ans,abs(x2-newx) * abs(y1-y2))


        if new_ans > 0:
            ans = min(ans,new_ans)

        # print(ans)

        downy = min(y1,y2)
        upy = max(y1,y2)

        _count = 0
        for i in range(N):
            x,y = G[i]

            if x1<=x<=x2 and downy<=y<=upy:
                _count += 1
        
        if not _count >= K: continue
        ans = min(ans,abs(x1-x2) * abs(y1-y2))

    
    print(ans)

            



if __name__ == "__main__":
    main()