Problem:
Score : 100 points

Problem Statement

There is a simple directed graph G with N vertices, numbered 1, 2, \ldots, N.

For each i and j (1 \leq i, j \leq N), you are given an integer a_{i, j} that represents whether there is a directed edge from Vertex i to j.
If a_{i, j} = 1, there is a directed edge from Vertex i to j; if a_{i, j} = 0, there is not.

Find the number of different directed paths of length K in G, modulo 10^9 + 7.
We will also count a path that traverses the same edge multiple times.

Constraints

All values in input are integers.

1 \leq N \leq 50

1 \leq K \leq 10^{18}

a_{i, j} is 0 or 1.

a_{i, i} = 0

Input

Input is given from Standard Input in the following format:

N K
a_{1, 1} \ldots a_{1, N}
:
a_{N, 1} \ldots a_{N, N}

Output

Print the number of different directed paths of length K in G, modulo 10^9 + 7.

Sample Input 1

4 2
0 1 0 0
0 0 1 1
0 0 0 1
1 0 0 0

Sample Output 1

6

G is drawn in the figure below:

There are six directed paths of length 2:

1 → 2 → 3

1 → 2 → 4

2 → 3 → 4

2 → 4 → 1

3 → 4 → 1

4 → 1 → 2

Sample Input 2

3 3
0 1 0
1 0 1
0 0 0

Sample Output 2

3

G is drawn in the figure below:

There are three directed paths of length 3:

1 → 2 → 1 → 2

2 → 1 → 2 → 1

2 → 1 → 2 → 3

Sample Input 3

6 2
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 1 0
0 0 0 0 0 1
0 0 0 0 0 0

Sample Output 3

1

G is drawn in the figure below:

There is one directed path of length 2:

4 → 5 → 6

Sample Input 4

1 1
0

Sample Output 4

0

Sample Input 5

10 1000000000000000000
0 0 1 1 0 0 0 1 1 0
0 0 0 0 0 1 1 1 0 0
0 1 0 0 0 1 0 1 0 1
1 1 1 0 1 1 0 1 1 0
0 1 1 1 0 1 0 1 1 1
0 0 0 1 0 0 1 0 1 0
0 0 0 1 1 0 0 1 0 1
1 0 0 0 1 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
1 0 1 1 1 0 1 1 1 0

Sample Output 5

957538352

Be sure to print the count modulo 10^9 + 7.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;

const ll mod = 1000000007;

// Matrix Definition{{{

template< class T >
struct Matrix{
    vector< vector<T> > A;

    Matrix(){};
    Matrix( int n, int m ) {
        A.assign(n,vector<T>(m,0));
    };
    Matrix( int n ) {
        A.assign(n,vector<T>(n,0));
    };

    int height() const {
        return (A.size());
    }

    int width() const {
        return (A[0].size());
    }

    inline vector<T> &operator[]( int k ) {
        return (A.at(k));
    }

    inline const vector<T> &operator[]( int k ) const {
        return (A.at(k));
    }

    // 単位行列
    static Matrix E( int n ){
        Matrix mat(n);
        for( int i = 0; i < n; i++ ) mat[i][i] = 1;
        return mat;
    }

    Matrix &operator+=( const Matrix &B ){
        int n = height(), m = width();
        assert( n == B.height() && m == B.width() );
        for( int i = 0; i < n; i++ )
            for( int j = 0; j < m; j++ )
                (*this)[i][j] += B[i][j];
        return (*this);
    }

    Matrix &operator-=( const Matrix &B ){
        int n = height(), m = width();
        assert( n == B.height() && m == B.width() );
        for( int i = 0; i < n; i++ )
            for( int j = 0; j < m; j++ )
                (*this)[i][j] -= B[i][j];
        return (*this);
    }

    Matrix &operator*=( const Matrix &B ){
        int n = height(), m = B.width(), p = width();
        assert( p == B.height() );
        vector< vector<T> > C( n, vector<T>(m, 0) );
        for( int i = 0; i < n; i++ )
            for( int j = 0; j < m; j++ )
                for( int k = 0; k < p; k++ )
                    (C[i][j] += (*this)[i][k] * B[k][j])%=mod;
        A.swap(C);
        return (*this);
    }

    Matrix power( ll k ){
        Matrix B = Matrix::E(height());
        while( k > 0 ){
            if( k&1 ) B *= *this;
            *this *= *this;
            k >>= 1;
        }
        A.swap(B.A);
        return *this;
    }

    Matrix operator+(const Matrix &B ) const {
        return (Matrix(*this) += B );
    }
    Matrix operator-(const Matrix &B ) const {
        return (Matrix(*this) -= B );
    }
    Matrix operator*(const Matrix &B ) const {
        return (Matrix(*this) *= B );
    }

    void Print(){
        int n = height(), m = width();
        for( int i = 0; i < n; i++ ){
            printf ("[");
            for( int j = 0; j < m; j++ ){
                printf ("%lld%s", (*this)[i][j], j == m-1 ? "]\n" : "," );
            }
        }
    }

};

// }}}

int main() {

    int N;
    ll K;
    int x;

    cin >> N >> K;

    Matrix<ll> a(N);

    for( int i = 0; i < N; i++ ){
        for( int j = 0; j < N; j++ ){
            cin >> x;
            a[i][j] = x;
        }
    }

    a.power( K );

    ll ans = 0;
    for( int i = 0; i < N; i++ ){
        for( int j = 0; j < N; j++ ){
            ans += a[i][j];
            ans %= mod;
        }
    }

    printf ("%lld\n", ans );


    return 0;
}