#include <iostream>
#include <fstream>
#include <algorithm>
#define INF 2000000000
#define lim 1000000
#define Next ++position == lim?f.read(buffer, lim), position = 0:0
#define NMax 310
#define KMax 310
using namespace std;
/**de impartit aria la 2 !!*/
int sol = INF;
int stanga[NMax], dreapta[NMax];
int nrunder[NMax][NMax];
int n, K;
ifstream f ("popandai.in");
int position;
char buffer[lim];
struct punct
{
int x, y;
punct()
{
x = y = 0;
}
punct (const int _x, const int _y)
{
x = _x;
y = _y;
}
bool operator < (const punct &other) const
{
if (x == other.x)
return y > other.y;
return x < other.x;
}
};
punct a[NMax];
inline void Read(int &x)
{
for (; buffer[position] < '0' || buffer[position] > '9'; Next);
for (x = 0; '0' <= buffer[position] && buffer[position] <= '9'; x = x*10 + buffer[position] - '0', Next);
}
void Read()
{
Read(n), Read(K);
int x, y, i;
for (i=1; i<=n; ++i)
{
Read(x), Read(y);
a[i] = punct(x, y);
}
}
inline int Determinant(const punct A, const punct B, const punct C)
{
///return a[i].y * a[k].x + a[j].x * a[k].y + a[i].x * a[j].y - a[i].y * a[j].x - a[j].y * a[k].x - a[i].x * a[k].y;
return A.y * C.x + B.x * C.y + A.x * B.y - A.y * B.x - B.y * C.x - A.x * C.y;
}
inline int NrPuncte(const int i, const int j, const int k)
{
/// i < j deci asta inseamna ca a[i].x < a[j].x; daca a[i].x == a[j].x atunci a[i].y > a[j].y
/// tin punctele in ordine dupa x si ma uit doar la pozitia punctului din mijloc, daca e deasupra
/// sau sub dreapta data de st si dr si in functie de asta calculez cu formulele de mai jos.
int st, mij, dr;
if (k < i)
st = k, mij = i, dr = j;
else
{
st = i;
if ( k < j )
mij = k, dr = j;
else
mij = j, dr = k;
}
if (Determinant(a[st], a[dr], a[mij]) > 0)
return nrunder[st][mij] + nrunder[mij][dr] - nrunder[st][dr];
return nrunder[st][dr] - nrunder[st][mij] - nrunder[mij][dr] - 1;
}
inline int Aria(const punct A, const punct B, const punct C)
{
return abs(A.y * C.x + B.x * C.y + A.x * B.y - A.y * B.x - B.y * C.x - A.x * C.y);
}
void Precalc()
{
int i, j, k;
for (i=1; i<=n; ++i)
for (j=i+1; j<=n; ++j)
for (k = 1; k<j; ++k)
if ((min(a[i].x, a[j].x) <= a[k].x && a[k].x < max(a[i].x, a[j].x)) && (Determinant(a[i], a[j], a[k]) < 0))
++nrunder[i][j];
}
void Solve()
{
/// sortez punctele crescator dupa x si in caz de egalitate, descrescator dupa y
sort(a+1, a+n+1);
/// precalculez in nrunder[i][j] cate puncte sunt sub segmentul [i, j) cu i < j
Precalc();
int i, j, k, det;
/**
pentru fiecare segment (i, j) fixat iau oricare al 3 lea punct si calculez aria triunghiului format
precum si cate puncte are in interior. Retin triunghiurile in 2 grupe reprezentand cele 2 semiplanuri
create de dreapta (i, j) stanga[..] respectiv dreapta[..]
stanga[x] = aria minima a unui triunghi care are in interior x puncte,
acest triunghi aflandu-se in semiplanul din stanga
dreapta[x] = aria minima a unui triunghi care are in interior x puncte,
acest triunghi aflandu-se in semiplanul din dreapta
Daca as avea fix K puncte in interior atunci as lua x puncte din stanga si K - x puncte din dreapta
dar cum imi trebuie cel putin K puncte si arie minima, prefer ca pentru un dreapta[x] de exemplu
sa aleg un dreapta[y] cu y>x si dreapta[y] < dreapta[x] (analog si cu stanga)
deci fac minime partiale de la n spre 1
si solutia = min(stanga[x] + dreapta[K-x]) , x de la 0 la K pentru orice i, j fixat; i<j
*/
for (i=1; i<=n; ++i)
{
for (j=i+1; j<=n; ++j)
{
for (k=0; k<=n; ++k)
stanga[k] = dreapta[k] = INF;
for (k=1; k<=n; ++k)
{
if (k == i || k == j)
continue;
det = Determinant(a[i], a[j], a[k]);
if (det > 0)
{
/// stanga
int nrpoints = NrPuncte(i, j, k);
stanga[nrpoints] = min(stanga[nrpoints], Aria(a[i], a[j], a[k]));
}
else
{
///dreapta
int nrpoints = NrPuncte(i, j, k);
dreapta[nrpoints] = min(dreapta[nrpoints], Aria(a[i], a[j], a[k]));
}
}
for (k=n; k; --k)
stanga[k-1] = min(stanga[k-1], stanga[k]),
dreapta[k-1] = min(dreapta[k-1], dreapta[k]);
for (k = 0; k <= K; ++k)
if (stanga[k] != INF && dreapta[K-k] != INF)
sol = min (sol, stanga[k] + dreapta[K-k]);
}
}
}
void Write()
{
FILE *g = fopen ("popandai.out", "w");
fprintf(g, "%.1lf\n", 1.0*sol/2);
fclose(g);
}
int main()
{
Read();
Solve();
Write();
return 0;
}