#include <bits/stdc++.h>
using namespace std;
const size_t MAX_N = 1e5 + 5;
const int MOD = 1e9 + 7;
struct edge {
  int to, n1, n2;
  edge() {}
  edge(int to, int n1, int n2) : to(to), n1(n1), n2(n2) {}
};
vector<edge> g[MAX_N];
int dp[MAX_N][2][2][2];
int self[MAX_N][2], res[2];
bool used[MAX_N];
inline void add(int &dp, int val) {
  dp += val;
  if (dp >= MOD) dp -= MOD;
}
void dfs(int v) {
  used[v] = true;
  bool nxt = false;
  for (auto &e : g[v]) {
    if (used[e.to]) continue;
    nxt = true;
    dfs(e.to);
    int u = e.to, n1 = e.n1, n2 = e.n2;
    for (int i = 0; i < 2; ++i)
      for (int j = 0; j < 2; ++j)
        for (int k = 0; k < 2; ++k)
          for (int l = 0; l < 2; ++l)
            add(dp[v][i ^ ((j ^ n1) | (k ^ n2)) ^ self[v][j]][j][l],
                dp[u][i][k][l]);
  }
  if (!nxt) dp[v][self[v][0]][0][0] = dp[v][self[v][1]][1][1] = 1;
}
inline void upd(int v, int n1 = -1, int n2 = -1) {
  dfs(v);
  static long long r[2], d[2];
  r[0] = res[0];
  r[1] = res[1];
  d[0] = d[1] = 0;
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      for (int k = 0; k < 2; ++k)
        d[i ^ ((~n1 ? (j ^ n1) : 0) | (~n2 ? (k ^ n2) : 0))] += dp[v][i][j][k];
  res[0] = res[1] = 0;
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j) add(res[i ^ j], r[i] * d[j] % MOD);
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0, k; i < n; ++i) {
    scanf("%d", &k);
    if (k == 1) {
      int a;
      scanf("%d", &a);
      (a < 0 ? self[-a][0] : self[a][1]) = true;
    } else {
      int a1, a2, n1 = 0, n2 = 0;
      scanf("%d%d", &a1, &a2);
      if (a1 < 0) n1 = 1, a1 *= -1;
      if (a2 < 0) n2 = 1, a2 *= -1;
      g[a1].emplace_back(a2, n1, n2);
      g[a2].emplace_back(a1, n2, n1);
    }
  }
  res[0] = 1;
  for (int i = 1; i <= m; ++i)
    if (!used[i] && g[i].size() <= 1) upd(i);
  for (int i = 1; i <= m; ++i)
    if (!used[i]) upd(i, g[i][1].n1, g[i][1].n2);
  cout << res[1] << '\n';
  return 0;
}
