← Home
package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

const MOD int64 = 1000000007

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) NextInt() int {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	sign := 1
	if fs.data[fs.idx] == '-' {
		sign = -1
		fs.idx++
	}
	num := 0
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		num = num*10 + int(c-'0')
		fs.idx++
	}
	return sign * num
}

func combine(t0, t1, a, b int64) (int64, int64) {
	n0 := (t0*a + t1*b) % MOD
	n1 := (t0*b + t1*a) % MOD
	return n0, n1
}

func getPath(start int, deg []int, adj [][2]int, u, v []int, usedEdge, visited []bool) []int {
	verts := make([]int, 0, 4)
	verts = append(verts, start)
	visited[start] = true
	cur := start
	for {
		nextEdge := -1
		for i := 0; i < deg[cur]; i++ {
			e := adj[cur][i]
			if !usedEdge[e] {
				nextEdge = e
				break
			}
		}
		if nextEdge == -1 {
			break
		}
		usedEdge[nextEdge] = true
		nxt := u[nextEdge]
		if nxt == cur {
			nxt = v[nextEdge]
		}
		if !visited[nxt] {
			visited[nxt] = true
		}
		verts = append(verts, nxt)
		cur = nxt
	}
	return verts
}

func getCycle(start int, deg []int, adj [][2]int, u, v []int, usedEdge, visited []bool) []int {
	verts := make([]int, 0, 4)
	verts = append(verts, start)
	visited[start] = true
	cur := start
	for {
		nextEdge := -1
		for i := 0; i < deg[cur]; i++ {
			e := adj[cur][i]
			if !usedEdge[e] {
				nextEdge = e
				break
			}
		}
		if nextEdge == -1 {
			break
		}
		usedEdge[nextEdge] = true
		nxt := u[nextEdge]
		if nxt == cur {
			nxt = v[nextEdge]
		}
		if nxt != start {
			visited[nxt] = true
			verts = append(verts, nxt)
		}
		cur = nxt
	}
	return verts
}

func countPath(verts []int, p []int) (int64, int64) {
	var dp, ndp [2][2]int64
	p0 := p[verts[0]]
	dp[0][0] = 1
	dp[1][p0] = 1
	for i := 1; i < len(verts); i++ {
		ndp = [2][2]int64{}
		pi := p[verts[i]]
		for prev := 0; prev < 2; prev++ {
			for par := 0; par < 2; par++ {
				val := dp[prev][par]
				if val == 0 {
					continue
				}
				ndp[0][par] += val
				if ndp[0][par] >= MOD {
					ndp[0][par] -= MOD
				}
				npar := par ^ pi ^ prev
				ndp[1][npar] += val
				if ndp[1][npar] >= MOD {
					ndp[1][npar] -= MOD
				}
			}
		}
		dp = ndp
	}
	a := dp[0][0] + dp[1][0]
	if a >= MOD {
		a -= MOD
	}
	b := dp[0][1] + dp[1][1]
	if b >= MOD {
		b -= MOD
	}
	return a, b
}

func countCycle(verts []int, p []int) (int64, int64) {
	var ans [2]int64
	start := verts[0]
	for x0 := 0; x0 < 2; x0++ {
		var dp, ndp [2][2]int64
		dp[x0][p[start]&x0] = 1
		for i := 1; i < len(verts); i++ {
			ndp = [2][2]int64{}
			pi := p[verts[i]]
			for prev := 0; prev < 2; prev++ {
				for par := 0; par < 2; par++ {
					val := dp[prev][par]
					if val == 0 {
						continue
					}
					ndp[0][par] += val
					if ndp[0][par] >= MOD {
						ndp[0][par] -= MOD
					}
					npar := par ^ pi ^ prev
					ndp[1][npar] += val
					if ndp[1][npar] >= MOD {
						ndp[1][npar] -= MOD
					}
				}
			}
			dp = ndp
		}
		for last := 0; last < 2; last++ {
			for par := 0; par < 2; par++ {
				val := dp[last][par]
				if val == 0 {
					continue
				}
				totalPar := par ^ (last & x0)
				ans[totalPar] += val
				if ans[totalPar] >= MOD {
					ans[totalPar] -= MOD
				}
			}
		}
	}
	return ans[0], ans[1]
}

func main() {
	in := NewFastScanner()
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	n := in.NextInt()
	m := in.NextInt()

	p := make([]int, m+1)
	deg := make([]int, m+1)
	adj := make([][2]int, m+1)
	u := make([]int, 0, n)
	v := make([]int, 0, n)
	c := 0

	addEdge := func(a, b int) {
		id := len(u)
		u = append(u, a)
		v = append(v, b)
		adj[a][deg[a]] = id
		deg[a]++
		adj[b][deg[b]] = id
		deg[b]++
	}

	for i := 0; i < n; i++ {
		k := in.NextInt()
		if k == 1 {
			x := in.NextInt()
			s := 0
			if x < 0 {
				s = 1
				x = -x
			}
			p[x] ^= 1
			c ^= s
		} else {
			a := in.NextInt()
			b := in.NextInt()
			s := 0
			t := 0
			if a < 0 {
				s = 1
				a = -a
			}
			if b < 0 {
				t = 1
				b = -b
			}
			if a == b {
				if s == t {
					p[a] ^= 1
					c ^= s
				} else {
					c ^= 1
				}
			} else {
				addEdge(a, b)
				p[a] ^= 1 ^ t
				p[b] ^= 1 ^ s
				c ^= s | t
			}
		}
	}

	usedEdge := make([]bool, len(u))
	visited := make([]bool, m+1)

	total0, total1 := int64(1), int64(0)

	for i := 1; i <= m; i++ {
		if visited[i] {
			continue
		}
		if deg[i] == 0 {
			visited[i] = true
			var a, b int64
			if p[i] == 0 {
				a, b = 2, 0
			} else {
				a, b = 1, 1
			}
			total0, total1 = combine(total0, total1, a, b)
		} else if deg[i] == 1 {
			verts := getPath(i, deg, adj, u, v, usedEdge, visited)
			a, b := countPath(verts, p)
			total0, total1 = combine(total0, total1, a, b)
		}
	}

	for i := 1; i <= m; i++ {
		if !visited[i] {
			verts := getCycle(i, deg, adj, u, v, usedEdge, visited)
			a, b := countCycle(verts, p)
			total0, total1 = combine(total0, total1, a, b)
		}
	}

	target := 1 ^ c
	if target == 0 {
		fmt.Fprintln(out, total0)
	} else {
		fmt.Fprintln(out, total1)
	}
}