#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
const int inf = 2000000000;
const long long infLL = 9000000000000000000;
template <typename first, typename second>
ostream& operator<<(ostream& os, const pair<first, second>& p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  os << "{";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  return os << "}";
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& v) {
  os << "[";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if (it != v.begin()) os << ",";
    os << *it;
  }
  return os << "]";
}
template <typename T>
ostream& operator<<(ostream& os, const multiset<T>& v) {
  os << "[";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if (it != v.begin()) os << ", ";
    os << *it;
  }
  return os << "]";
}
template <typename first, typename second>
ostream& operator<<(ostream& os, const map<first, second>& v) {
  os << "[";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if (it != v.begin()) os << ", ";
    os << it->first << " = " << it->second;
  }
  return os << "]";
}
void faltu() { cerr << '\n'; }
template <typename T>
void faltu(T a[], int n) {
  for (int i = 0; i < n; ++i) cerr << a[i] << ' ';
  cerr << '\n';
}
template <typename T, typename... hello>
void faltu(T arg, const hello&... rest) {
  cerr << arg << ' ';
  faltu(rest...);
}
const int mx = 1e6 + 5;
int n, w;
vector<int> vec[mx];
int l[mx];
set<pair<int, int>, greater<pair<int, int>>> st;
vector<int> tree[mx];
void init(int idx, int node, int l, int r) {
  if (l == r) {
    tree[idx][node] = vec[idx][l];
    return;
  }
  int mid = (l + r) / 2;
  init(idx, 2 * node, l, mid);
  init(idx, 2 * node + 1, mid + 1, r);
  tree[idx][node] = max(tree[idx][2 * node], tree[idx][2 * node + 1]);
}
int query(int idx, int node, int l, int r, int b, int e) {
  if (l > e || r < b) return -inf;
  if (l >= b && r <= e) return tree[idx][node];
  int mid = (l + r) / 2;
  int p1 = query(idx, 2 * node, l, mid, b, e);
  int p2 = query(idx, 2 * node + 1, mid + 1, r, b, e);
  return max(p1, p2);
}
int L[mx], R[mx];
long long tree2[mx * 4];
void update2(int node, int l, int r, int b, int x) {
  if (l == r) {
    tree2[node] = x;
    return;
  }
  int mid = (l + r) / 2;
  if (mid >= b)
    update2(2 * node, l, mid, b, x);
  else
    update2(2 * node + 1, mid + 1, r, b, x);
  tree2[node] = tree2[2 * node] + tree2[2 * node + 1];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> w;
  for (int i = 0; i < n; ++i) {
    L[i] = R[i] = 1;
    cin >> l[i];
    st.insert(make_pair(l[i], i));
    vec[i].resize(l[i] + 1);
    tree[i].resize((l[i] + 1) * 4);
    for (int j = 1; j <= l[i]; ++j) {
      cin >> vec[i][j];
    }
    init(i, 1, 1, l[i]);
  }
  for (int i = 1; i <= w; ++i) {
    long long ans = 0;
    for (set<pair<int, int>, greater<pair<int, int>>>::iterator itr =
             st.begin();
         itr != st.end(); ++itr) {
      if (min(i, w - i + 2) > (*itr).first) break;
      pair<int, int> p = *itr;
      L[p.second] = max(1, p.first - (w - i));
      R[p.second] = min(p.first, i);
      long long temp =
          query(p.second, 1, 1, l[p.second], L[p.second], R[p.second]);
      if (p.first < i || i + p.first <= w) temp = max(temp, 0LL);
      update2(1, 1, n, p.second + 1, temp);
    }
    ans = tree2[1];
    cout << ans << " ";
  }
}
