#include <bits/stdc++.h>
using namespace std;
struct DisjointSet {
  vector<int> f, sz;
  DisjointSet(int size) {
    f.resize(size);
    sz.resize(size);
    for (int i = 0; i < size; i++) {
      f[i] = i;
      sz[i] = i;
    }
  }
  int father(int src) {
    if (src == f[src]) return src;
    return f[src] = father(f[src]);
  }
  bool unite(int a, int b) {
    int fa = father(a), fb = father(b);
    if (sz[fa] < sz[fb]) swap(fa, fb);
    if (fa == fb) return false;
    f[fb] = fa;
    sz[fa] = max(sz[fa], sz[fb] + 1);
    return true;
  }
};
const int sz = 5e5;
int n, m;
bitset<sz> used, unit;
vector<pair<int, int> > adj[sz];
void dfs(int src) {
  unit[src] = 1;
  for (pair<int, int> x : adj[src]) {
    if (!unit[x.first]) dfs(x.first);
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  DisjointSet dsu(m);
  for (int i = 0; i < n; i++) {
    int x, a, b;
    cin >> x;
    if (x == 1) {
      cin >> a;
      if (!unit[a]) {
        dfs(--a);
        used[i] = 1;
      }
    } else {
      cin >> a >> b;
      --a;
      --b;
      if (unit[a] && unit[b])
        continue;
      else if (unit[a] ^ unit[b]) {
        used[i] = 1;
        dsu.unite(a, b);
        dfs(a);
        dfs(b);
      } else {
        if (dsu.unite(a, b)) used[i] = 1;
      }
    }
  }
  long long tot = 1, cnt = used.count();
  for (int i = 0; i < cnt; i++) {
    tot <<= 1;
    tot %= ((long long)(1e9 + 7));
  }
  cout << tot << ' ' << cnt << '\n';
  for (int i = 0; i < n; i++) {
    if (used[i]) cout << i + 1 << ' ';
  }
  cout << '\n';
  return 0;
}
