#define INPUT "./io/test.in"
#define OUTPUT "./io/test.out"
// clang-format off
	#ifdef NARUT_LOCAL
	#include "local.hpp"
	#include "reopen.hpp"
	#else
	#pragma GCC optimize("-O2", "-ftree-vectorize")
	#include <algorithm>
	#include <array>
	#include <bitset>
	#include <cassert>
	#include <cctype>
	#include <cmath>
	#include <complex>
	#include <cstdint>
	#include <cstdio>
	#include <cstdlib>
	#include <cstring>
	#include <deque>
	#include <exception>
	#include <functional>
	#include <initializer_list>
	#include <iomanip>
	#include <iostream>
	#include <iterator>
	#include <limits>
	#include <list>
	#include <locale>
	#include <map>
	#include <memory>
	#include <numeric>
	#include <queue>
	#include <random>
	#include <set>
	#include <sstream>
	#include <stack>
	#include <stdexcept>
	#include <tuple>
	#include <type_traits>
	#include <utility>
	#include <vector>
	using namespace std;
	#define DBG(...)
	#define DBG2(...)
	#define Debug(...)
	#define TM_(...) template <class __VA_ARGS__>
	#define ENABLE(...) TM_(T) static enable_if_t<__VA_ARGS__>
	#define SFINAE(name, ...)                                                                \
		TM_(, class = void) struct name##_s : false_type {};                                 \
		TM_(T) struct name##_s<T, decltype(void(__VA_ARGS__))> : true_type {};               \
		TM_(T) constexpr auto name = name##_s<T>::value;
	namespace narut {
	TM_(T) using TupSz = tuple_size<decay_t<T>>;
	SFINAE(Iterable, begin(declval<T &>()))
	SFINAE(IsTuple, TupSz<T>{})
	SFINAE(Coutable, cout << declval<T &>())
	SFINAE(Cinable, cin >> declval<T &>())
	TM_(, class = void) struct Spc { static const char val = '\n'; };
	TM_(T) struct Spc<T, enable_if_t<Coutable<T>>> { static const char val = ' '; };
	struct Ctx {
		ENABLE(Coutable<T>) Write(T const &t) { cout << t; }
		ENABLE(!Coutable<T> and Iterable<T>) Write(T const &t) {
			auto it = begin(t), e = end(t);
			if (it != e) Write(*it++);
			for (; it != e; Write(*it++)) cout << Spc<decltype(*it)>::val;
		}
		TM_(T, size_t... Is)
		static void WriteTup(T const &t, index_sequence<Is...>) {
			(void)(int[]){0, ((Is == 0) ? 0 : ((cout << ' '), 0), Write(get<Is>(t)), 0)...};
		}
		ENABLE(!Coutable<T> and !Iterable<T> and IsTuple<T>) Write(T const &t) {
			WriteTup(t, make_index_sequence<TupSz<T>::value>{});
		}
		ENABLE(Cinable<T>) Read(T &t) { cin >> t; }
		ENABLE(!Cinable<T> and Iterable<T>) Read(T &t) {
			for (auto &&x : t) Read(x);
		}
		TM_(T, size_t... Is) static void ReadTup(T &t, index_sequence<Is...>) {
			(void)(int[]){0, (Read(get<Is>(t)), 0)...};
		}
		ENABLE(!Cinable<T> and !Iterable<T> and IsTuple<T>) Read(T &t) {
			ReadTup(t, make_index_sequence<TupSz<T>::value>{});
		}
	};
	void Cout() { cout << '\n'; }
	TM_(F, class... Ts) void Cout(F const &f, Ts const &... ts) {
		Ctx::Write(f);
		(void)(int[]){0, (cout << ' ', Ctx::Write(ts), 0)...};
		cout << '\n';
	}
	TM_(T) T Cin() {
		T t;
		Ctx::Read(t);
		return t;
	}
	TM_(T) void Cin(T &t) { Ctx::Read(t); }
	TM_(T) void Cin(T &t, int n) {
		t.resize(n);
		Ctx::Read(t);
	}
	TM_(T) struct Big {
		constexpr operator T() const {
			T x = 0, mask = 0x3f;
			for (int i = 0; i < sizeof(T); i++) x |= mask << 8 * i;
			return x;
		}
	};
	} // namespace narut
	using narut::Big;
	using narut::Cin;
	using narut::Cout;
	using ll = long long;

	using uint = unsigned int;
	#endif
// clang-format on

template <class T, class AddT, class MultT, T P>
struct ModNum {
    T val = 0;
    constexpr ModNum() = default;
    constexpr ModNum(T x) : val(x) {}
    template <class S>
    static constexpr ModNum Safe(S x) {
        return static_cast<T>(((x % P) + P) % P);
    }
    explicit constexpr operator T() const { return val; }

    constexpr bool operator==(ModNum rhs) const { return val == rhs.val; }
    constexpr bool operator!=(ModNum rhs) const { return val != rhs.val; }
    constexpr ModNum operator-() const { return (val == 0) ? (*this) : (P - val); }

    constexpr ModNum& operator+=(ModNum rhs) { return *this = Add(val, rhs.val); }
    constexpr ModNum& operator-=(ModNum rhs) { return *this = Sub(val, rhs.val); }
    constexpr ModNum& operator*=(ModNum rhs) { return *this = Mult(val, rhs.val); }
    constexpr ModNum& operator/=(ModNum rhs) { return *this *= rhs.Inverse(); }

    template <class S>
    constexpr ModNum Pow(S ex) const {
        if (P == 1) return 0;
        if (ex < 0) return Pow(-ex).Inverse();
        ModNum result = 1;
        ModNum base(*this);
        while (ex > 0) {
            if (ex & 1) result *= base;
            ex >>= 1;
            base *= base;
        }
        return result;
    }
    constexpr ModNum Inverse() const { return Pow(P - 2); }
    friend constexpr ModNum operator+(ModNum lhs, ModNum rhs) { return Add(lhs.val, rhs.val); }
    friend constexpr ModNum operator-(ModNum lhs, ModNum rhs) { return Sub(lhs.val, rhs.val); }
    friend constexpr ModNum operator*(ModNum lhs, ModNum rhs) { return Mult(lhs.val, rhs.val); }
    friend constexpr ModNum operator/(ModNum lhs, ModNum rhs) { return lhs * rhs.Inverse(); }

   private:
    static constexpr T Add(AddT lhs, AddT rhs) {
        auto sum = lhs + rhs;
        return (sum < P) ? sum : (sum - P);
    }
    static constexpr T Sub(AddT lhs, AddT rhs) {
        auto dif = lhs - rhs;
        return (dif >= 0) ? dif : (dif + P);
    }
    static constexpr T Mult(MultT lhs, MultT rhs) { return static_cast<T>((lhs * rhs) % P); }
    friend std::ostream& operator<<(std::ostream& os, ModNum m) { return os << m.val; }
    friend std::istream& operator>>(std::istream& is, ModNum& m) {
        is >> m.val;
        return is;
    }
};
using Num = ModNum<int, int, long long, 1000000007>;



namespace LinAlg {
	template <class T> struct Matrix {
		struct Row {
			Matrix &mat;
			uint r;
			T const &operator[](uint j) const {
            #ifdef _GLIBCXX_DEBUG
				if (j >= mat.n)
					throw out_of_range("Indexing " + to_string(j) + " m = " + to_string(mat.n));
            #endif
				return mat.arr[r * mat.n + j];
			}
			T &operator[](uint j) {
            #ifdef _GLIBCXX_DEBUG
				if (j >= mat.n)
					throw out_of_range("Indexing " + to_string(j) + " m = " + to_string(mat.n));
            #endif
				return mat.arr[r * mat.n + j];
			}
		};
		struct CRow {
			Matrix const &mat;
			uint r;
			T const &operator[](uint j) const {
            #ifdef _GLIBCXX_DEBUG
				if (j >= mat.n)
					throw out_of_range("Indexing " + to_string(j) + " m = " + to_string(mat.n));
            #endif
				return mat.arr[r * mat.n + j];
			}
		};
		uint m = 0, n = 0;
		vector<T> arr;
		Matrix() = default;
		explicit Matrix(uint m, uint n) : m(m), n(n), arr(m * n) {}
		explicit Matrix(uint m, uint n, T val) : m(m), n(n), arr(m * n, val) {}

		template <class U>
		Matrix(Matrix<U> const &other)
			: m(other.m), n(other.n), arr(other.arr.begin(), other.arr.end()) {}

		Row operator[](uint i) {
            #ifdef _GLIBCXX_DEBUG
			if (i >= m) throw out_of_range("Indexing " + to_string(i) + " m = " + to_string(m));
            #endif
			return Row{*this, i};
		}
		CRow operator[](uint i) const {
            #ifdef _GLIBCXX_DEBUG
			if (i >= m) throw out_of_range("Indexing " + to_string(i) + " m = " + to_string(m));
            #endif
			return CRow{*this, i};
		}

		auto begin() { return arr.begin(); }
		auto begin() const { return arr.begin(); }
		auto end() { return arr.end(); }
		auto end() const { return arr.end(); }

		template <class U> Matrix &operator+=(Matrix<U> const &A) {
			for (uint i = 0; i < arr.size(); i++) arr[i] += A.arr[i];
			return *this;
		}

		template <class U> Matrix &operator-=(Matrix<U> const &A) {
			for (uint i = 0; i < arr.size(); i++) arr[i] -= A.arr[i];
			return *this;
		}

        void Fill(T const& t) { fill(arr.begin(), arr.end(), t); }

		void Reshape(uint m, uint n) {
			this->m = m, this->n = n;
			arr.resize(m * n);
		}

		Matrix &Transpose() { swap(m, n); }

		template <class S> static Matrix PowImpl(const Matrix &A, S p) {
			if (p == 1) return A;
			auto res = PowImpl(A, p / 2);
			if (p % 2) return res * res * A;
			return res * res;
		}

		template <class S> Matrix Pow(S p) const {
			if (m != n) throw out_of_range("Can't square a non square matrix");
			if (p == 0) return Identity(m);
			return PowImpl(*this, p);
		}

		friend ostream &operator<<(ostream &os, const Matrix &A) {
			if (A.arr.size() == 0) return os;
			for (uint i = 0, k = 0;;) {
				os << A.arr[i];
				if (++i == A.arr.size()) return os;
				if (++k == A.n) {
					os << '\n';
					k = 0;
				} else
					os << ' ';
			}
		}

		static auto Identity(uint n) {
			Matrix out(n, n);
			for (uint i = 0; i < n; i++) out[i][i] = 1;
			return out;
		}
	};

	template <class T, class C, class V = decltype(declval<T>() * declval<C>()[0])>
	auto operator*(Matrix<T> const &A, C const &B) {
		vector<V> out(A.m);
		for (uint i = 0; i < A.m; i++) {
			for (uint k = 0; k < A.n; k++) {
				out[i] += A[i][k] * B[k];
			}
		}
		return out;
	}

	template <class T, class C, class V = decltype(declval<T>() * declval<C>()[0])>
	auto operator*(C const &A, Matrix<T> const &B) {
		vector<V> out(B.n);
		for (uint k = 0; k < A.m; k++) {
			for (uint j = 0; j < B.n; j++) {
				out[j] += A[k][j] * B[k];
			}
		}
		return out;
	}

	template <class T, class U, class V = decltype(declval<T>() * declval<U>())>
	auto operator*(Matrix<T> const& A, Matrix<U> const& B) {
		if (A.n != B.m) throw out_of_range("Matrix mult: Dimensions don't agree.");
		Matrix<V> out(A.m, B.n);
		for (uint i = 0; i < A.m; i++) {
			for (uint j = 0; j < B.n; j++) {
				for (uint k = 0; k < A.n; k++) {
					out[i][j] += A[i][k] * B[k][j];
				}
			}
		}
		return out;
	}

	template <class T, class D, class U, class E, class V = decltype(declval<T>() + declval<U>())>
	auto operator+(Matrix<T> const& A, Matrix<U> const& B) {
		Matrix<V> out(A);
		out += B;
		return out;
	}

	template <class T, class D, class U, class E, class V = decltype(declval<T>() + declval<U>())>
	auto operator-(Matrix<T> const& A, Matrix<U> const& B) {
		Matrix<V> out(A);
		out -= B;
		return out;
	}
} // namespace LinAlg
// template <class T> using Mat = LinAlg::Matrix<T>;
using Mat = LinAlg::Matrix<Num>;



auto Run() {
	int n; ll k;
	cin>>n>>k;
	Mat adj(n, n);
	Cin(adj);

	auto res = adj.Pow(k);

	Num ans;
	for (auto r : res) ans += r;
	
	cout << ans;		
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(10);

	Run();
}



Measured memory_bytes: 256