import fractions import math import sys from collections import Counter, defaultdict, deque from types import GeneratorType # From https://github.com/cheran-senthil/PyRival/blob/master/pyrival/misc/bootstrap.py def bootstrap(f, stack=[]): def wrappedfunc(*args, **kwargs): if stack: return f(*args, **kwargs) else: to = f(*args, **kwargs) while True: if type(to) is GeneratorType: stack.append(to) to = next(to) else: stack.pop() if not stack: break to = stack[-1].send(to) return to return wrappedfunc from math import inf def getArticulationPoints(graph): N = len(graph) visited = [False] * N disc = [inf] * N low = [inf] * N parent = [-1] * N ap = [False] * N time = 0 @bootstrap def dfs(u): nonlocal time children = 0 visited[u] = True disc[u] = time low[u] = time time += 1 for v in graph[u]: if visited[v] == False: parent[v] = u children += 1 yield dfs(v) low[u] = min(low[u], low[v]) if parent[u] == -1 and children > 1: ap[u] = True if parent[u] != -1 and low[v] >= disc[u]: ap[u] = True elif v != parent[u]: low[u] = min(low[u], disc[v]) yield for i in range(N): if visited[i] == False: dfs(i) ret = [x for x in range(N) if ap[x]] return ret def solve(N, L, lines): assert len(lines) == L linesAtStation = defaultdict(set) for i, line in enumerate(lines): for x in line: linesAtStation[x].add(i) essential = set() graph = [set() for i in range(L)] for station, ids in linesAtStation.items(): assert len(ids) > 0 if len(ids) == 1: # disconnects a station that's only on this line (i,) = ids essential.add(i) else: # small only for l1 in ids: for l2 in ids: if l1 != l2: graph[l1].add(l2) graph[l2].add(l1) essential.update(getArticulationPoints(graph)) return len(essential) if __name__ == "__main__": T = int(input()) for t in range(1, T + 1): (N, L) = [int(x) for x in input().split()] lines = [] for _ in range(L): (K,) = [int(x) for x in input().split()] line = [int(x) for x in input().split()] assert len(line) == K lines.append(line) ans = solve(N, L, lines) print("Case #" + str(t) + ": " + str(ans))