#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  for (int i = 0; i < (int)v.size(); i++) {
    cout << v[i] << ' ';
  }
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& v) {
  for (auto& i : v) {
    cout << i << " ";
  }
  cout << endl;
  return os;
}
const int MAXN = 5e5 + 5;
int parent[MAXN];
int singlenode[MAXN];
void make_set(int v) {
  for (int i = 0; i < MAXN; ++i) parent[i] = i;
}
int find_set(int v) {
  parent[v] = parent[parent[v]];
  if (v == parent[v]) return v;
  return find_set(parent[v]);
}
void union_sets(int a, int b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    parent[b] = a;
    if (singlenode[b] < singlenode[a]) {
      singlenode[a] = singlenode[b];
      singlenode[b] = 0;
    } else {
      singlenode[b] = 0;
    }
  }
}
long long modpow(long long base, long long pow, long long mod) {
  base %= mod;
  long long res = 1;
  for (; pow; pow >>= 1) {
    if (pow & 1) res = res * base % mod;
    base = base * base % mod;
  }
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  vector<pair<int, int> > singles;
  vector<pair<int, pair<int, int> > > dub;
  for (int i = 0; i < n; ++i) {
    int amt;
    cin >> amt;
    if (amt == 1) {
      int a;
      cin >> a;
      a--;
      singles.push_back(pair<int, int>(i + 1, a));
    } else {
      int a, b;
      cin >> a >> b;
      a--, b--;
      dub.push_back(pair<int, pair<int, int> >(i + 1, pair<int, int>(a, b)));
    }
  }
  make_set(MAXN);
  vector<int> basis;
  int ite1 = 0, ite2 = 0;
  for (int i = 0; i < n; ++i) {
    int id1 = 1000005000, id2 = 1000005000;
    if (ite1 < (int)singles.size()) id1 = singles[ite1].first;
    if (ite2 < (int)dub.size()) id2 = dub[ite2].first;
    if (id1 < id2) {
      int p = find_set(singles[ite1].second);
      if (singlenode[p] == 0) {
        singlenode[p] = singles[ite1].first;
      }
      ite1++;
    } else {
      int a = dub[ite2].second.first;
      int b = dub[ite2].second.second;
      if (find_set(a) != find_set(b) &&
          (singlenode[a] == 0 || singlenode[b] == 0)) {
        union_sets(a, b);
        basis.push_back(dub[ite2].first);
      }
      ite2++;
    }
  }
  for (int i = 0; i < MAXN; ++i)
    if (singlenode[i]) basis.push_back(singlenode[i]);
  sort(begin(basis), end(basis));
  long long used = (int)basis.size();
  const long long mod = 1e9 + 7;
  long long power = modpow(2ll, used, mod);
  cout << power << " " << used << endl;
  cout << basis << endl;
}
