//给m个函数
//其相应是自变量x属于{1,2,...n}
//f(x)属于{1,2...3}
//给出当中一些函数,问有多少种不同的函数集合使得
//1<=i<=n f1(f2(f3...fm(i))) = i
//直接为(m!)^(sum-1) sum为不知道的函数个数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 110 ;
typedef long long ll ;
const ll mod = 1e9+7 ;
int map[maxn][maxn] ;
int vis[maxn];
int a[maxn] ;
int main()
{
//freopen("in.txt" ,"r" ,stdin) ;
//freopen("out.txt","w" ,stdout);
int n , m ;
int t = 0 ;
while(~scanf("%d%d" ,&m , &n))
{
int sum = 0 ;
int flag = 0 ;
for(int i = 1;i <= n;i++)
{
memset(vis , 0 , sizeof(vis)) ;
int tmp ;
scanf("%d" , &tmp);
if(tmp == -1)
sum++;
else
{
map[i][1] = tmp;
if(tmp < 1 || tmp > m || vis[tmp])flag = 1;
for(int j = 2;j <= m;j++)
{
scanf("%d" , &map[i][j]) ;
if(map[i][j] < 1 || map[i][j] > m || vis[map[i][j]])
flag = 1;
vis[map[i][j]] = 1;
}
}
}
if(flag)
{
puts("0");
continue ;
}
if(sum)
{
ll ans = 1;
sum--;
ll tmp = 1 ;
for(ll i = 1;i <= m;i++)
tmp = (tmp*i)%mod ;
while(sum--)
ans = (ans*tmp)%mod ;
printf("%lld\n" , ans) ;
continue ;
}
for(int i = 1;i <= m;i++)
a[i] = i ;
for(int i = n;i > 0;i--)
for(int j = 1;j <= m;j++)
a[j] = map[i][a[j]] ;
flag = 0 ;
for(int i = 1;i <= m;i++)
if(a[i] != i)
{
flag = 1;
break ;
}
if(flag)puts("0");
else puts("1");
}
return 0 ;
}