#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <climits>
#include <algorithm>
#include <map>
#include <queue>
#include <cassert>
using namespace std;

typedef pair<int,int>  pi;
typedef pair<pair<int,int>,int>  ppi;
typedef vector<pair<pair<int,int>,int> >  vppi;
#define ff first.first
#define fs first.second
#define se second

struct Stone { int row, col, d; };

const int VMAX = 1600;
const int MMAX = 80;
const int S = 1598;
const int T = 1599;

struct Edge { int to1, to2, cost; };
vector<Edge> G[VMAX][MMAX];
int dist[VMAX][MMAX];

void addEdge(int u1, int u2, int v1, int v2, int cost) {
    G[u1][u2].push_back((Edge){ v1, v2, cost });
}

int risk(Stone a, Stone b) {
    return (a.d + b.d) * abs(a.col - b.col);
}

int main() {
    int n, m;
    while (cin >> n >> m, n) {
        for (int i=0; i<VMAX; ++i) {
            for (int j=0; j<MMAX; ++j) {
                G[i][j].clear();
            }
        }

        vector<Stone> stones;
        int k;
        for (int i=0; i<n; ++i) {
            cin >> k;
            int x, d;
            for (int j=0; j<k; ++j) {
                cin >> x >> d;
                stones.push_back((Stone){ i, x, d });
            }
        }

        for (int i=0; i<(int)stones.size(); ++i) {
            // S
            if (stones[i].row == 0) {
                for (int j=0; j<=m; ++j) {
                    addEdge(S, j, i, j, 0);
                }
            } else if (stones[i].row == 1) {
                for (int j=1; j<=m; ++j) {
                    addEdge(S, j, i, j-1, 0);
                }
            }

            // T
            if (stones[i].row == n-1) {
                for (int j=0; j<=m; ++j) {
                    addEdge(i, j, T, j, 0);
                }
            } else if (stones[i].row == n-2) {
                for (int j=1; j<=m; ++j) {
                    addEdge(i, j, T, j-1, 0);
                }
            }

            // other
            for (int j=i+1; j<(int)stones.size(); ++j) {
                int jump = stones[j].row - stones[i].row;
                if (3 <= jump) break;
                if (jump == 1) {
                    for (int k=0; k<=m; ++k) {
                        addEdge(i, k, j, k, risk(stones[i], stones[j]));
                    }
                } else if (jump == 2) {
                    for (int k=1; k<=m; ++k) {
                        addEdge(i, k, j, k-1, risk(stones[i], stones[j]));
                    }
                }
            }
        }

        for (int i=0; i<VMAX; ++i) {
            for (int j=0; j<MMAX; ++j) {
                dist[i][j] = INT_MAX;
            }
        }
        dist[S][m] = 0;
        priority_queue<ppi, vppi, greater<ppi> > q;
        q.push(make_pair(make_pair(0, S), m));
        while ( ! q.empty()) {
            int cost = q.top().ff;
            int u1 = q.top().fs;
            int u2 = q.top().se;
            q.pop();
            for (int i=0; i<(int)G[u1][u2].size(); ++i) {
                Edge &e = G[u1][u2][i];
                if (cost + e.cost < dist[e.to1][e.to2]) {
                    dist[e.to1][e.to2] = cost + e.cost;
                    q.push(make_pair(make_pair(cost + e.cost, e.to1), e.to2));
                }
            }
        }
        cout << *min_element(dist[T], dist[T]+MMAX) << endl;
    }
    return 0;
}

Measured memory_bytes: 50068