#include <bits/stdc++.h>
using namespace std;

#define start_routine() int begtime = clock();
#define end_routine() int endtime = clock(); cerr << endl << "Time elapsed: " << (endtime - begtime)*1000/CLOCKS_PER_SEC << " ms"; return 0
#define speed() cin.tie(0), cout.tie(0), ios_base::sync_with_stdio(false)
#define exit(a, b) return cout << a, b;

#define PB push_back
#define MP make_pair

#define sd(n) scanf("%lld", &n)
#define pdn(n) printf("%lld\n", n);
#define pds(n) printf("%lld ", n);
#define endl '\n'

#define forn(a, b, i) for (int i = a; i < b; i += 1)
#define all(v) v.begin(), v.end() 

using vi = vector<int>;
using vb = vector<bool>;
using pii = pair<int, int>;
using mii = map<int, int>;

#define print(stuff) cout << stuff << endl
#define len(stuff) stuff.size()

#define int long long
#define float long double 

const int upper = 5e5 + 2;
const int M = (int) 998244353;
const int inf = (int) 1e17;
const double eps =  1e-8;

int n, q; 
vector<vector<pii>> adj;

#define left lft
#define right rgt 

int left[upper], right[upper], arr[upper];
int idx[upper];

int next_id = 0;

int tree[8 * upper], tag[8 * upper];

vector<pair<pii, int>> queries[upper];
int response[upper];

void dfs (int root, int prev) {
	bool is_leaf = true;
	next_id += 1;
	idx[root] = next_id;
	for (auto i: adj[root]) {
		if (i.first != prev) {
			is_leaf = false;
			dfs(i.first, root);	
		}
	}
	left[root] = inf, right[root] = -inf;
	for (auto i: adj[root]) {
		if (i.first != prev) {
			left[root] = min(left[root], left[i.first]);
			right[root] = max(right[root], right[i.first]);
		}
	}
	if (is_leaf) {
		left[root] = right[root] = idx[root];
	}
}

void init () {
	for (int i = 0; i < 4 * upper; i += 1) tree[i] = inf, tag[i] = 0;
	for (int i = 0; i < upper; i += 1) arr[i] = inf;
}

void dfs0 (int root, int prev, int covered) {
	bool is_leaf = true;
	for (auto i: adj[root]) {
		if (i.first != prev) {
			is_leaf = false;
			dfs0(i.first, root, covered + i.second);
		}
	}
	if (is_leaf) {
		arr[idx[root]] = covered;
	}
}

void build (int node, int l, int r) {
	if (l == r) {
		tree[node] = arr[l];
		return;
	}
	int mid = (l + r) >> 1;
	build (2 * node + 1, l, mid);
	build (2 * node + 2, mid + 1, r);

	tree[node] = min(tree[2 * node + 1], tree[2 * node + 2]);
}

int query (int node, int l, int r, int lq, int rq) {
	if (rq < l or lq > r) return inf;
	if (l == r) {
		tree[node] += tag[node];
		tag[node] = 0;
		return tree[node];
	}
	if (tag[node]) {
		tag[2 * node + 1] += tag[node];
		tag[2 * node + 2] += tag[node];
		tree[node] += tag[node];
		tag[node] = 0;
	}
	if (lq <= l and rq >= r) return tree[node];
	int mid = (l + r) >> 1;
	return min(query(2 * node + 1, l, mid, lq, rq), query(2 * node + 2, mid + 1, r, lq, rq));
}
	
void update (int node, int l, int r, int lu, int ru, int add) {
	if (lu > r or ru < l) return;
	if (tag[node]) {
		tree[node] += tag[node];
		tag[2 * node + 1] += tag[node];
		tag[2 * node + 2] += tag[node];
		tag[node] = 0;
	}
	if (l >= lu and r <= ru) {
		tag[node] += add;
		return; 
	} 
	int mid = (l + r) >> 1;
	update (2 * node + 1, l, mid, lu, ru, add);
	update (2 * node + 2, mid + 1, r, lu, ru, add);

	tree[node] = min(tree[2 * node + 1] + tag[2 * node + 1], tree[2 * node + 2] + tag[2 * node + 2]);
}

void dfs_answer (int root, int prev) {
	for (auto i: queries[root]) {
		int ans = query(1, 1, upper, i.first.first, i.first.second);
		response[i.second] = ans;
	}
	for (auto i: adj[root]) {
		if (i.first == prev) 
			continue;
		update(1, 1, upper, 1, upper, i.second);
		update(1, 1, upper, left[i.first], right[i.first], -2 * i.second);
		dfs_answer(i.first, root);
		update(1, 1, upper, 1, upper, -i.second);
		update(1, 1, upper, left[i.first], right[i.first], 2 * i.second);
	}
}

signed main () {
	start_routine();
	speed();
	#ifndef ONLINE_JUDGE
	// freopen("input.txt", "r", stdin);
	// freopen("output.txt", "w", stdout);
	// freopen("errlog.txt", "w", stderr);
	#endif

	int n, m; cin >> n >> m;
	int cnt[m + 1] = {0};

	for (int i = 1; i <= n; i += 1) {
		int k; cin >> k;
		for (int j = 1; j <= k; j += 1) {
			int lol; cin >> lol;
			cnt[lol] += 1;
		}
	}

	int ans = 0;
	for (int i = 1; i <= m; i += 1) {
		if (cnt[i] == n) ans += 1;
	}

	cout << ans;
 	end_routine();	
}

Measured memory_bytes: 14592