#include <bits/stdc++.h>
int n, m;
std::vector<int> vec[500010], ans;
bool ncon[500010];
int par[500010];
int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
void dfs(int x, int fa) {
  ncon[x] = true;
  for (auto y : vec[x]) {
    if (y != fa) dfs(y, x);
  }
}
long long qpow(long long a, long long b) {
  a %= 1000000007;
  long long res = 1;
  for (; b > 0; b >>= 1) {
    if (b & 1) res = res * a % 1000000007;
    a = a * a % 1000000007;
  }
  return res;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; ++i) par[i] = i;
  for (int i = 1, k, x, y; i <= n; ++i) {
    scanf("%d", &k);
    if (k == 1) {
      scanf("%d", &x);
      if (!ncon[x]) {
        ncon[x] = true;
        ans.push_back(i);
      }
    } else {
      scanf("%d %d", &x, &y);
      if (ncon[x]) {
        if (!ncon[y]) {
          dfs(y, -1);
          ans.push_back(i);
        }
      } else if (ncon[y]) {
        dfs(x, -1);
        ans.push_back(i);
      } else {
        int fx = find(x), fy = find(y);
        if (fx != fy) {
          par[fx] = fy;
          vec[x].push_back(y);
          vec[y].push_back(x);
          ans.push_back(i);
        }
      }
    }
  }
  printf("%lld %d\n", qpow(2, (long long)ans.size()), (int)ans.size());
  for (auto x : ans) printf("%d ", x);
  return 0;
}
