Covering the stains
Difficulty: Hard

There is a huge blanket on your bed but unfortunately it has **N** stains. You cover them using 
a single, rectangular silk cloth. The silk is expensive, which is why the rectangular piece needs to have the least area as possible. You love this blanket and decide to minimize the area covering the  stains. You buy some cleaning liquid to remove the stains but sadly it isn't enough to clean all of them. You can just remove exactly **K** stains. The rest of the stains need to be covered using a single, rectangular fragment of silk cloth.

Let **X** denote the area of the smallest possible silk cloth that may cover all the stains originally. You need to find the number of different ways in which you may remove **K** stains so that the remaining **N-K** stains can be covered with silk of **area strictly less than X** (We are looking for any configuration that will reduce the cost).

Assume that each stain is a point and that the rectangle is aligned parallel to the axes.  


Input Format:
The first line contains two integers **N** (1<=N<=1000) and **K** (0<=K<=N). 
Next follow **N** lines, one for each stain. Each line contains two integers in the form 'X Y', (0<=X,Y<100000), the coordinates of each stain into the blanket. Each pair of coordinates is unique.


Output Format:
Output a single integer. The remainder of the division by 1000000007 of the answer.


Sample Input:
    5 2
    0 1
    3 3
    2 0
    0 3
    2 3


Sample Output:
	8


Python 3 starter code:
#
# Complete the 'coveringStains' function below.
#
# The function is expected to return an INTEGER.
# The function accepts following parameters:
#  1. INTEGER k
#  2. 2D_INTEGER_ARRAY coordinates
#

def coveringStains(k, coordinates):
    # Write your code here




Reference solution (Java):
###Java  
```java  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;



public class Main {
    
static int MOD = (int) 1e9 + 7;
    
public static void main(String[] args) throws IOException {
    int N, K, mask;
    int stains[][];
    int arr[];
    int DP[][][];
    int vals[];
    
    InputStreamReader sr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(sr);
    
    String cad[] = br.readLine().split(" ");
    N = Integer.parseInt(cad[0]);
    K = Integer.parseInt(cad[1]);
    
    K = N - K;
            
            if(K == 0) {
                System.out.print(1);
                System.exit(0);
            }
    
    stains = new int[N+2][2];
    arr = new int[N+2];
    vals = new int[]{0,100000,0,100000};
    
    for(int i = 1;i<=N;i++) {
        cad = br.readLine().split(" ");
        stains[i][0] = Integer.parseInt(cad[0]);
        stains[i][1] = Integer.parseInt(cad[1]);
        
        vals[0] = Math.max(vals[0], stains[i][0]);
        vals[1] = Math.min(vals[1], stains[i][0]);
        vals[2] = Math.max(vals[2], stains[i][1]);
        vals[3] = Math.min(vals[3], stains[i][1]);
    }
            
    
    for(int i = 1;i<=N;i++) {
        mask = 0;
        for(int j = 0;j<4;j++) {
            if(vals[j] == stains[i][j/2])
                mask |= (1<<j);
        }
        arr[i] = mask;            
    }
    
    DP = new int[K+2][N+2][18];
    
    for(int j = 1;j<=N;j++) {
        DP[1][j][ arr[j] ] = 1;
        for(int k = 0;k<16;k++){
            DP[1][j][k] += DP[1][j-1][k]; 
        }
    }    
    
    for(int i=1;i<K;i++) {
        for(int j = i;j<N;j++) {
            for(int k = 0;k<16;k++){
                DP[i+1][j+1][k | arr[j+1]] = (DP[i+1][j+1][k | arr[j+1]] + DP[i][j][k] ) % MOD; 
                DP[i+1][j+1][k] = (DP[i+1][j+1][k] + DP[i+1][j][k] ) % MOD;
            }
        }
    }
    
    int sol = 0;
    for(int k = 0;k<15;k++)
        sol = (sol + DP[K][N][k]) % MOD;
    
    System.out.println(sol);        
}
}
```