#include <bits/stdc++.h>
using namespace std;
template <class T>
int size(const T& x) {
  return x.size();
}
const int INF_INT = numeric_limits<int>::max();
const long long MOD = 1000000007;
struct vec {
  int k;
  int x1, x2;
  int ind;
};
vector<int> parent;
vector<vector<int> > elems;
int find_set(int v) {
  if (v == parent[v]) return v;
  return parent[v] = find_set(parent[v]);
}
void union_sets(int a, int b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (elems[a].size() < elems[b].size()) swap(a, b);
    parent[b] = a;
    for (auto&& el : elems[b]) elems[a].push_back(el);
    elems[b].clear();
  }
}
void FEuclidsNightmare(std::istream& in, std::ostream& out) {
  int n, m;
  in >> n >> m;
  vector<vec> vecs;
  for (int i = 0; i < n; i++) {
    int k, x1, x2;
    in >> k;
    in >> x1;
    x2 = -1;
    if (k == 2) {
      in >> x2;
      if (x2 < x1) swap(x1, x2);
    }
    vecs.push_back({k, x1, x2, i + 1});
  }
  parent = vector<int>(m + 1, -1);
  elems = vector<vector<int> >(m + 1, vector<int>());
  for (int i = 0; i < m; i++) {
    parent[i + 1] = i + 1;
    elems[i + 1] = {i + 1};
  }
  vector<int> possib(m + 1, 0);
  vector<vec> basis;
  for (vec cvec : vecs) {
    if (cvec.k == 1) {
      if (!possib[cvec.x1]) {
        possib[cvec.x1] = 1;
        basis.push_back(cvec);
        if (find_set(cvec.x1) != -1) {
          for (auto&& el : elems[cvec.x1]) possib[el] = 1;
        }
      }
    } else {
      assert(cvec.k == 2);
      if ((possib[cvec.x1] && !possib[cvec.x2]) ||
          (!possib[cvec.x1] && possib[cvec.x2])) {
        possib[cvec.x1] = possib[cvec.x2] = 1;
        basis.push_back(cvec);
        for (int i = 0; i < 2; i++) {
          int tx1 = cvec.x1;
          if (i == 1) tx1 = cvec.x2;
          if (find_set(cvec.x1) != -1) {
            for (auto&& el : elems[cvec.x1]) possib[el] = 1;
          }
        }
      } else if (!possib[cvec.x1] && !possib[cvec.x2]) {
        if (find_set(cvec.x1) != find_set(cvec.x2)) basis.push_back(cvec);
        union_sets(cvec.x1, cvec.x2);
      }
    }
  }
  long long sz = 1;
  for (int i = 0; i < basis.size(); i++) {
    sz *= 2ll;
    sz %= MOD;
  }
  out << sz << " " << basis.size() << endl;
  for (auto&& el : basis) out << el.ind << " ";
  out << endl;
}
struct Solver {
  void solve(std::istream& in, std::ostream& out) {
    return FEuclidsNightmare(in, out);
  }
};
int main() {
  std::ios_base::sync_with_stdio(false), std::cin.tie(NULL),
      std::cout.tie(NULL);
  Solver solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  return 0;
}
