#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  char ch = getchar();
  long long x = 0, f = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      ;
    f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
struct edge {
  long long to, next, v;
} e[101000 * 2];
long long T, n, tot = 1, m, u, v, del, pdu, pdv, an0, an1, cnt;
long long flag[101000], head[101000], vis[101000], f[101000][2][2];
void add(long long x, long long y, long long v) {
  e[++tot] = (edge){y, head[x], v};
  head[x] = tot;
}
void add(long long x, long long y, long long v1, long long v2) {
  x = abs(x);
  y = abs(y);
  add(x, y, v1);
  add(y, x, v2);
}
void dfs(long long x, long long pre) {
  cnt -= 2;
  vis[x] = 1;
  for (long long i = head[x]; i; i = e[i].next) {
    cnt++;
    if (e[i].to == x) cnt++;
    if (!vis[e[i].to])
      dfs(e[i].to, i);
    else if (i != (pre ^ 1)) {
      u = x;
      v = e[i].to;
      del = i;
    }
  }
}
long long check(long long k1, long long k2, long long k3) {
  if ((k3 & 2) == 0) k1 ^= 1;
  if ((k3 & 1) == 0) k2 ^= 1;
  return k1 | k2;
}
void treedp(long long x, long long fa) {
  for (long long i = head[x]; i; i = e[i].next)
    if (e[i].to != fa && (i ^ del) && (i ^ del ^ 1)) treedp(e[i].to, x);
  memset(f[x], 0, sizeof(f[x]));
  for (long long w = 0; w <= 1; ++w) {
    if (x == u && w != pdu) continue;
    if (x == v && w != pdv) continue;
    long long ans0 = 1, ans1 = 0;
    for (long long i = head[x]; i; i = e[i].next) {
      long long to = e[i].to;
      if (to == fa || !(i ^ del) || !(i ^ del ^ 1)) continue;
      long long an0 = ans0, an1 = ans1;
      ans0 = 0;
      ans1 = 0;
      for (long long w1 = 0; w1 <= 1; ++w1) {
        long long A = f[to][w1][0], B = f[to][w1][1];
        if (check(w, w1, e[i].v)) swap(A, B);
        ans0 = (ans0 + 1ll * A * an0 + 1ll * B * an1) % 1000000007;
        ans1 = (ans1 + 1ll * A * an1 + 1ll * B * an0) % 1000000007;
      }
    }
    if (flag[x] & (1 << w)) swap(ans0, ans1);
    f[x][w][0] = (f[x][w][0] + ans0) % 1000000007;
    f[x][w][1] = (f[x][w][1] + ans1) % 1000000007;
  }
}
void solve(long long x) {
  cnt = 0;
  del = -100;
  dfs(x, -1);
  long long ans0 = 0, ans1 = 0;
  if (del == -100) {
    v = 0;
    u = x;
    pdu = 0;
    pdv = 1;
    treedp(x, 0);
    ans0 = (ans0 + 1ll * f[x][0][0] + f[x][1][0]) % 1000000007;
    ans1 = (ans1 + 1ll * f[x][0][1] + f[x][1][1]) % 1000000007;
    pdu = 1;
    treedp(x, 0);
    ans0 = (ans0 + 1ll * f[x][0][0] + f[x][1][0]) % 1000000007;
    ans1 = (ans1 + 1ll * f[x][0][1] + f[x][1][1]) % 1000000007;
  } else {
    for (pdu = 0; pdu < 2; pdu++)
      for (pdv = 0; pdv < 2; pdv++) {
        treedp(u, 0);
        if (check(pdu, pdv, e[del].v))
          swap(f[u][0][0], f[u][0][1]), swap(f[u][1][0], f[u][1][1]);
        ans0 = (ans0 + 1ll * f[u][0][0] + f[u][1][0]) % 1000000007;
        ans1 = (ans1 + 1ll * f[u][0][1] + f[u][1][1]) % 1000000007;
      }
  }
  long long k0 = an0, k1 = an1;
  an0 = ((long long)k0 * ans0 + (long long)k1 * ans1) % 1000000007;
  an1 = ((long long)k0 * ans1 + (long long)k1 * ans0) % 1000000007;
}
int main() {
  T = read();
  n = read();
  while (T--) {
    long long x = read(), y;
    if (x == 1) {
      y = read();
      if (y > 0)
        flag[y] |= 2;
      else
        flag[-y] |= 1;
    } else {
      x = read();
      y = read();
      if (x < 0 && y < 0) add(x, y, 0, 0);
      if (x < 0 && y > 0) add(x, y, 1, 2);
      if (x > 0 && y < 0) add(x, y, 2, 1);
      if (x > 0 && y > 0) add(x, y, 3, 3);
    }
  }
  an0 = 1;
  an1 = 0;
  for (long long i = 1; i <= n; ++i)
    if (!vis[i]) solve(i);
  printf("%d", an1);
}
