#include <bits/stdc++.h>
using namespace std;
const int BUFSIZE = 1 << 16;
char BUFFER[BUFSIZE + 5];
int REM = 0, POS = 0;
char GETCHAR() {
  if (REM <= 0) {
    POS = 0;
    REM = fread(BUFFER, 1, BUFSIZE, stdin);
    if (REM <= 0) return EOF;
  }
  --REM;
  return BUFFER[POS++];
}
void GETALPHA(char &C) {
  C = EOF;
  while (!isalpha(C)) C = GETCHAR();
}
template <class T>
void GETINT(T &VAL) {
  VAL = 0;
  char C = EOF;
  while (C != '-' && !isdigit(C)) C = GETCHAR();
  bool NEG = C == '-';
  if (NEG) C = GETCHAR();
  while (isdigit(C)) {
    VAL = VAL * 10 + C - '0';
    C = GETCHAR();
  }
  if (NEG) VAL = -VAL;
}
const int MAXN = 1005;
struct Product {
  int idx, type;
  long long cost;
  bool operator<(const Product &that) const { return cost > that.cost; }
};
int n, k;
Product a[MAXN];
vector<int> res[MAXN];
bool used[MAXN];
bool hasStool[MAXN];
int main() {
  GETINT(n);
  GETINT(k);
  for (int i = (1); i <= (n); ++i) {
    a[i].idx = i;
    GETINT(a[i].cost);
    GETINT(a[i].type);
  }
  sort(a + 1, a + n + 1);
  memset(used, false, sizeof(used));
  memset(hasStool, false, sizeof(hasStool));
  int cnt = 0;
  for (int i = (1); i <= (n); ++i)
    if (cnt < k && a[i].type == 1) {
      used[i] = true;
      res[cnt].push_back(i);
      hasStool[cnt] = true;
      ++cnt;
    }
  for (int i = (1); i <= (n); ++i)
    if (cnt < k && !used[i]) {
      used[i] = true;
      res[cnt].push_back(i);
      ++cnt;
    }
  for (int i = (1); i <= (n); ++i)
    if (!used[i]) res[k - 1].push_back(i);
  double total = 0;
  for (int i = 0; i < (k); ++i) {
    long long small = a[res[i][0]].cost;
    for (int j = 0; j < (res[i].size()); ++j) {
      total += a[res[i][j]].cost;
      small = min(small, a[res[i][j]].cost);
    }
    if (hasStool[i]) total -= 0.5 * small;
  }
  printf("%0.1lf\n", total);
  for (int i = 0; i < (k); ++i) {
    printf("%d ", res[i].size());
    for (int j = 0; j < (res[i].size()); ++j) printf("%d ", a[res[i][j]].idx);
    printf("\n");
  }
  return 0;
}
