"""
#If FastIO not needed, use this and don't forget to strip
#import sys, math
#input = sys.stdin.readline
"""

import os
import sys
from io import BytesIO, IOBase
import heapq as h 
from bisect import bisect_left, bisect_right
import time

from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
 
    def __init__(self, file):
        import os
        self.os = os
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None
 
    def read(self):
        while True:
            b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()
 
    def readline(self):
        while self.newlines == 0:
            b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()
 
    def flush(self):
        if self.writable:
            self.os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)
 
 
class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")
 
 
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

from collections import defaultdict as dd, deque as dq, Counter as dc
import math, string

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

start_time = time.time()

def getInts():
    return [int(s) for s in input().split()]

def getInt():
    return int(input())

def getStrs():
    return [s for s in input().split()]

def getStr():
    return input()

def listStr():
    return list(input())

def getMat(n):
    return [getInts() for _ in range(n)]

def isInt(s):
    return '0' <= s[0] <= '9'

MOD = 10**9+7 

"""
Where elements are together, they can only be achieved together

1,2
1,3
2,3

2,3
3,4
4,5
5,6
6,2

2 and 5? I only actually need the do, the 5 adds nothing more

If I can get one member of the cycle alone, I can get them all alone

2,3
3,4
4,5
5,3

If I have one single and a chain, I can make them all single

"""

def solve():
    N, M = getInts()
    m_set = set()
    graph = dd(set)
    singles = dd(int)
    lookup = dd(int)
    nodes = set()
    for n in range(N):
        k, *a = getInts()
        if len(a) > 1:
            c, d = a[:]
            nodes.add(c)
            nodes.add(d)
            if c > d:
                c, d = d, c
            graph[c].add(d)
            graph[d].add(c)
            lookup[(c,d)] = n+1
        else:
            singles[a[0]] = n+1
            nodes.add(a[0])
    @bootstrap
    def dfs(node):
        global cycle
        nodes.remove(node)
        path.add(node)
        for neigh in graph[node]:
            if neigh not in nodes and neigh != node:
                cycle += 1
            if neigh in nodes:
                visited.append((min(node,neigh),max(node,neigh)))
                yield dfs(neigh)
        yield
    ans = []
    while nodes:
        global cycle
        visited = []
        path = set()
        cycle = 0
        node = next(iter(nodes))
        dfs(node)
        if len(path) == 1:
            x = next(iter(path))
            ans.append(singles[x])
            continue
        sing_count = 0
        for a,b in visited:
            if a in singles and not sing_count:
                ans.append(singles[a])
                sing_count += 1
            elif b in singles and not sing_count:
                ans.append(singles[b])
                sing_count += 1
            ans.append(lookup[(a,b)])
    print(pow(2,len(ans),MOD),len(ans))
    print(*sorted(ans))
    return
    
#for _ in range(getInt()):
#print(solve())
solve()


#print(time.time()-start_time)