#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;   }