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>
#include <boost/multiprecision/cpp_int.hpp>

using namespace std;

namespace mp = boost::multiprecision;

#define INF 100000000
#define YJ 1145141919
#define INF_INT_MAX 2147483647
#define INF_LL 9223372036854775
#define INF_LL_MAX 9223372036854775807
#define EPS 1e-10
#define MOD 1000000007
#define MOD9 998244353
#define Pi acos(-1)
#define LL long long
#define ULL unsigned long long
#define LD long double

#define int long long

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(a)  begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())

const int MAX_N = 55;

int N, K;

template <typename T>
class Matrix {
public:
  Matrix(int r, int c) {
    mat.clear();
    for(int i = 0; i < r; i++) {
      mat.push_back(vector<T>());
      mat[i].resize(c);
    }
  }

  vector<T>& operator[] (int r) {
    return mat[r];
  }

  void print() const {
    for(int i = 0; i < mat.size(); i++) {
      for(int j = 0; j < mat[i].size(); j++) {
        cerr << mat[i][j] << " ";
      }
      cerr << endl;
    }
  }

  unsigned int getR() const {
    return mat.size();
  }

  unsigned int getC() const {
    return mat[0].size();
  }

  Matrix operator + (Matrix& matrix) {
    Matrix<T> ret(this->getR(), this->getC());
    for(int r = 0; r < matrix.getR(); r++) {
      for(int c = 0; c < matrix.getC(); c++) {
        ret[r][c] = (*this)[r][c] + matrix[r][c];
        ret[r][c] %= MOD;
      }
    }
    return ret;
  }

  void operator += (Matrix& matrix) {
    for(int r = 0; r < matrix.getR(); r++) {
      for(int c = 0; c < matrix.getC(); c++) {
        (*this)[r][c] += matrix[r][c];
        (*this)[r][c] %= MOD;
      }
    }
  }

  Matrix operator * (Matrix& matrix) {
    Matrix<T> ret(this->getR(), matrix.getC());
    for(int r = 0; r < getR(); r++) {
      for(int c = 0; c < matrix.getC(); c++) {
        for(int rr = 0; rr < matrix.getR(); rr++) {
          ret[r][c] += (*this)[r][rr] * matrix[rr][c];
          ret[r][c] %= MOD;
        }
      }
    }
    return ret;
  }

  void operator *= (Matrix& matrix) {
    (*this) = (*this) * matrix;
  }

private:
  vector<vector<T>> mat;
};

signed main()
{
  cin >> N >> K;
  Matrix<int> mat(N, N), tmp(N,N);

  REP(i,N) {
    REP(j,N) {
      cin >> mat[i][j];
    }
    tmp[i][i] = 1;
  }

  Matrix<int> initMat(1, N);
  REP(i,N) {
    initMat[0][i] = 1;
  }

  while(K) {
    if(K&1)
      tmp *= mat;
    
    mat *= mat;
    K /= 2;
  }

  initMat *= tmp;

  int ans = 0;
  REP(n,N) {
    ans += initMat[0][n];
    ans %= MOD;
  }

  cout << ans << endl;

  return 0;
}