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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Text;
using static System.Math;

class Program
{
    static int n;
    static long k;
    static int[,] a;
    static long mod = (long)1e9 + 7;

    static void Main()
    {
        string[] input = Console.ReadLine().Split();
        n = int.Parse(input[0]);
        k = long.Parse(input[1]);
        a = new int[n, n];
        for (int i = 0; i < n; i++)
        {
            input = Console.ReadLine().Split();
            for (int j = 0; j < n; j++)
                a[i, j] = int.Parse(input[j]);
        }

        Matrix<long> ans = new Matrix<long>(n, 1);
        for (int i = 0; i < n; i++)
            ans[i, 0] = 1;
        Matrix<long> X = new Matrix<long>(n, n);
        Matrix<long>.SetMod();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                X[i, j] = a[j, i];
        X.Pow(k);
        ans = X * ans;
        long answer = 0;
        for (int i = 0; i < n; i++)
        {
            answer += ans[i, 0];
            answer %= mod;
        }
        Console.WriteLine(answer);
    }
}

/* T型の行列 */
struct Matrix<T>
{
    private T[,] A; //各値を格納
    public T this[int i, int j] //要素のインデクサ
    {
        get
        {
            try { return A[i, j]; } catch { throw; }
        }
        set
        {
            try
            {
                if (Calc_Mod)
                    A[i, j] = (dynamic)value % mod;
                else
                    A[i, j] = (dynamic)value;
            }
            catch { throw; }
        }
    }
    public int width; //列の個数
    public int height; //行の個数
    private static bool Calc_Mod = false; //modをとって計算するか(初期設定はfalse)
    public static long mod = (long)1e9 + 7; //余り(初期設定は1e9+7)

    /* コンストラクタ(行数、列数を指定) */
    public Matrix(int height, int width)
    {
        this.width = width;
        this.height = height;
        A = new T[height, width];
    }

    /* modをとって計算するように設定し、余りを設定. modをとるようになるのは以降の演算 */
    public static void SetMod(long m)
    {
        Calc_Mod = true;
        mod = m;
    }
    public static void SetMod()
    {
        Calc_Mod = !Calc_Mod;
    }

    /* 行列を標準出力に出力 */
    /*
       A[0,0] A[0,1] A[0,2] ... A[0,(width-1)]
       A[1,0] A[1,1] A[1,2] ... A[1,(width-1)]
         .                             .
         .                             .
         .                             .
       A[(height-1),0] A[(height-1),1] ... A[(hright-1),(width-1)]
     */
    public void Show()
    {
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                System.Console.Write("{0} ", A[i, j]);
            }
            System.Console.WriteLine("\b");
        }
    }

    /* n×nの単位行列を作り、返す */
    public static Matrix<T> E(int n)
    {
        Matrix<T> E = new Matrix<T>(n, n);
        for (int i = 0; i < n; i++)
            E[i, i] = (dynamic)1;
        return E;
    }

    /* A => -A */
    public static Matrix<T> operator -(Matrix<T> A)
    {
        for (int i = 0; i < A.height; i++)
            for (int j = 0; j < A.width; j++)
                A[i, j] *= (dynamic)(-1);
        return A;
    }

    /* A => +A */
    public static Matrix<T> operator +(Matrix<T> A)
    {
        return A;
    }

    /* (A,B) => A + B */
    public static Matrix<T> operator +(Matrix<T> A, Matrix<T> B)
    {
        if (A.width != B.width || A.height != B.height)
            throw new System.ArithmeticException();
        Matrix<T> C = new Matrix<T>(A.width, B.width);
        for (int i = 0; i < A.height; i++)
        {
            for (int j = 0; j < A.width; j++)
            {
                if (Calc_Mod)
                    C[i, j] = ((dynamic)A[i, j] + (dynamic)B[i, j]) % (dynamic)mod;
                else
                    C[i, j] = (dynamic)A[i, j] + (dynamic)B[i, j];
            }
        }
        return C;
    }

    /* (k,A) => k * A (kは整数) */
    public static Matrix<T> operator *(long k, Matrix<T> A)
    {
        Matrix<T> B = new Matrix<T>(A.height, A.width);
        for (int i = 0; i < A.height; i++)
        {
            for (int j = 0; j < A.width; j++)
            {
                if (Calc_Mod)
                    B[i, j] = (dynamic)A[i, j] % mod * k % mod;
                else
                    B[i, j] = (dynamic)A[i, j] * k;
            }
        }
        return B;
    }

    /* (A,B) => A - B */
    public static Matrix<T> operator -(Matrix<T> A, Matrix<T> B)
    {
        return A + (-B);
    }

    /* (A,B) => A * B */
    public static Matrix<T> operator *(Matrix<T> A, Matrix<T> B)
    {
        if (A.width != B.height)
            throw new System.ArithmeticException();
        int n = A.height;
        int m = B.width;
        int p = A.width;
        Matrix<T> C = new Matrix<T>(n, m);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                for (int k = 0; k < p; k++)
                {
                    if (Calc_Mod)
                        C[i, j] = ((dynamic)C[i, j] + (dynamic)A[i, k] * (dynamic)B[k, j] % (dynamic)mod) % (dynamic)mod;
                    else
                        C[i, j] = (dynamic)C[i, j] + (dynamic)A[i, k] * (dynamic)B[k, j];
                }
            }
        }
        return C;
    }

    /* thisをk乗する */
    public void Pow(long k)
    {
        if (k < 0)
            throw new System.ArithmeticException();
        this = Pow(this, k);
    }

    /* (A,k) => A^k (kは整数) */
    public static Matrix<T> Pow(Matrix<T> A, long k)
    {
        if (A.width != A.height)
            throw new System.ArithmeticException();
        if (k < 0)
            throw new System.ArithmeticException();
        if (k == 0)
            return E(A.width);
        Matrix<T> t = Pow(A, k / 2);
        if (k % 2 == 0)
            return t * t;
        return t * t * A;
    }
}