#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
int val[(100100 + 10)][2], num[(100100 + 10)];
int fst[(100100 + 10)], vv[(300050)], nxt[(300050)], e;
int dp[(100100 + 10)][2][2], f[(100100 + 10)][2], g[(100100 + 10)][2];
int pre[(100100 + 10)];
bool vis[(100100 + 10)];
bool mark[(300050)];
int cir[(100100 + 10)], ccnt, path[(100100 + 10)], pcnt;
int ep;
vector<int> node;
void init() {
  memset(fst, -1, sizeof fst);
  memset(pre, -1, sizeof pre);
  e = 0;
}
void adde(int u, int v) { vv[e] = v, nxt[e] = fst[u], fst[u] = e++; }
bool dfs(int u) {
  vis[u] = 1;
  int child = 0;
  for (int i = fst[u]; ~i; i = nxt[i]) {
    if (mark[i]) continue;
    mark[i] = mark[i ^ 1] = 1;
    int v = vv[i];
    if (vis[v]) return 1;
    if (dfs(v)) return 1;
    ++child;
  }
  if (child == 0) ep = u;
  return 0;
}
void add(int &u, int v) {
  u += v;
  if (u >= 1000000007) u -= 1000000007;
}
void solve(int id, vector<int> node, int in_cir) {
  if (!in_cir) {
    dp[0][1][0] = 1, dp[0][0][0] = 1;
  } else {
    memset(dp[0], 0, sizeof dp[0]);
    dp[0][in_cir - 1][0] = 1;
  }
  int lastv, nxtv, st = node[0];
  if (num[st] == 1)
    st = abs(val[st][0]);
  else {
    lastv = abs(val[st][0]);
    if (node.size() > 1) {
      int tmp = node[1];
      for (int j = 0; j < num[tmp]; ++j)
        if (lastv == abs(val[tmp][j])) {
          lastv = abs(val[st][1]);
          break;
        }
    }
  }
  int sz = node.size();
  for (int i = 0; i < sz; ++i) {
    memset(dp[i + 1], 0, sizeof dp[i + 1]);
    int u = node[i];
    if (num[u] == 1) {
      nxtv = lastv;
      for (int pj = 0; pj < 2; ++pj)
        for (int pk = 0; pk < 2; ++pk) {
          int k = pj ^ (val[u][0] < 0) ^ pk;
          add(dp[i + 1][pj][k], dp[i][pj][pk]);
        }
    } else {
      int id = 0;
      if (abs(val[u][id]) != lastv) id ^= 1;
      nxtv = abs(val[u][id ^ 1]);
      for (int pj = 0; pj < 2; ++pj)
        for (int pk = 0; pk < 2; ++pk)
          for (int j = 0; j < 2; ++j) {
            int k = (pj ^ (val[u][id] < 0)) | (j ^ (val[u][id ^ 1] < 0));
            k ^= pk;
            add(dp[i + 1][j][k], dp[i][pj][pk]);
          }
    }
    lastv = nxtv;
  }
  if (!in_cir) {
    for (int j = 0; j < 2; ++j)
      add(f[id][0], dp[sz][j][0]), add(f[id][1], dp[sz][j][1]);
  } else {
    add(f[id][0], dp[sz][in_cir - 1][0]);
    add(f[id][1], dp[sz][in_cir - 1][1]);
  }
}
void gao(int u) {
  vis[u] = 1;
  node.push_back(u);
  for (int i = fst[u]; ~i; i = nxt[i]) {
    int v = vv[i];
    if (vis[v]) continue;
    gao(v);
  }
}
int main() {
  int n, m;
  scanf("%d%d", &m, &n);
  init();
  for (int i = 1; i <= m; ++i) {
    scanf("%d", &num[i]);
    for (int j = 0; j < num[i]; ++j) {
      scanf("%d", &val[i][j]);
      int t = abs(val[i][j]);
      if (pre[t] == -1)
        pre[t] = i;
      else
        adde(pre[t], i), adde(i, pre[t]);
    }
  }
  int free = 0;
  for (int i = 1; i <= n; ++i)
    if (pre[i] == -1) free++;
  for (int i = 1; i <= m; ++i) {
    if (!vis[i]) {
      ep = -1;
      if (dfs(i)) {
        cir[ccnt++] = i;
      } else
        path[pcnt++] = ep;
    }
  }
  memset(vis, 0, sizeof vis);
  for (int i = 0; i < pcnt; ++i) {
    node.clear();
    gao(path[i]);
    solve(i, node, 0);
  }
  for (int i = 0; i < ccnt; ++i) {
    node.clear();
    gao(cir[i]);
    solve(i + pcnt, node, 1);
    solve(i + pcnt, node, 2);
  }
  g[0][0] = 1;
  for (int i = 1; i <= pcnt + ccnt; ++i) {
    add(g[i][0], (long long)g[i - 1][0] * f[i - 1][0] % 1000000007);
    add(g[i][0], (long long)g[i - 1][1] * f[i - 1][1] % 1000000007);
    add(g[i][1], (long long)g[i - 1][1] * f[i - 1][0] % 1000000007);
    add(g[i][1], (long long)g[i - 1][0] * f[i - 1][1] % 1000000007);
  }
  int tot = pcnt + ccnt;
  for (int i = 0; i < free; ++i)
    g[tot][1] = (long long)g[tot][1] * 2 % 1000000007;
  printf("%d\n", g[tot][1]);
}
