1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <bits/stdc++.h>
#define FOR(i,p,k) for(int i=(p);i<=(k);++i)
#define REP(i,n) FOR(i,0,(n)-1)
#define ssize(x) (int((x).size()))
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define gc getchar_unlocked
using namespace std;
typedef long long ll;
constexpr ll mod = 1000000007ll;

void wczytaj(int &a){
	int c = gc();
	while(c < '0' || c > '9') c = gc();
	for(a = 0; c >= '0' && c <= '9'; c = gc()) a = 10*a+c-'0';
}

ll odw(ll a, ll b = mod-2ll){
	ll ret = 1ll;
	for(; b; b>>=1, a=(a*a)%mod) if(b&1ll) ret = (ret*a)%mod;
	return ret;
}

struct znajdz_i_polacz{
	vector<int> r;
	znajdz_i_polacz(int n){
		r.resize(n);
		REP(i, n) r[i] = i;
	}
	int f(int x){
		if(r[x] != x) r[x] = f(r[x]);
		return r[x];
	}
	void u(int a, int b){
		a = f(a), b = f(b);
		if(a != b) r[a] = b;
	}
};

void solve(){
	int n, k;
	wczytaj(n), wczytaj(k);
	znajdz_i_polacz janusz(n*n);
	while(k--){
		vector<int> perm(n);
		REP(i, n) wczytaj(perm[i]), --perm[i];
		REP(i, n) REP(j, n) if(i != j) janusz.u(i*n+j, perm[i]*n+perm[j]);
	}
	
	vector<vector<int>> spojne(n*n);
	REP(i, n*n) spojne[janusz.f(i)].emplace_back(i);
	
	ll wyn = 0ll;
	for(vector<int> vec : spojne) if(ssize(vec) > 1){
		ll t = ssize(vec), x = 0ll;
		for(int i : vec) if(i/n > i%n) ++x;
		wyn = (wyn + ((x*(t-x))%mod)*odw(t))%mod;
	}
	printf("%lld", wyn);
}

int main(){
	solve();
	return 0;
}