You are given n sequences. Each sequence consists of positive integers, not exceeding m. All integers in one sequence are distinct, but the same integer may appear in multiple sequences. The length of the i-th sequence is ki.

Each second integers in each of the sequences are shifted by one to the left, i.e. integers at positions i > 1 go to positions i - 1, while the first integers becomes the last.

Each second we take the first integer of each sequence and write it down to a new array. Then, for each value x from 1 to m we compute the longest segment of the array consisting of element x only.

The above operation is performed for 10100 seconds. For each integer from 1 to m find out the longest segment found at this time.

Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 100 000) — the number of sequences and the maximum integer that can appear in the sequences. 

Then follow n lines providing the sequences. Each of them starts with an integer ki (1 ≤ ki ≤ 40) — the number of integers in the sequence, proceeded by ki positive integers — elements of the sequence. It's guaranteed that all integers in each sequence are pairwise distinct and do not exceed m.

The total length of all sequences doesn't exceed 200 000.

Output

Print m integers, the i-th of them should be equal to the length of the longest segment of the array with all its values equal to i during the first 10100 seconds.

Examples

Input

3 4
3 3 4 1
4 1 3 4 2
3 3 1 4


Output

2
1
3
2


Input

5 5
2 3 1
4 5 1 3 2
4 2 1 3 5
1 3
2 5 3


Output

3
1
4
0
1


Input

4 6
3 4 5 3
2 6 3
2 3 6
3 3 6 5


Output

0
0
2
1
1
2
#include <bits/stdc++.h>
using namespace std;
struct edge {
  long long to, cost;
  edge() {}
  edge(long long a, long long b) { to = a, cost = b; }
};
const long long dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
const long long mod = 1000000007;
struct mint {
  long long x = 0;
  mint(long long y = 0) {
    x = y;
    if (x < 0 || x >= mod) x = (x % mod + mod) % mod;
  }
  mint(const mint& ope) { x = ope.x; }
  mint operator-() { return mint(-x); }
  mint operator+(const mint& ope) { return mint(x) += ope; }
  mint operator-(const mint& ope) { return mint(x) -= ope; }
  mint operator*(const mint& ope) { return mint(x) *= ope; }
  mint operator/(const mint& ope) { return mint(x) /= ope; }
  mint& operator+=(const mint& ope) {
    x += ope.x;
    if (x >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint& ope) {
    x += mod - ope.x;
    if (x >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint& ope) {
    x *= ope.x, x %= mod;
    return *this;
  }
  mint& operator/=(const mint& ope) {
    long long n = mod - 2;
    mint mul = ope;
    while (n) {
      if (n & 1) *this *= mul;
      mul *= mul;
      n >>= 1;
    }
    return *this;
  }
  mint inverse() { return mint(1) / *this; }
  bool operator==(const mint& ope) { return x == ope.x; }
  bool operator!=(const mint& ope) { return x != ope.x; }
};
mint modpow(mint a, long long n) {
  if (n == 0) return mint(1);
  if (n % 2)
    return a * modpow(a, n - 1);
  else
    return modpow(a * a, n / 2);
}
istream& operator>>(istream& is, mint& ope) {
  long long t;
  is >> t, ope.x = t;
  return is;
}
ostream& operator<<(ostream& os, mint& ope) { return os << ope.x; }
ostream& operator<<(ostream& os, const mint& ope) { return os << ope.x; }
bool exceed(long long x, long long y, long long m) { return x >= m / y + 1; }
void mark() { cout << "*" << endl; }
void yes() { cout << "YES" << endl; }
void no() { cout << "NO" << endl; }
long long sgn(long long x) {
  if (x > 0) return 1;
  if (x < 0) return -1;
  return 0;
}
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
long long digitnum(long long x, long long b = 10) {
  long long ret = 0;
  for (; x; x /= b) ret++;
  return ret;
}
long long digitsum(long long x, long long b = 10) {
  long long ret = 0;
  for (; x; x /= b) ret += x % b;
  return ret;
}
string lltos(long long x) {
  string ret;
  for (; x; x /= 10) ret += x % 10 + '0';
  reverse(ret.begin(), ret.end());
  return ret;
}
long long stoll(string& s) {
  long long ret = 0;
  for (auto c : s) ret *= 10, ret += c - '0';
  return ret;
}
template <typename T>
void uniq(T& vec) {
  sort(vec.begin(), vec.end());
  vec.erase(unique(vec.begin(), vec.end()), vec.end());
}
template <typename T>
ostream& operator<<(ostream& os, vector<T>& vec) {
  for (int i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, deque<T>& deq) {
  for (int i = 0; i < deq.size(); i++)
    os << deq[i] << (i + 1 == deq.size() ? "" : " ");
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U>& pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, map<T, U>& map_var) {
  for (typename map<T, U>::iterator itr = map_var.begin(); itr != map_var.end();
       itr++) {
    os << "(" << itr->first << ", " << itr->second << ")";
    itr++;
    if (itr != map_var.end()) os << ",";
    itr--;
  }
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T>& set_var) {
  for (typename set<T>::iterator itr = set_var.begin(); itr != set_var.end();
       itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, multiset<T>& set_var) {
  for (typename multiset<T>::iterator itr = set_var.begin();
       itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}
template <typename T>
void outa(T a[], long long s, long long t) {
  for (long long i = s; i <= t; i++) {
    cout << a[i];
    if (i < t) cout << " ";
  }
  cout << endl;
}
void dump_func() { cout << endl; }
template <class Head, class... Tail>
void dump_func(Head&& head, Tail&&... tail) {
  cout << head;
  if (sizeof...(Tail) > 0) cout << " ";
  dump_func(std::move(tail)...);
}
long long extgcd(long long a, long long b, long long& x, long long& y) {
  if (b == 0) {
    x = 1, y = 0;
    return a;
  }
  long long xx, yy;
  long long d = extgcd(b, a % b, xx, yy);
  x = yy, y = xx - (a / b) * yy;
  return d;
}
long long mod_inverse(long long a, long long m) {
  long long x, y;
  if (extgcd(a, m, x, y) != 1) return -1;
  return (x % m + m) % m;
}
long long mul(long long a, long long n, long long mod) {
  if (n == 0) return 0;
  if (n % 2)
    return (mul(a, n - 1, mod) + a) % mod;
  else
    return mul(a, n / 2, mod) * 2 % mod;
}
pair<long long, long long> congruence(long long a, long long b, long long m) {
  long long d = gcd(a, m);
  if (b % d) return make_pair(0, -1);
  a /= d, b /= d, m /= d;
  return pair<long long, long long>(mul(b % m, mod_inverse(a, m) % m, m), m);
}
pair<long long, long long> SimultaneousCongruence(long long a[], long long b[],
                                                  long long m[], long long n) {
  long long x = 0, M = 1;
  for (int i = 1; i <= n; i++) {
    pair<long long, long long> res =
        congruence(a[i] * M, (b[i] - a[i] * x % m[i] + m[i]) % m[i], m[i]);
    if (res.second == -1) return res;
    x += M * res.first, M *= res.second;
  }
  return make_pair(x, M);
}
struct SWAG {
  long long size;
  stack<pair<long long, long long> > head, tail;
  pair<long long, long long> rsum;
  SWAG() { init(); }
  pair<long long, long long> Ident() {
    return pair<long long, long long>(0, 1);
  }
  pair<long long, long long> ope(pair<long long, long long> x,
                                 pair<long long, long long> y) {
    if (x.second == -1 || y.second == -1)
      return pair<long long, long long>(0, -1);
    long long a[] = {0, 1, 1}, b[] = {0, x.first, y.first},
              m[] = {0, x.second, y.second};
    return SimultaneousCongruence(a, b, m, 2);
  }
  void init() {
    size = 0;
    while (head.size()) head.pop();
    while (tail.size()) tail.pop();
    rsum = Ident();
  }
  void push(pair<long long, long long> x) {
    size++;
    rsum = ope(rsum, x);
    tail.push(x);
  }
  void pop() {
    if (size == 0) return;
    if (head.size() == 0) {
      pair<long long, long long> sum = Ident();
      while (tail.size()) {
        pair<long long, long long> x = tail.top();
        sum = ope(x, sum);
        head.push(sum);
        tail.pop();
      }
      rsum = Ident();
    }
    head.pop();
    size--;
  }
  pair<long long, long long> query() {
    pair<long long, long long> ret = rsum;
    if (head.size()) ret = ope(head.top(), ret);
    return ret;
  }
};
long long n, m;
long long k[100005];
vector<pair<long long, long long> > vec[100005];
SWAG swag;
long long calc(vector<pair<long long, long long> >& vec) {
  if (((long long)(vec).size()) < 0) return -1e18;
  swag.init();
  long long n = ((long long)(vec).size()), r = -1, ret = 0;
  for (long long(i) = (0); (i) <= (n - 1); (i)++) {
    while (r + 1 < n) {
      r++;
      swag.push(vec[r]);
      if (swag.query().second != -1)
        (ret) = max((ret), (r - i + 1));
      else
        break;
    }
    swag.pop();
  }
  return ret;
}
int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  long long x;
  for (long long(i) = (1); (i) <= (n); (i)++) {
    cin >> k[i];
    for (long long(j) = (0); (j) <= (k[i] - 1); (j)++)
      cin >> x, vec[x].push_back(pair<long long, long long>(i, j));
  }
  for (long long(i) = (1); (i) <= (m); (i)++) {
    vector<pair<long long, long long> > tmp;
    long long ans = 0;
    for (long long(j) = 0; (j) < (long long)(vec[i]).size(); (j)++) {
      if (j > 0 && vec[i][j].first > vec[i][j - 1].first + 1) {
        (ans) = max((ans), (calc(tmp)));
        tmp.clear();
      }
      tmp.push_back(
          pair<long long, long long>(vec[i][j].second, k[vec[i][j].first]));
    }
    (ans) = max((ans), (calc(tmp)));
    cout << ans << "\n";
  }
  return 0;
}
