#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
struct DSU {
  vector<int> mark;
  vector<int> sz;
  vector<int> p;
  DSU(int n) {
    mark.resize(n + 1);
    sz.resize(n + 1, 1);
    p.resize(n + 1);
    for (int i = 1; i <= n; i++) p[i] = i;
  }
  int find_root(int a) {
    if (p[a] == a) return a;
    p[a] = find_root(p[a]);
    mark[a] = mark[p[a]];
    return p[a];
  }
  bool union_set(int a, int b) {
    a = find_root(a);
    b = find_root(b);
    if (a == b) return false;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
    if (mark[b]) mark[a] = 1;
    return true;
  }
};
long long visited_count = 0;
int dfs(vector<vector<pair<int, int>>> &gr, vector<int> &used,
        vector<int> &special, vector<pair<int, pair<int, int>>> &edge, int s) {
  used[s] = 1;
  visited_count++;
  int res = special[s];
  if (special[s] != INT_MAX)
    edge.push_back(make_pair(special[s], make_pair(s, s)));
  for (int i = 0; i < gr[s].size(); i++) {
    int v = gr[s][i].first, w = gr[s][i].second;
    if (!used[v]) {
      edge.push_back(make_pair(w, make_pair(s, v)));
      res = min(res, dfs(gr, used, special, edge, v));
    }
  }
  return res;
}
int main() {
  cin.tie(NULL);
  cout.tie(NULL);
  ios_base ::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<int> special(m + 1, INT_MAX);
  vector<vector<pair<int, int>>> gr(m + 1);
  for (int i = 1; i <= n; i++) {
    int k;
    cin >> k;
    if (k == 1) {
      int ver;
      cin >> ver;
      special[ver] = i;
    } else {
      int u, v;
      cin >> u >> v;
      gr[u].push_back(make_pair(v, i));
      gr[v].push_back(make_pair(u, i));
    }
  }
  long long cardT = 1;
  vector<int> subS;
  vector<int> used(m + 1);
  DSU syst(m);
  for (int i = 1; i <= m; i++) {
    if (used[i]) continue;
    int old = visited_count;
    vector<pair<int, pair<int, int>>> edge;
    int sp = dfs(gr, used, special, edge, i);
    int vis = visited_count - old;
    if (sp == INT_MAX) vis--;
    for (int j = 0; j < vis; j++) cardT = (cardT * 2LL) % mod;
    sort(edge.begin(), edge.end());
    if (sp == INT_MAX) {
      for (int j = 0; j < edge.size(); j++) {
        if (syst.union_set(edge[j].second.first, edge[j].second.second)) {
          subS.push_back(edge[j].first);
        }
      }
    } else {
      for (int j = 0; j < edge.size(); j++) {
        if (edge[j].second.first == edge[j].second.second) {
          int ver = edge[j].second.first;
          if (!syst.mark[syst.find_root(ver)]) {
            syst.mark[syst.find_root(ver)] = 1;
            subS.push_back(edge[j].first);
          }
        } else {
          int u = edge[j].second.first, v = edge[j].second.second;
          if (syst.mark[syst.find_root(u)] && syst.mark[syst.find_root(v)] ||
              syst.find_root(u) == syst.find_root(v))
            continue;
          syst.union_set(u, v);
          subS.push_back(edge[j].first);
        }
      }
    }
  }
  sort(subS.begin(), subS.end());
  cout << cardT << ' ' << subS.size() << '\n';
  for (int i = 0; i < subS.size(); i++) cout << subS[i] << ' ';
}
