The "BerCorp" company has got *n* employees. These employees can use *m* approved official languages for the formal correspondence. The languages are numbered with integers from 1 to *m*. For each employee we have the list of languages, which he knows. This list could be empty, i. e. an employee may know no official languages. But the employees are willing to learn any number of official languages, as long as the company pays their lessons. A study course in one language for one employee costs 1 berdollar.

Find the minimum sum of money the company needs to spend so as any employee could correspond to any other one (their correspondence can be indirect, i. e. other employees can help out translating).
The first line contains two integers *n* and *m* (2 ≤ *n*, *m* ≤ 100) — the number of employees and the number of languages.

Then *n* lines follow — each employee's language list. At the beginning of the *i*-th line is integer *k*<sub class="lower-index">*i*</sub> (0 ≤ *k*<sub class="lower-index">*i*</sub> ≤ *m*) — the number of languages the *i*-th employee knows. Next, the *i*-th line contains *k*<sub class="lower-index">*i*</sub> integers — *a*<sub class="lower-index">*ij*</sub> (1 ≤ *a*<sub class="lower-index">*ij*</sub> ≤ *m*) — the identifiers of languages the *i*-th employee knows. It is guaranteed that all the identifiers in one list are distinct. Note that an employee may know zero languages.

The numbers in the lines are separated by single spaces.
n,m=list(map(lambda x:int(x),input().split()))
sets=[]
for _ in range(n):
    a=list(map(lambda x:int(x),input().split()))
    if a[0]==0:
        sets.append(set())
    else:
        sets.append(set(a[1:]))
class DisjSet:
    def __init__(self, n):
        # Constructor to create and
        # initialize sets of n items
        self.rank = [1] * n
        self.parent = [i for i in range(n)]
        self.extra=[]

    # Finds set of given item x
    def find(self, x):

        # Finds the representative of the set
        # that x is an element of
        if (self.parent[x] != x):
            # if x is not the parent of itself
            # Then x is not the representative of
            # its set,
            self.parent[x] = self.find(self.parent[x])

        # so we recursively call Find on its parent
        # and move i's node directly under the
        # representative of this set

        return self.parent[x]

    # Do union of two sets represented
    # by x and y.
    def Union(self, x, y):

        # Find current sets of x and y
        xset = self.find(x)
        yset = self.find(y)

        # If they are already in same set
        if xset == yset:
            self.extra.append((x,y))
            return

        # Put smaller ranked item under
        # bigger ranked item if ranks are
        # different
        if self.rank[xset] < self.rank[yset]:
            self.parent[xset] = yset

        elif self.rank[xset] > self.rank[yset]:
            self.parent[yset] = xset

        # If ranks are same, then move y under
        # x (doesn't matter which one goes where)
        # and increment rank of x's tree
        else:
            self.parent[yset] = xset
            self.rank[xset] = self.rank[xset] + 1
obj=DisjSet(n)
for i in range(n):
    for j in range(i+1,n):
        if len(sets[i].intersection(sets[j]))>0:
            obj.Union(i,j)
reps=set()
for i in range(n):
    reps.add(obj.find(i))
print(len(reps)-1)