#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
struct Edge {
  int to, id;
  Edge(int to = 0, int id = 0) : to(to), id(id) {}
};
vector<int> basis;
struct DSU {
  int n;
  vector<int> p, clr;
  DSU(int n) : n(n), p(n), clr(n) {
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int get(int x) {
    if (p[x] == x) return x;
    get(p[x]);
    clr[x] ^= clr[p[x]];
    p[x] = p[p[x]];
    return p[x];
  }
  int getColor(int x) {
    get(x);
    return clr[x];
  }
  void unite(int a, int b) {
    int ra = get(a);
    int rb = get(b);
    clr[ra] = 1 ^ getColor(a) ^ getColor(b);
    p[ra] = rb;
    assert(getColor(a) != getColor(b));
  }
};
long long qpowmod(long long a, long long b, long long mod) {
  long long res = 1;
  while (b) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return res;
}
int main() {
  int n, m;
  scanf("%d%d", &m, &n);
  DSU dsu(n + 1);
  for (int i = 0; i < m; i++) {
    int cnt;
    scanf("%d", &cnt);
    assert(cnt == 1 || cnt == 2);
    if (cnt == 1) {
      int x;
      scanf("%d", &x);
      if (dsu.get(x) != dsu.get(0)) {
        dsu.unite(x, 0);
        basis.push_back(i + 1);
      }
    } else {
      int x, y;
      scanf("%d%d", &x, &y);
      assert(x != y);
      if (dsu.get(x) != dsu.get(y)) {
        dsu.unite(x, y);
        basis.push_back(i + 1);
      } else if (dsu.get(x) != dsu.get(0) &&
                 dsu.getColor(x) == dsu.getColor(y)) {
        dsu.unite(x, 0);
        basis.push_back(i + 1);
      }
    }
  }
  printf("%lld %d\n", qpowmod(2, basis.size(), MOD), (int)basis.size());
  sort(basis.begin(), basis.end());
  for (int x : basis) {
    printf("%d ", x);
  }
  puts("");
}
