#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int INF = 1E9;
const int MAXN = 100500;
const int MOD = (int)1E9 + 7;
void add(int &x, int y) {
  x += y;
  if (x >= MOD) x -= MOD;
}
int n, m;
vector<int> a[MAXN];
vector<int> where[MAXN];
int used[MAXN], useda[MAXN];
int put[MAXN];
int ans, mult;
vector<int> st[2], sgn[2];
vector<int> cur[2], dp[2];
vector<int> f[2][2][2];
int collect[2];
vector<int> indexes;
void add() {
  assert(st[0].size() >= 1);
  assert(st[0].size() == st[1].size());
  for (int i = 0; i < (int)(2); i++) {
    sgn[i].clear();
    sgn[i].resize(st[i].size(), 0);
    for (int j = 0; j < (int)(st[i].size()); j++)
      if (st[i][j] < 0) {
        sgn[i][j] = 1;
        st[i][j] *= -1;
      }
  }
  int curAns[2], tmpAns[2];
  for (int i = 0; i < (int)(2); i++) curAns[i] = 0;
  for (int v1 = 0; v1 < (int)(2); v1++)
    for (int v2 = 0; v2 < (int)(2); v2++) {
      for (int i = 0; i < (int)(2); i++)
        for (int j = 0; j < (int)(st[i].size()); j++) put[st[i][j]] = -1;
      if (st[0][0] == 0 && v1) continue;
      if (st[1][0] == 0 && v2) continue;
      put[st[0][0]] = v1;
      if (put[st[1][0]] != -1 && put[st[1][0]] != v2) continue;
      put[st[1][0]] = v2;
      for (int i = 0; i < (int)(2); i++)
        for (int j = 0; j < (int)(2); j++)
          for (int k = 0; k < (int)(2); k++) {
            f[i][j][k].clear();
            f[i][j][k].resize(st[0].size(), 0);
          }
      f[v1][v2][(sgn[0][0] ^ v1) || (sgn[1][0] ^ v2)][0] = 1;
      for (int i = 0; i < (int)st[0].size() - 1; i++) {
        for (int l1 = 0; l1 < (int)(2); l1++)
          for (int l2 = 0; l2 < (int)(2); l2++)
            for (int res = 0; res < (int)(2); res++)
              if (f[l1][l2][res][i]) {
                put[st[0][i]] = l1;
                put[st[1][i]] = l2;
                for (int w1 = 0; w1 < (int)(2); w1++)
                  for (int w2 = 0; w2 < (int)(2); w2++) {
                    if (put[st[0][i + 1]] != -1 && put[st[0][i + 1]] != w1)
                      continue;
                    if (put[st[1][i + 1]] != -1 && put[st[1][i + 1]] != w2)
                      continue;
                    if (st[0][i + 1] == 0 && w1) continue;
                    if (st[1][i + 1] == 0 && w2) continue;
                    add(f[w1][w2][res ^ ((sgn[0][i + 1] ^ w1) ||
                                         (sgn[1][i + 1] ^ w2))][i + 1],
                        f[l1][l2][res][i]);
                  }
              }
      }
      for (int i = 0; i < (int)(2); i++) tmpAns[i] = 0;
      for (int l1 = 0; l1 < (int)(2); l1++)
        for (int l2 = 0; l2 < (int)(2); l2++)
          for (int res = 0; res < (int)(2); res++)
            add(tmpAns[res], f[l1][l2][res][st[0].size() - 1]);
      for (int i = 0; i < (int)(2); i++) {
        add(curAns[i], tmpAns[i]);
      }
    }
  for (int i = 0; i < (int)(2); i++) {
    cur[i].push_back(curAns[i]);
  }
}
void dfs1(int id, int v) {
  useda[id] = 1;
  used[v] = 1;
  assert(!where[v].empty());
  for (int i = 0; i < (int)(a[id].size()); i++) st[i].push_back(a[id][i]);
  if (st[0].size() > st[1].size()) st[1].push_back(0);
  for (auto ww : a[id]) {
    int w = abs(ww);
    if (!used[w]) {
      used[w] = 1;
      for (auto id2 : where[w])
        if (!useda[id2]) dfs1(id2, w);
    }
  }
  for (auto id2 : where[v]) {
    if (!useda[id2]) {
      dfs1(id2, v);
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < (int)(n); i++) {
    int k;
    scanf("%d", &k);
    a[i].resize(k);
    for (int j = 0; j < (int)(k); j++) {
      scanf("%d", &a[i][j]);
      where[abs(a[i][j])].push_back(i);
    }
  }
  mult = 1;
  for (int i = (int)(1); i < (int)(m + 1); i++)
    if (where[i].empty()) {
      used[i] = 1;
      mult = (mult * 2) % MOD;
    }
  for (int i = (int)(1); i < (int)(m + 1); i++)
    if (!used[i]) {
      for (int j = 0; j < (int)(2); j++) st[j].clear();
      for (auto id : where[i]) {
        if (!useda[id]) {
          dfs1(id, i);
        }
      }
      add();
    }
  for (int i = 0; i < (int)(2); i++) dp[i].resize(cur[i].size() + 1, 0);
  dp[0][0] = 1;
  dp[1][0] = 0;
  for (int i = 0; i < (int)cur[0].size(); i++) {
    for (int f = 0; f < (int)(2); f++)
      for (int nf = 0; nf < (int)(2); nf++)
        add(dp[f ^ nf][i + 1], 1ll * dp[f][i] * cur[nf][i] % MOD);
  }
  ans = dp[1][cur[0].size()];
  ans = (1ll * ans * mult) % MOD;
  cout << ans << '\n';
  return 0;
}
