MOD=10**9+7
import sys
input=sys.stdin.buffer.readline #FOR READING PURE INTEGER INPUTS (space separation ok)
def oneLineArrayPrint(arr):
    print(' '.join([str(x) for x in arr]))
def solveActual():
    singleBitsIdx=[None for _ in range(m)] #index of vector with bit i set as 1
    indexesHaveBeenAdded=[False for _ in range(n)]
    sPrime=[]
    
    for i in range(n):
        if len(vS[i])==1:
            setBit=vS[i][0]
            singleBitsIdx[setBit]=i
    for i in range(n):
        if len(vS[i])==1:
            setBit=vS[i][0]
            if indexesHaveBeenAdded[i]==False: #not yet added
                sPrime.append(i+1) #output 1-indexed
                indexesHaveBeenAdded[i]=True
        else:
            setBit1=vS[i][0]
            setBit2=vS[i][1]
            singleIdx1=singleBitsIdx[setBit1]
            singleIdx2=singleBitsIdx[setBit2]
            if singleIdx1==None or singleIdx2==None: #can add both this doubleIdx and singleIdx (if any is not None)
                sPrime.append(i+1)
            else:
                if not indexesHaveBeenAdded[singleIdx1]==indexesHaveBeenAdded[singleIdx2]==True:
                    sPrime.append(i+1) #at least 1 of them not used yet
                    if indexesHaveBeenAdded[singleIdx1]==indexesHaveBeenAdded[singleIdx2]==False:
                        if singleIdx1<singleIdx2: #mark the larger idx as taken so I only take the smaller one later
                            indexesHaveBeenAdded[singleIdx2]=True
                        else:
                            indexesHaveBeenAdded[singleIdx1]=True
                    else: #at least 1 of them have been used
                        indexesHaveBeenAdded[singleIdx1]=True
                        indexesHaveBeenAdded[singleIdx2]=True #set both as taken
            
    TSize=pow(2,len(sPrime),MOD)
    print('{} {}'.format(TSize,len(sPrime)))
    oneLineArrayPrint(sPrime)

def solveNaiveTest():
    from itertools import permutations
    vectors=[[0 for _ in range(m)]]
    for v in vS:
        temp=[0 for _ in range(m)]
        for i in v:
            temp[i]=1
        vectors.append(temp)
    allP=set()
    for i in range(1,n+1):
        for p in permutations(vectors,i):
            temp=[0 for _ in range(m)]
            for v in p:
                for j in range(m):
                    temp[j]+=v[j]
                    temp[j]%=2
            allP.add(tuple(temp))
    print('Naive solution')
    print('T size:{}'.format(len(allP)))
    

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:])
#solveNaiveTest()
solveActual()