import heapq
import sys
input = iter(sys.stdin.read().splitlines()).__next__


n, m = map(int, input().split())
S = [tuple(sorted([int(i)-1 for i in input().split()][1:])) for i in range(n)]
indices = {(vec[0], vec[-1]): i+1 for i, vec in enumerate(S)}

# redundant vectors should be part of cycle
graph = {}
# print(S)
for vec in S:
    first_one = vec[0]
    second_one = vec[-1]
    for a, b in ((first_one, second_one), (second_one, first_one)):
        if a not in graph:
            graph[a] = set()
        graph[a].add(b)
# print(graph)

# take vectors starting from lexicographically smallest until we find a cycle
# S.sort()
# S_prime = []
# visited = set()
# for vec in S:
#     if vec in visited:
#         continue
#     queue = [vec]
#     parents = {vec: None}
#     while queue:
#         vec = heapq.heappop(queue)
#         visited.add(vec)
#         if vec[0] == vec[1]:
#             continue
S_prime = set()
for dim in range(m):
    if dim in graph:
        if dim in graph[dim]:
            other_dim = dim
        else:
            other_dim = max(graph[dim])
        S_prime.add((min(dim, other_dim), max(dim, other_dim)))
        # S_prime.add(tuple(sorted(dim, min(graph[dim]))))

# 2**|S'| different sums among |S'| linearly independent vectors
T_size = pow(2, len(S_prime), 10**9+7)
print(T_size, len(S_prime))
# print(S_prime)
print(*sorted(map(indices.get, S_prime)))