#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
template <class T>
inline T Sqr(const T& x) {
  return x * x;
}
template <class T>
inline T Abs(const T& x) {
  return x > 0 ? x : -x;
}
template <class T>
inline T Min(const T& a, const T& b) {
  return a < b ? a : b;
}
template <class T>
inline T Max(const T& a, const T& b) {
  return a > b ? a : b;
}
template <class T>
inline void Swap(T& a, T& b) {
  T _;
  _ = a;
  a = b;
  b = _;
}
template <class T>
inline T Ksm(const T& a, const T& b, const T& m) {
  T _ = 1;
  for (; b; b >>= 1, a = a * a % m) (b & 1) ? _ = _ * a % m : 0;
  return _ % m;
}
set<int> S;
int n, m, ufs[maxn], chk;
int a[maxn][maxn], b[maxn][maxn];
int getint() {
  char ch = getchar();
  int result = 0, res = 1;
  for (; '0' > ch || ch > '9'; ch = getchar()) ch == '-' ? res = -1 : 0;
  for (; '0' <= ch && ch <= '9';
       result = result * 10 + ch - '0', ch = getchar())
    ;
  return result * res;
}
int find(int x) {
  int f, tmp;
  for (f = x; ufs[f] != f; f = ufs[f])
    ;
  for (; f != x; tmp = ufs[x], ufs[x] = f, x = tmp)
    ;
  return f;
}
int main() {
  n = getint(), m = getint();
  for (int i = 1; i <= n; ++i) ufs[i] = i;
  for (int i = 1; i <= n; ++i) {
    int k = getint(), j;
    chk += k;
    for (; k--;) j = getint(), a[i][j] = 1, b[j][i] = 1;
  }
  if (chk == 0) return printf("%d", n), 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j)
      if (a[i][j] == 1)
        for (int k = 1; k <= n; ++k)
          if (b[j][k] == 1 && i != k) {
            int fx = find(i), fy = find(k);
            ufs[fx] = fy;
          }
  }
  for (int i = 1; i <= n; ++i) {
    int f = find(i);
    S.insert(f);
  }
  printf("%d", S.size() - 1);
  return 0;
}
