#include <bits/stdc++.h>
std::vector<std::vector<bool> > g(200, std::vector<bool>(200, false));
std::vector<bool> used(200, false);
int n, m;
int gn;
void dfs(int v) {
  used[v] = true;
  for (int i = 0; i < gn; i++) {
    if (!used[i] && g[v][i]) dfs(i);
  }
}
int count_unused() {
  int calls = 0;
  int i;
  for (i = 1; i <= n; i++) {
    if (!used[i * 2 - 2]) {
      dfs(i * 2 - 2);
      calls++;
    }
  }
  int anylang = 0;
  for (i = 1; i <= m; i++) {
    if (used[i * 2 - 1]) {
      anylang = 1;
      break;
    }
  }
  return calls - anylang;
}
void fill_g(int i, int l) {
  int si = i * 2 - 2;
  int li = l * 2 - 1;
  g[si][li] = true;
  g[li][si] = true;
}
int main(int argc, char** argv) {
  scanf("%d %d", &n, &m);
  int i, j, k, l;
  for (i = 1; i <= n; i++) {
    scanf("%d", &k);
    for (j = 0; j < k; j++) {
      scanf("%d", &l);
      fill_g(i, l);
    }
  }
  gn = std::max(n * 2 - 2, m * 2 - 1) + 1;
  printf("%d\n", count_unused());
  return 0;
}
