/*
这题弄懂的过程可谓相当艰难...为了弄懂差分法和线段扫描法,我大约参考了四串代码(当然,其实看代码不是最难的,最难的是,我知道代码的语义,可是不知道为什么要那样写...)下面贴四个blog,里面的解析,对于理解代码和理解这两种方法,非常重要!!
http://blog.csdn.net/h1021456873/article/details/53240994
http://www.cnblogs.com/agenthtb/p/5998819.html
http://www.cnblogs.com/iRedBean/p/5975561.html
http://blog.csdn.net/morejarphone/article/details/52852161
以及,这题后来还RE了几次,发现是我太粗心了,a数组和d数组的维度是不同的,前者约是n的上限,后者约是c的上限,两个上限不同,就算要以一种代替所有,也应该选c的上限,才不会越界...可因为我的粗心,运行错误了几次,戒之慎勿忘!!!
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
const int M = 1e6 + 10;
vector<int>a[N];
int d[M];
void work(int l, int r)
{
d[l]++;
d[r + 1]--;
}
int main()
{
cin.tie(0);
cin.sync_with_stdio(false);
memset(d, 0, sizeof(d));
int n, c, m, tp, i, j, x, y;
cin >> n >> c;
int sum = 0, flag = 1;
for ( i = 1; i <= n; i++ )
{
a[i].clear();
cin >> m;
a[i].push_back(m);
for ( j = 1; j <= a[i][0]; j++ )
{
cin >> m; a[i].push_back(m);
}
}
for ( i = 1; i < n; i++ )
{
tp = min(a[i][0], a[i+1][0]);
for ( j = 1; j <= tp; j++)
{
x = a[i][j];
y = a[i + 1][j];
if ( x != y) break;
}
if (j > tp && a[i][0] > a[i+1][0])
{
cout << -1 << endl;
return 0;
}
if ( y > x )
{
work(0, c - y);
work(c + 1 - x, c - 1);
}
else if ( x > y )
{
work(c + 1 - x, c - y );
}
else work(0, c - 1);
}
for (int i = 0; i < c; i++)
{
sum += d[i];
if ( sum == n - 1)
{
cout << i << endl;
flag = 0; break;
}
}
if (flag)
cout << -1 << endl;
return 0;
}