#include <bits/stdc++.h>
using namespace std;
struct Point {
  int x;
  int y;
  int index;
  double angle;
  void Translate(int dx, int dy) {
    x += dx;
    y += dy;
  }
  void CalculateAngle() { angle = atan2(y, x); }
  bool operator<(const Point& p) const { return angle < p.angle; }
};
std::ostream& operator<<(std::ostream& stream, const Point& p) {
  stream << "(" << p.x << "," << p.y << ")";
}
int n, m;
Point points[250];
Point ccPoints[250];
queue<int> Q[250];
vector<int> visibleOut[250], visibleIn[250];
long long dp[250][250][51];
long long maxArea[51];
long long sol = 0;
bool IsLeftTurn(Point p1, Point p2, Point p3) {
  Point v1;
  v1.x = p2.x - p1.x;
  v1.y = p2.y - p1.y;
  Point v2;
  v2.x = p3.x - p2.x;
  v2.y = p3.y - p2.y;
  return (long long)v1.x * v2.y - (long long)v1.y * v2.x > 0;
}
inline long long TriangleArea(Point p1, Point p2) {
  return (long long)p1.x * p2.y - (long long)p1.y * p2.x;
}
void Proceed(int i, int j) {
  while (Q[i].size() > 0 &&
         IsLeftTurn(ccPoints[Q[i].front()], ccPoints[i], ccPoints[j])) {
    Proceed(Q[i].front(), j);
    Q[i].pop();
  }
  visibleOut[i].push_back(j);
  visibleIn[j].push_back(i);
  Q[j].push(i);
}
inline void MakeVisibilityGraph(int rightCount) {
  for (int i = 0; i < rightCount; i++) {
    while (!Q[i].empty()) {
      Q[i].pop();
    }
    visibleIn[i].clear();
    visibleOut[i].clear();
  }
  for (int i = 0; i < rightCount - 1; i++) {
    Proceed(i, i + 1);
  }
}
inline void MaxArea(int rightCount) {
  for (int i = 0; i < rightCount; i++) {
    for (int j = 0; j < visibleOut[i].size(); j++) {
      for (int k = 0; k <= m; k++) dp[i][visibleOut[i][j]][k] = 0;
    }
  }
  for (int i = rightCount - 1; i >= 0; i--) {
    for (int j = 0; j <= m; j++) maxArea[j] = 0;
    int outIndex = visibleOut[i].size() - 1;
    for (int inIndex = visibleIn[i].size() - 1; inIndex >= 0; inIndex--) {
      dp[visibleIn[i][inIndex]][i][0] = 0;
      dp[visibleIn[i][inIndex]][i][1] =
          TriangleArea(ccPoints[visibleIn[i][inIndex]], ccPoints[i]);
      for (int j = 2; j <= m; j++)
        dp[visibleIn[i][inIndex]][i][j] =
            maxArea[j - 1] > 0
                ? maxArea[j - 1] +
                      TriangleArea(ccPoints[visibleIn[i][inIndex]], ccPoints[i])
                : 0;
      while (outIndex >= 0 &&
             IsLeftTurn(ccPoints[visibleIn[i][inIndex]], ccPoints[i],
                        ccPoints[visibleOut[i][outIndex]])) {
        for (int j = 1; j <= 50; j++) {
          if (dp[i][visibleOut[i][outIndex]][j - 1] > maxArea[j - 1]) {
            maxArea[j - 1] = dp[i][visibleOut[i][outIndex]][j - 1];
            dp[visibleIn[i][inIndex]][i][j] =
                maxArea[j - 1] +
                TriangleArea(ccPoints[visibleIn[i][inIndex]], ccPoints[i]);
          }
        }
        outIndex--;
      }
    }
  }
  for (int i = 0; i < rightCount; i++) {
    for (int j = 0; j < visibleOut[i].size(); j++) {
      sol = max(sol, dp[i][visibleOut[i][j]][m - 2]);
    }
  }
}
inline void ProcessLeftmostPoint(int leftIndex) {
  int rightCount = 0;
  for (int i = 0; i < n; i++) {
    if (i != leftIndex && points[i].x >= points[leftIndex].x) {
      ccPoints[rightCount] = points[i];
      ccPoints[rightCount].Translate(-points[leftIndex].x,
                                     -points[leftIndex].y);
      ccPoints[rightCount].CalculateAngle();
      ++rightCount;
    }
  }
  sort(ccPoints, ccPoints + rightCount);
  MakeVisibilityGraph(rightCount);
  MaxArea(rightCount);
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d %d", &points[i].x, &points[i].y);
    points[i].index = i;
  }
  for (int i = 0; i < n; i++) {
    ProcessLeftmostPoint(i);
  }
  cout << sol / 2 << (sol % 2 == 1 ? ".50" : ".00") << endl;
  return 0;
}
