#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
int n, m;
int clauses[123123][2];
vector<int> uses[123123];
bool vis[123123];
vector<int> chain[123123];
int counter;
vector<pair<long long, long long>> dips;
long long ans;
int rightc(int cnr) {
  int xnr = abs(clauses[cnr][1]);
  if (uses[xnr].size() == 2) {
    return uses[xnr][0] == cnr ? uses[xnr][1] : uses[xnr][0];
  } else {
    return 0;
  }
}
void load() {
  cin >> n >> m;
  int k;
  for (int i = 1; i <= n; ++i) {
    cin >> k;
    for (int j = 0; j < k; ++j) {
      cin >> clauses[i][j];
      uses[abs(clauses[i][j])].push_back(i);
    }
  }
}
void dfs(int cnr, int from) {
  if (vis[cnr]) {
    return;
  }
  vis[cnr] = 1;
  if (abs(clauses[cnr][1]) == from) {
    swap(clauses[cnr][0], clauses[cnr][1]);
  }
  chain[counter].push_back(cnr);
  dfs(rightc(cnr), abs(clauses[cnr][1]));
}
void dfs2(int cnr, int from, int f) {
  if (vis[cnr]) {
    return;
  }
  vis[cnr] = 1;
  if (!clauses[cnr][1]) {
    if (!f) {
      swap(clauses[cnr][0], clauses[cnr][1]);
    }
  } else {
    if (abs(clauses[cnr][1]) == from) {
      swap(clauses[cnr][0], clauses[cnr][1]);
    }
  }
  chain[counter].push_back(cnr);
  dfs2(rightc(cnr), abs(clauses[cnr][1]), 1);
}
void buildChains() {
  vis[0] = 1;
  for (int i = 1; i <= m; ++i)
    if (uses[i].size() == 1 && !vis[uses[i][0]]) {
      dfs(uses[i][0], i);
      ++counter;
    }
  for (int i = 1; i <= m; ++i)
    if (uses[i].size() == 2) {
      if (!vis[uses[i][0]] && !clauses[uses[i][0]][1]) {
        dfs2(uses[i][0], i, 0);
        ++counter;
      }
      if (!vis[uses[i][1]] && !clauses[uses[i][1]][1]) {
        dfs2(uses[i][1], i, 0);
        ++counter;
      }
    }
  for (int i = 1; i <= n; ++i)
    if (!vis[i]) {
      dfs(i, abs(clauses[i][0]));
      ++counter;
    }
}
long long dp[123123][2][2][2];
int val(int i, int j, int nr) {
  int v1 = i;
  if (clauses[nr][0] < 0) {
    v1 = 1 - v1;
  }
  if (clauses[nr][0] == 0) {
    v1 = 0;
  }
  int v2 = j;
  if (clauses[nr][1] < 0) {
    v2 = 1 - v2;
  }
  if (clauses[nr][1] == 0) {
    v2 = 0;
  }
  return (v1 | v2);
}
void cleaar(int si) {
  for (int i = 0; i < si; ++i)
    for (int j = 0; j < 2; ++j)
      for (int l = 0; l < 2; ++l)
        for (int k = 0; k < 2; ++k) dp[i][j][l][k] = 0;
}
void consider(int nr) {
  if (chain[nr].size() == 1 &&
      abs(clauses[chain[nr][0]][0]) == abs(clauses[chain[nr][0]][1])) {
    if (clauses[chain[nr][0]][0] == clauses[chain[nr][0]][1]) {
      dips.push_back(make_pair(1, 1));
    } else {
      dips.push_back(make_pair(0, 2));
    }
    return;
  }
  cleaar(chain[nr].size());
  int fi = chain[nr][0];
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j) dp[0][i][j][val(i, j, fi)] = 1;
  for (int i = 0; i < chain[nr].size() - 1; ++i)
    for (int j = 0; j < 2; ++j)
      for (int l = 0; l < 2; ++l)
        for (int k = 0; k < 2; ++k) {
          dp[i + 1][j][0][val(l, 0, chain[nr][i + 1]) ^ k] += dp[i][j][l][k];
          dp[i + 1][j][0][val(l, 0, chain[nr][i + 1]) ^ k] %= mod;
          dp[i + 1][j][1][val(l, 1, chain[nr][i + 1]) ^ k] += dp[i][j][l][k];
          dp[i + 1][j][1][val(l, 1, chain[nr][i + 1]) ^ k] %= mod;
        }
  int si = chain[nr].size();
  if (!clauses[chain[nr][0]][0] && !clauses[chain[nr][si - 1]][1]) {
    dips.push_back(make_pair(dp[si - 1][0][0][0], dp[si - 1][0][0][1]));
    return;
  }
  if (!clauses[chain[nr][si - 1]][1]) {
    long long r0 = (dp[si - 1][0][0][0] + dp[si - 1][1][0][0]) % mod;
    long long r1 = (dp[si - 1][0][0][1] + dp[si - 1][1][0][1]) % mod;
    dips.push_back(make_pair(r0, r1));
    return;
  }
  if (abs(clauses[chain[nr][0]][0]) != abs(clauses[chain[nr][si - 1]][1])) {
    long long r0 = (dp[si - 1][0][0][0] + dp[si - 1][1][1][0] +
                    dp[si - 1][0][1][0] + dp[si - 1][1][0][0]) %
                   mod;
    long long r1 = (dp[si - 1][0][0][1] + dp[si - 1][1][1][1] +
                    dp[si - 1][0][1][1] + dp[si - 1][1][0][1]) %
                   mod;
    dips.push_back(make_pair(r0, r1));
    return;
  }
  long long r0 = (dp[si - 1][0][0][0] + dp[si - 1][1][1][0]) % mod;
  long long r1 = (dp[si - 1][0][0][1] + dp[si - 1][1][1][1]) % mod;
  dips.push_back(make_pair(r0, r1));
}
void makeAns() {
  long long a = dips[0].first;
  long long b = dips[0].second;
  for (int i = 1; i < counter; ++i) {
    long long c = (a * dips[i].first + b * dips[i].second) % mod;
    long long d = (a * dips[i].second + b * dips[i].first) % mod;
    a = c;
    b = d;
  }
  ans = b;
  for (int i = 1; i <= m; ++i)
    if (uses[i].empty()) {
      ans *= 2;
      ans %= mod;
    }
}
void debug() {
  return;
  for (int i = 0; i < counter; ++i) {
    cerr << i << " : ";
    for (int ind : chain[i]) {
      cerr << "(" << clauses[ind][0] << ", " << clauses[ind][1] << ") ";
    }
    cerr << endl;
  }
  for (auto tmp : dips) {
    cerr << tmp.first << " " << tmp.second << endl;
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  load();
  buildChains();
  for (int i = 0; i < counter; ++i) {
    consider(i);
  }
  debug();
  makeAns();
  cout << ans << endl;
}
