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 <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;

#define LEN(x) (int)x.size()
#define ALL(x) x.begin(), x.end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int,int>;
using vpii = vector<pii>;

template<typename T, typename M = __gnu_pbds::null_type>
using ordered_set = __gnu_pbds::tree<T, M, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

inline int fcmp(double x, double y)
{ return (x < y + EPS ? (x < y - EPS ? -1 : 0) : 1);}

template<class base_t, const int M, const int N>
class matrix
{
private:
    base_t **t;

public:
    matrix(base_t c = 0)
    {
        t = new base_t*[M];
        for(int i = 0; i < M; i++)
        {
            t[i] = new base_t[N];
            for(int j = 0; j < N; j++)
                t[i][j] = 0;
            t[i][i] = c;
        }
    }

    base_t* & operator [] (const int i) { return t[i];}

    matrix<base_t, M, N> operator + (matrix<base_t, M, N>& b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] + b[i][j];
        return ans;
    }
    matrix<base_t, M, N>& operator += (matrix<base_t, M, N>& b)
    {
        return *this = *this + b;
    }

    matrix<base_t, M, N> operator - (matrix<base_t, M, N>& b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] - b[i][j];
        return ans;
    }
    matrix<base_t, M, N>& operator -= (matrix<base_t, M, N>& b)
    {
        return *this = *this - b;
    }

    template<const int U>
    matrix<base_t, M, U> operator * (matrix<base_t, N, U>& b)
    {
        matrix<base_t, M, U> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < U; j++)
                for(int k = 0; k < N; k++)
                    ans[i][j] += t[i][k] * b[k][j];
        return ans;
    }
    template<const int U>
    matrix<base_t, M, U>& operator *= (matrix<base_t, N, U>& b)
    {
        return *this = *this * b;
    }

    matrix<base_t, M, N> operator + (base_t b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] + b;
        return ans;
    }
    matrix<base_t, M, N> operator - ( base_t b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] - b;
        return ans;
    }
    matrix<base_t, M, N> operator * (base_t b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] * b;
        return ans;
    }
    matrix<base_t, M, N> operator / (base_t b)
    {
        matrix<base_t, M, N> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[i][j] = t[i][j] / b;
        return ans;
    }

    matrix<base_t, N, M> tranpose()
    {
        matrix<base_t, N, M> ans;
        for(int i = 0; i < M; i++)
            for(int j = 0; j < N; j++)
                ans[j][i] = t[i][j];
        return ans;
    }

    base_t trace()
    {
        base_t sum = base_t(0);
        for(int i = 0; i < min(M, N); i++)
            sum += t[i][i];
        return sum;
    }
};

template<ll mod>
struct modint
{
    ll val;
    
    inline ll normalize(ll n)
    {
        if(n >= mod || n < -mod)
            n %= mod;
        if(n < 0)
            n += mod;
        return n;
    }

    modint(){ val = 0;}
    template<class T> modint(T x = 0) { val = normalize(x);}
    template<class T> explicit operator T() { return static_cast<T>(val);}

    modint<mod>& operator += (const modint<mod> o) { return *this = modint<mod>(val + o.val);}   
    template<class T> modint<mod>& operator += (const T o) { return *this = modint<mod>(val + normalize(o));}   
    modint<mod>& operator -= (const modint<mod> o) { return *this = modint<mod>(val - o.val);}   
    template<class T> modint<mod>& operator -= (const T o) { return *this = modint<mod>(val - normalize(o));}   
    modint<mod>& operator *= (const modint<mod> o) { return *this = modint<mod>(val * o.val);}   
    template<class T> modint<mod>& operator *= (const T o) { return *this = modint<mod>(val * normalize(o));}

    modint<mod>& operator++() { return *this += 1;}
    modint<mod>& operator--() { return *this -= 1;}

    modint<mod> operator + (const modint<mod> o) { return modint<mod>(val + o.val);}   
    template<class T> modint<mod> operator + (const T o) { return modint<mod>(val + o);}   
    modint<mod> operator - (const modint<mod> o) { return modint<mod>(val - o.val);}   
    template<class T> modint<mod> operator - (const T o) { return modint<mod>(val - o);}   
    modint<mod> operator * (const modint<mod> o) { return modint<mod>(val * o.val);}   
    template<class T> modint<mod> operator * (const T o) { return modint<mod>(val * o);}

    bool operator == (const modint<mod> o) { return val == o.val;}
    template<class T> bool operator == (const T o) { return val == normalize(o);}
    bool operator != (const modint<mod> o) { return val != o.val; }
    template<class T> bool operator != (const T o) { return val != normalize(o);}

    bool operator < (const modint<mod> o) { return val < o.val;}
    template<class T> bool operator < (const T o) { return val < normalize(o);}

    modint<mod>& operator /= (const modint<mod> o) { return *this *= o.inv();}
    template<class T> modint<mod>& operator /= (const T o) { return *this *= modint<mod>(o).inv();}
    modint<mod> operator / (modint<mod> o) {modint<mod> ans(val); return ans * o.inv();}
    template<class T> modint<mod> operator / (T o) { return modint<mod>(val) / modint<mod>(o);}

    modint<mod> inv() { return fexp(*this, mod - 2);}

    friend istream& operator >> (istream& in, modint<mod>& n)
    {
        ll x; in >> x;
        n = modint<mod>(x);
        return in;
    }

    friend ostream& operator << (ostream& out, const modint<mod>& n)
    {
        return out << n.val;
    }
};

template<class T>
T fexp(T b, ll x)
{
    T ans(1);

    while(x)
    {
        if(x & 1LL) ans = ans * b;
        b = b * b;
        x >>= 1LL;
    }

    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cout.precision(10);
    
    int n; ll k;
    cin >> n >> k;

    matrix<modint<MOD>, 50, 50> mat;

    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            cin >> mat[i][j];

    mat = fexp(mat, k);
    
    modint<MOD> ans = 0;

    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            ans += mat[i][j];

    cout << ans << endl;

    return 0;
}