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)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())



#define MOD 1000000007




template<class T = long long>
class Matrix {
	int _row, _col;
	T* p;
public:
	Matrix() :_row(0), _col(0), p(0) {}
	Matrix(int row, int col) :_row(row), _col(col) {
		p = new T[_row*_col];
	}
	Matrix(const Matrix& a) :_row(-1), p(0) {
		copy(a);
	}
	~Matrix() {
		delete[] p;
	}
	int row()const { return _row; }
	int col()const { return _col; }
	void resize(int r, int c) {
		if (_row*_col != r * c) {
			delete[] p;
			p = new T[r*c];
		}
		_row = r;
		_col = c;
	}
	void swap(Matrix& a) {
		std::swap(_row, a._row);
		std::swap(_col, a._col);
		std::swap(p, a.p);
	}
	void copy(const Matrix& a) {
		resize(a._row, a._col);
		for (int i = 0; i < row(); i++)
			for (int j = 0; j < col(); j++)
				p[i*col() + j] = a[i][j];
	}
	T* operator[](int i)const { return p + (i*_col); }
	Matrix& operator =(const Matrix &a) {
		copy(a);
		return *this;
	}
	Matrix& operator *=(const Matrix &a) {
		(*this*a).swap(*this);
		return *this;
	}
	Matrix operator *(const Matrix &a)const {
		assert(col() == a.row());
		Matrix res(row(), a.col());

		//ikjループ キャッシュ効率化　要計測
		for (int i = 0; i < row(); i++) {
			for (int j = 0; j < a.col(); j++)res[i][j] = 0;
			for (int k = 0; k < col(); k++) {
				T da = p[i*col() + k];
				const T * const __restrict pb = a[k];
				T * const __restrict pc = res[i];
				for (int j = 0; j < a.col(); j++) {
					pc[j] = (pc[j] + da * pb[j]) % MOD;
				}
			}
		}
		return res;
	}
	Matrix pow(long long n)const {
		assert(row() == col());
		int size = row();
		Matrix res(size, size), x(*this);
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++)res[i][j] = i == j;
		}
		while (n) {
			if (n & 1) {
				(res*x).swap(res);
			}
			(x*x).swap(x);
			n >>= 1;
		}
		return res;
	}
};



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n;
	long long k;
	cin >> n >> k;
	int a[50][50];
	rep(i, n)rep(j, n)cin >> a[i][j];

	Matrix<> mat(n, n);
	rep(i, n)rep(j, n)mat[i][j] = a[i][j];

	mat = mat.pow(k);
	int s = 0;
	rep(i, n)rep(j, n)(s += mat[i][j]) %= MOD;
	cout << s << endl;



	return 0;
}