(AB)(AB)(AB)=A(BA)(BA)B
用到线性代数的知识还是蛮有亲切感的。。毕竟上了大学就感觉这门课学到了东西。。
//#include<bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
const double pi=acos(-1.0);
#define ll long long
#define pb push_back
#define sqr(a) ((a)*(a))
#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
const double eps=1e-10;
const int maxn=1e3+56;
const int inf=0x3f3f3f3f;
const ll mod=6;
ll arr[maxn];
ll n,m;
struct mat{
ll a[15][15];
ll n,m;
mat(){memset(a,0,sizeof a);n=0;m=0;}
mat(ll x,ll y){memset(a,0,sizeof a);n=x;m=y;}
mat operator* (const mat &rhs)const{
mat ans;
ans.n=n;ans.m=rhs.m;
for(int i=1;i<=n;i++){
for(int j=1;j<=rhs.m;j++){
for(int k=1;k<=m;k++){
ans.a[i][j]=(ans.a[i][j]+a[i][k]*rhs.a[k][j])%mod;
}
}
}
return ans;
}
mat operator^ (ll rhs)const{
mat ans(n,n),b=*this;
for(int i=1;i<=n;i++)ans.a[i][i]=1;
for(;rhs;rhs>>=1,b=b*b)
if(rhs&1)ans=ans*b;
return ans;
}
};
ll a[maxn][maxn],b[maxn][maxn],c1[maxn][maxn],c2[maxn][maxn];
int main(){
while(~scanf("%lld%lld",&n,&m)&&n){
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
scanf("%lld",&a[i][j]);
for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)
scanf("%lld",&b[i][j]);
mat tmp(m,m);
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++){
tmp.a[i][j]=0;
for(int k=1;k<=n;k++){
tmp.a[i][j]+=b[i][k]*a[k][j];
tmp.a[i][j]%=6;
}
}
mat p=tmp^(n*n-1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
c1[i][j]=0;
for(int k=1;k<=m;k++){
c1[i][j]=(c1[i][j]+a[i][k]*p.a[k][j])%6;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
c2[i][j]=0;
for(int k=1;k<=m;k++){
c2[i][j]=(c2[i][j]+c1[i][k]*b[k][j])%6;
}
}
ll ans=0;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)ans+=c2[i][j];
printf("%lld
",ans);
}
}