#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */


bool solve() {

  int n, m; cin >> n >> m;
  if (n == 0 and m == 0) {
    return false;
  }

  vector<vector<pair<int, int>>> info(n); // info[i] := 行 i {位置，cost}

  for (int i = 0; i < n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int pos, cost; cin >> pos >> cost;
      info[i].push_back({pos, cost});
    }
  }
  
  vector<vector<vector<lint>>> dp(n, vector<vector<lint>> (1001, vector<lint> (m + 1, INF)));
  for (int j = 0; j < info[0].size(); j++) {
    int pos = info[0][j].first;
    dp[0][pos][0] = 0;
  }

  for (int j = 0; j < info[1].size(); j++) {
    int pos = info[1][j].first;
    dp[1][pos][1] = 0;
  }

  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < info[i].size(); j++) {
      for (int k = 0; k <= m; k++) {
        // cerr << "kudan : " << dp[2][1][1] << endl;
        int curPos = info[i][j].first;
        lint cost1 = info[i][j].second;
        lint curCost = dp[i][curPos][k];

        // 普通のジャンプ
        for (int j = 0; j < info[i + 1].size(); j++) {
          int nxtPos = info[i + 1][j].first;
          lint cost2 = info[i + 1][j].second;
          lint nxtCost = (cost1 + cost2) * (lint)abs(curPos - nxtPos);
          dp[i + 1][nxtPos][k] = min(dp[i + 1][nxtPos][k], curCost + nxtCost);
        }

        // 2 段飛ばしジャンプ
        if (i + 2 < n and k < m) {
          for (int j = 0; j < info[i + 2].size(); j++) {
            int nxtPos = info[i + 2][j].first;
            // cerr << "i = " << i << ", curPos = " << curPos << ", nxtPos = " << nxtPos << endl;
            lint cost2 = info[i + 2][j].second;
            lint nxtCost = (cost1 + cost2) * (lint)abs(curPos - nxtPos);
            // cerr << "curCost = " << curCost << ", nxtCost = " << nxtCost << endl;
            // cerr << "before: " << i + 2 << " " << nxtPos << " " << k + 1 << ", " << dp[i + 2][nxtPos][k + 1] << endl;
            dp[i + 2][nxtPos][k + 1] = min(dp[i + 2][nxtPos][k + 1], curCost + nxtCost);
            // cerr << "after: " << i + 2 << " " << nxtPos << " " << k + 1 << ", " << dp[i + 2][nxtPos][k + 1] << endl;
          }
        }
      }
    }
  }

  lint ans = INF;
  for (int j = 0; j < info[n - 1].size(); j++) {
    for (int k = 0; k <= m; k++) {
      int pos = info[n - 1][j].first;
      ans = min(ans, dp[n - 1][pos][k]);
    }
  }

  for (int j = 0; j < info[n - 2].size(); j++) {
    for (int k = 0; k < m; k++) {
      int pos = info[n - 2][j].first;
      ans = min(ans, dp[n - 2][pos][k]);
    }
  }

  cout << ans << endl;
  return true;
}


int main() {
  
  while (1) {
    if (!solve()) break;
  }
  return 0;
}



Measured memory_bytes: 98412