因为每个点不超过两次 两两连边 发现是一些环和链相互独立
然后就是在环链上DP 注意一些细节
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int P=100000007;
const int N=100005;
struct edge{
int u,v,next;
}G[N<<2];
int head[N],inum=1;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int tag[N],tis[N];
int vst[N];
#define V G[p].v
int cir,tot,lst[N];
inline void dfs(int u,int fa){
vst[u]=1; lst[++tot]=u;
for (int p=head[u];p;p=G[p].next)
if (p!=(fa^1)){
if (vst[V])
cir=1;
else
dfs(V,p);
}
}
ll f[N][2][2][2];
int cnt; ll F[N][2];
inline void Point(int idx){
int x=lst[1];
if (tis[x]==1)
F[idx][0]=F[idx][1]=1;
else if (tag[x]==0)
F[idx][0]=2;
else
F[idx][1]=2;
}
inline void Chain(int idx){
f[1][0][0][0]=f[1][1][1][0]=1;
for (int i=2;i<=tot;i++){
int x=lst[i];
for (int t=0;t<2;t++)
for (int o=0;o<2;o++)
for (int k=0;k<2;k++)
for (int j=0;j<2;j++)
(f[i][t][j^tag[x]][k^(o|j)]+=f[i-1][t][o][k])%=P;
}
for (int t=0;t<2;t++)
for (int o=0;o<2;o++)
for (int k=0;k<2;k++){
int ret=k;
if (tis[lst[1]]==2)
ret^=(t^tag[lst[1]]);
if (tis[lst[tot]]==2)
ret^=o;
(F[idx][ret]+=f[tot][t][o][k])%=P;
}
for (int i=1;i<=tot;i++) for (int t=0;t<2;t++) for (int o=0;o<2;o++) for (int k=0;k<2;k++) f[i][t][o][k]=0;
}
inline void Circle(int idx){
lst[++tot]=lst[1];
f[1][0][0][0]=f[1][1][1][0]=1;
for (int i=2;i<=tot;i++){
int x=lst[i];
for (int t=0;t<2;t++)
for (int o=0;o<2;o++)
for (int k=0;k<2;k++)
for (int j=0;j<2;j++)
(f[i][t][j^tag[x]][k^(o|j)]+=f[i-1][t][o][k])%=P;
}
F[idx][0]=(f[tot][0][0][0]+f[tot][1][1][0])%P;
F[idx][1]=(f[tot][0][0][1]+f[tot][1][1][1])%P;
for (int i=1;i<=tot;i++) for (int t=0;t<2;t++) for (int o=0;o<2;o++) for (int k=0;k<2;k++) f[i][t][o][k]=0;
}
ll H[N][2];
inline ll Total(){
H[0][0]=1;
for (int i=1;i<=cnt;i++)
for (int j=0;j<2;j++)
for (int k=0;k<2;k++)
(H[i][j^k]+=H[i-1][j]*F[i][k]%P)%=P;
return H[cnt][1];
}
int n,m;
int deg[N];
int main(){
int b,tem,last;
freopen("orxor.in","r",stdin);
freopen("orxor.out","w",stdout);
read(m); read(n);
for (int i=1;i<=m;i++){
read(b);
for (int j=1;j<=b;j++){
last=tem; read(tem);
if (tem<0) tem=-tem,tag[tem]^=1;
tis[tem]++;
}
if (b==2)
add(tem,last,++inum),add(last,tem,++inum),deg[tem]++,deg[last]++;
}
ll tt=1;
for (int i=1;i<=n;i++)
if (!tis[i])
(tt*=2)%=P;
for (int i=1;i<=n;i++)
if (tis[i] && !vst[i]){
cir=tot=0;
dfs(i,0);
if (!cir){
for (int j=1;j<=tot;j++)
vst[lst[j]]=0;
for (int j=1;j<=tot;j++)
if (deg[lst[j]]==1){
tot=0,dfs(lst[j],0);
break;
}
}
++cnt;
if (tot==1)
Point(cnt);
else if (!cir)
Chain(cnt);
else
Circle(cnt);
}
printf("%lld\n",tt*Total()%P);
return 0;
}