from collections import defaultdict
MOD=10**9+7
import sys
input=sys.stdin.buffer.readline #FOR READING PURE INTEGER INPUTS (space separation ok)
class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
    def find(self, a): #return parent of a. a and b are in same set if they have same parent
        acopy = a
        while a != self.parent[a]:
            a = self.parent[a]
        while acopy != a: #path compression
            self.parent[acopy], acopy = a, self.parent[acopy]
        return a
    def union(self, a, b): #union a and b
        self.parent[self.find(b)] = self.find(a)

def oneLineArrayPrint(arr):
    print(' '.join([str(x+1) for x in arr]))
def solveActual():
    uf=UnionFind(m)
    
    for i,x in enumerate(vS): #idx,vertex(vertices)
        if len(x)==2:
            v1,v2=x
            uf.union(v1,v2)
            
    componentEdges=defaultdict(lambda:list()) #componentEdges[parent]=[all component edges]
    componentVertices=defaultdict(lambda:set()) #componentVertices[parent]={all component vertices}
    componentHasOne=[False for _ in range(m)]
#    componentHasOne[parent]=True if at least 1 of the component has an edge leading to itself
#    an edge leads to itself if it only has 1 set bit
    allParents=set()
    for i,x in enumerate(vS):
        parent=uf.find(x[0])
        allParents.add(parent)
        componentEdges[parent].append(i)
        if len(x)==1:
            componentVertices[parent].add(x[0])
            componentHasOne[parent]=True
        else:
            componentVertices[parent].add(x[0])
            componentVertices[parent].add(x[1])
    
    #each component has k vertices.
    #each component shall have at most k-1 useful edges if componentHasOne==False, or k edges if it's True
    #pick the k-1 or k edges with the smallest values
    #each component contributes independently 2**(nEdges) to the number of ways.
    #just find 2**(nEdges or number of included indexes)
    
    sPrime=[]
    for parent in allParents:
        edges=sorted(componentEdges[parent])
        nVertices=len(componentVertices[parent])
        if componentHasOne[parent]:
            maxEdges=nVertices
        else:
            maxEdges=nVertices-1
        edgeCnt=0
        for edge in edges:
            sPrime.append(edge)
            edgeCnt+=1
            if edgeCnt==maxEdges:
                break
    sPrime.sort()
    
    TSize=pow(2,len(sPrime),MOD)
    print('{} {}'.format(TSize,len(sPrime)))
    oneLineArrayPrint(sPrime)


n,m=[int(x) for x in input().split()]
vS=[] #0-indexed

for _ in range(n):
    xx=[int(x) for x in input().split()]
    #number of 1s, coordinates with 1s
    for i in range(1,len(xx)):
        xx[i]-=1 #0-index
    vS.append(xx[1:])
solveActual()