#include <bits/stdc++.h>
using namespace std;
long long RES[2], NW[2], NN[2];
int k[100020];
int a[100020][2];
int ST, IS, NO;
vector<int> g[100020];
vector<int> vec[100020];
bool f[100020];
void solve1(int p, int u, int to, long long RES00, long long RES01,
            long long RES10, long long RES11) {
  f[u] = 1;
  if (abs(a[u][0]) == to && a[u][0] < 0) {
    swap(RES00, RES10);
    swap(RES01, RES11);
  }
  if (k[u] == 2 && abs(a[u][1]) == to && a[u][1] < 0) {
    swap(RES00, RES10);
    swap(RES01, RES11);
  }
  long long NEW00, NEW01, NEW10, NEW11;
  if (k[u] == 1) {
    NEW00 = (RES00) % 1000000007;
    NEW01 = (RES01) % 1000000007;
    NEW10 = (RES11) % 1000000007;
    NEW11 = (RES10) % 1000000007;
    if (a[u][0] < 0) {
      swap(NEW00, NEW10);
      swap(NEW01, NEW11);
    }
  } else {
    NEW00 = (RES00 + RES11) % 1000000007;
    NEW01 = (RES10 + RES01) % 1000000007;
    NEW10 = (RES01 + RES11) % 1000000007;
    NEW11 = (RES00 + RES10) % 1000000007;
    if (abs(a[u][0]) != to && a[u][0] < 0) {
      swap(NEW00, NEW10);
      swap(NEW01, NEW11);
    }
    if (abs(a[u][1]) != to && a[u][1] < 0) {
      swap(NEW00, NEW10);
      swap(NEW01, NEW11);
    }
  }
  int nxtvec = vec[u][0];
  if (vec[u].size() == 2 && nxtvec == p) nxtvec = vec[u][1];
  if (nxtvec == p) {
    NW[0] = (RES[0] * (NEW10 + NEW00) % 1000000007 +
             RES[1] * (NEW11 + NEW01) % 1000000007) %
            1000000007;
    NW[1] = (RES[0] * (NEW11 + NEW01) % 1000000007 +
             RES[1] * (NEW10 + NEW00) % 1000000007) %
            1000000007;
    RES[0] = NW[0];
    RES[1] = NW[1];
    return;
  }
  int nxt = abs(a[u][0]);
  if (k[u] == 2 && to == nxt) nxt = abs(a[u][1]);
  solve1(u, nxtvec, nxt, NEW00, NEW01, NEW10, NEW11);
}
void solve2(int p, int u, int to, long long RES00, long long RES01,
            long long RES10, long long RES11) {
  if (u == ST) {
    NO++;
  }
  f[u] = 1;
  if (NO == 2) {
    if (IS) {
      NN[0] = (NN[0] + RES10) % 1000000007;
      NN[1] = (NN[1] + RES11) % 1000000007;
    } else {
      NN[0] = (NN[0] + RES00) % 1000000007;
      NN[1] = (NN[1] + RES01) % 1000000007;
    }
    return;
  }
  if (abs(a[u][0]) == to && a[u][0] < 0) {
    swap(RES00, RES10);
    swap(RES01, RES11);
  }
  if (k[u] == 2 && abs(a[u][1]) == to && a[u][1] < 0) {
    swap(RES00, RES10);
    swap(RES01, RES11);
  }
  long long NEW00, NEW01, NEW10, NEW11;
  NEW00 = (RES00 + RES11) % 1000000007;
  NEW01 = (RES10 + RES01) % 1000000007;
  NEW10 = (RES01 + RES11) % 1000000007;
  NEW11 = (RES00 + RES10) % 1000000007;
  if (abs(a[u][0]) != to && a[u][0] < 0) {
    swap(NEW00, NEW10);
    swap(NEW01, NEW11);
  }
  if (abs(a[u][1]) != to && a[u][1] < 0) {
    swap(NEW00, NEW10);
    swap(NEW01, NEW11);
  }
  int nxt = abs(a[u][0]);
  if (to == nxt) nxt = abs(a[u][1]);
  int nxtvec = vec[u][0];
  if (nxtvec == p || (abs(a[nxtvec][0]) != nxt && abs(a[nxtvec][1]) != nxt))
    nxtvec = vec[u][1];
  solve2(u, nxtvec, nxt, NEW00, NEW01, NEW10, NEW11);
}
int n, m, i, j;
int main() {
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    scanf("%d", &k[i]);
    for (j = 0; j < k[i]; j++) {
      scanf("%d", &a[i][j]);
      g[abs(a[i][j])].push_back(i);
    }
  }
  RES[0] = 1;
  RES[1] = 0;
  long long ANS = 1;
  for (i = 1; i <= m; i++) {
    if (g[i].size() == 0) {
      ANS = (1LL * ANS * 2LL) % 1000000007;
      continue;
    }
    if (g[i].size() == 2 && g[i][0] == g[i][1]) {
      int u = g[i][0];
      if (a[u][0] != a[u][1]) {
        swap(RES[0], RES[1]);
        RES[1] = (RES[1] * 2LL) % 1000000007;
        RES[0] = (RES[0] * 2LL) % 1000000007;
        continue;
      }
      long long SU = (RES[0] + RES[1]) % 1000000007;
      RES[0] = RES[1] = SU;
      continue;
    }
    if (g[i].size() == 2) {
      vec[g[i][0]].push_back(g[i][1]);
      vec[g[i][1]].push_back(g[i][0]);
    }
  }
  for (i = 1; i <= n; i++)
    if (vec[i].size() == 0) {
      if (k[i] == 1) {
        long long SU = (RES[0] + RES[1]) % 1000000007;
        RES[0] = RES[1] = SU;
      } else if (k[i] == 2 && abs(a[i][0]) != abs(a[i][1])) {
        NW[0] = RES[0];
        NW[1] = RES[1];
        RES[0] = (NW[0] + NW[1] * 3LL) % 1000000007;
        RES[1] = (NW[0] * 3LL + NW[1]) % 1000000007;
      }
    }
  for (i = 1; i <= n; i++)
    if (!f[i] && vec[i].size() == 1) {
      int to = abs(a[i][0]);
      if (k[i] >= 2 && g[to].size() > 1) to = abs(a[i][1]);
      solve1(0, i, to, 1, 0, 1, 0);
    }
  for (i = 1; i <= n; i++)
    if (vec[i].size() == 2 && !f[i]) {
      int to = abs(a[i][1]);
      ST = i;
      NN[0] = 0;
      NN[1] = 0;
      IS = 0;
      NO = 0;
      solve2(0, i, to, 1, 0, 0, 0);
      IS = 1;
      NO = 0;
      solve2(0, i, to, 0, 0, 1, 0);
      NW[0] = ((RES[0] * NN[0]) % 1000000007 + (RES[1] * NN[1]) % 1000000007) %
              1000000007;
      NW[1] = ((RES[0] * NN[1]) % 1000000007 + (RES[1] * NN[0]) % 1000000007) %
              1000000007;
      RES[0] = NW[0];
      RES[1] = NW[1];
    }
  RES[1] = (RES[1] * ANS) % 1000000007;
  cout << RES[1] << endl;
}
