#include <bits/stdc++.h>
using namespace std;
long long MOD_EXPO(long long b, long long p, long long m) {
  if (p == 0) return 1;
  long long ret = MOD_EXPO(b, p / 2, m) % m;
  ret = (ret * ret) % m;
  return ((p & 1) ? (ret * b) % m : ret % m);
}
long long POWER(long long N, long long K) {
  long long i, ans = 1;
  for (i = 1; i <= K; i++) ans *= N;
  return ans;
}
int SET(int N, int pos) { return (N | (1 << pos)); }
int RESET(int N, int pos) { return (N & !(1 << pos)); }
bool CHECK(int N, int pos) { return (N & (1 << pos)); }
int dx4[] = {1, -1, 0, 0};
int dy4[] = {0, 0, 1, -1};
int dx6[] = {0, 0, 1, -1, 0, 0};
int dy6[] = {1, -1, 0, 0, 0, 0};
int dz6[] = {0, 0, 0, 0, 1, -1};
int dx8[] = {1, -1, 0, 0, -1, 1, -1, 1};
int dy8[] = {0, 0, 1, -1, 1, 1, -1, -1};
int dkx8[] = {-1, 1, -1, 1, -2, -2, 2, 2};
int dky8[] = {2, 2, -2, -2, 1, -1, 1, -1};
int tc = 1;
const double eps = 1e-9;
const double pi = acos(-1.0);
const long long int mx = 1e2;
const long long int mod = 1e9 + 7;
int zero[mx + 5];
int prev_[mx + 5];
int parent[mx + 5];
int set_size[mx + 5];
void make_set(void) {
  int i;
  for (i = 1; i <= mx; i++) {
    zero[i] = 0;
    prev_[i] = 0;
    parent[i] = i;
    set_size[i] = 0;
  }
  return;
}
int find_set(int x) {
  if (x == parent[x]) return x;
  return parent[x] = find_set(parent[x]);
}
void union_set(int a, int b) {
  int u = find_set(a);
  int v = find_set(b);
  if (u != v) {
    parent[u] = v;
    set_size[v] += set_size[u];
    set_size[u] = set_size[v];
  }
  return;
}
int main() {
  int i, j, n, m, a, b, ans;
  set<int> s;
  make_set();
  cin >> n >> m;
  ans = 0;
  for (i = 1; i <= n; i++) {
    scanf("%d", &a);
    for (j = 1; j <= a; j++) {
      scanf("%d", &b);
      if (prev_[b]) {
        union_set(i, prev_[b]);
      }
      prev_[b] = i;
    }
    if (a == 0) {
      ans++;
      zero[i] = 1;
    }
  }
  for (i = 1; i <= n; i++) {
    if (!zero[i]) s.insert(find_set(i));
  }
  ans += max(0, (int)s.size() - 1);
  cout << ans << "\n";
  return 0;
}
