#include <bits/stdc++.h>
#pragma warning(disable : 4996)
using namespace std;
int n, m;
vector<pair<int, pair<int, int>>> edge[200000];
long long ans = 1;
int odat[200000];
int bias;
int check[200000];
int get(pair<int, int> info, int x, int y) {
  if (info.first == -1) x ^= 1;
  if (info.second == -1) y ^= 1;
  return x | y;
}
int bonus(int dat, int x) {
  if (dat == 1 && x) return 1;
  if (dat == -1 && !x) return 1;
  return 0;
}
vector<pair<long long, long long>> podat;
int main() {
  int i, j, k, l;
  cin >> m >> n;
  for (i = 0; i < m; i++) {
    int x;
    scanf("%d", &x);
    if (x == 1) {
      int y;
      scanf("%d", &y);
      odat[abs(y) - 1] = y > 0 ? 1 : -1;
    } else {
      int y, z;
      scanf("%d%d", &y, &z);
      if (abs(y) == abs(z)) {
        if (y == z)
          odat[abs(y) - 1] = y > 0 ? 1 : -1;
        else
          bias ^= 1;
        continue;
      }
      int u, v;
      u = y > 0 ? 1 : -1, v = z > 0 ? 1 : -1;
      edge[abs(y) - 1].emplace_back(abs(z) - 1, make_pair(u, v));
      edge[abs(z) - 1].emplace_back(abs(y) - 1, make_pair(v, u));
    }
  }
  for (i = 0; i < n; i++) {
    if (check[i]) continue;
    if (edge[i].size() == 0) {
      check[i] = 1;
      if (odat[i]) {
        podat.emplace_back(1, 1);
      } else {
        ans *= 2, ans %= 1000000007;
      }
      continue;
    } else if (edge[i].size() == 2)
      continue;
    int past = -1;
    int now = i;
    pair<int, int> pastinfo(0, 0);
    long long d[2][2] = {
        0,
    };
    while (1) {
      check[now] = 1;
      int nex = -1;
      pair<int, int> info;
      for (auto e : edge[now]) {
        if (e.first != past) nex = e.first, info = e.second;
      }
      if (past == -1) {
        if (odat[now] == 1)
          d[0][0] = 1, d[1][1] = 1;
        else if (odat[now] == -1)
          d[0][1] = 1, d[1][0] = 1;
        else
          d[0][0] = d[1][0] = 1;
      } else {
        long long nd[2][2] = {
            0,
        };
        for (j = 0; j < 2; j++) {
          for (k = 0; k < 2; k++) {
            for (l = 0; l < 2; l++) {
              nd[l][k ^ get(pastinfo, j, l) ^ bonus(odat[now], l)] += d[j][k];
              nd[l][k ^ get(pastinfo, j, l) ^ bonus(odat[now], l)] %=
                  1000000007;
            }
          }
        }
        for (j = 0; j < 2; j++)
          for (k = 0; k < 2; k++) d[j][k] = nd[j][k];
      }
      if (nex == -1) break;
      pastinfo = info;
      past = now;
      now = nex;
    }
    podat.emplace_back((d[0][0] + d[1][0]) % 1000000007,
                       (d[0][1] + d[1][1]) % 1000000007);
  }
  for (i = 0; i < n; i++) {
    if (check[i]) continue;
    pair<long long, long long> rdat(0, 0);
    for (int ii = 0; ii < 2; ii++) {
      int past = -1;
      int now = i;
      pair<int, int> pastinfo(0, 0);
      long long d[2][2] = {
          0,
      };
      int size = 0;
      while (1) {
        check[now] = 1;
        size++;
        int nex = -1;
        pair<int, int> info;
        int flag = 0;
        for (auto e : edge[now]) {
          if (e.first == past && !flag) {
            flag = 1;
            continue;
          }
          nex = e.first, info = e.second;
        }
        if (past == -1) {
          d[ii][0] = 1;
        } else {
          long long nd[2][2] = {
              0,
          };
          for (j = 0; j < 2; j++) {
            for (k = 0; k < 2; k++) {
              for (l = 0; l < 2; l++) {
                nd[l][k ^ get(pastinfo, j, l)] += d[j][k];
                nd[l][k ^ get(pastinfo, j, l)] %= 1000000007;
              }
            }
          }
          for (j = 0; j < 2; j++)
            for (k = 0; k < 2; k++) d[j][k] = nd[j][k];
        }
        if (nex == i) break;
        pastinfo = info;
        past = now;
        now = nex;
      }
      pair<int, int> tarinfo;
      if (size != 2) {
        for (auto e : edge[i]) {
          if (e.first == now) {
            tarinfo = e.second;
          }
        }
      } else {
        if (edge[i][0].second == pastinfo)
          tarinfo = edge[i][1].second;
        else
          tarinfo = edge[i][0].second;
      }
      for (j = 0; j < 2; j++) {
        int u = get(tarinfo, ii, j);
        if (!u)
          rdat.first += d[j][0], rdat.second += d[j][1];
        else
          rdat.second += d[j][0], rdat.first += d[j][1];
        rdat.first %= 1000000007, rdat.second %= 1000000007;
      }
    }
    podat.push_back(rdat);
  }
  long long d[2] = {1, 0};
  for (auto e : podat) {
    long long nd[2] = {0, 0};
    nd[0] += d[0] * e.first;
    nd[0] += d[1] * e.second;
    nd[1] += d[0] * e.second;
    nd[1] += d[1] * e.first;
    nd[0] %= 1000000007, nd[1] %= 1000000007;
    d[0] = nd[0], d[1] = nd[1];
  }
  cout << d[1 ^ bias] * ans % 1000000007;
  return 0;
}
