/*
* Problem :: 10830 / 행렬 제곱
*
* Kind :: Divide And Conquer
*
* Insight
* - 행렬 A 의 B 제곱
* max(B)=10^11 이니...
* A * A * A * ... * A 로는 무조건 시간초과다
* + 분할정복을 이용해서 거듭제곱을 해야한다
* A^B 에서 B 가 짝수면, A^B = A^(B/2) * A^(B/2)
* A^B 에서 B 가 홀수면, A^B = A^((B-1)/2) * A^((B-1)/2) * A
* # 이렇게 계산한다면,
* A^17 을 구할 때
* A^17 = A^8 * A^8 * A
* A^8 = A^4 * A^4
* A^4 = A^2 * A^2
* A^2 = A^1 * A^1
* A^1 = A^0 * A^0 * A
* 로, 필요에 따라 A^17, A^8, A^4, A^2, A^1 을 구하여서
* 훨씬 효율적으로 계산할 수 있게 된다
* -> 이 경우, 시간복잡도는 일일이 계산하는 O(B) 에 비해
* O(logB) 가 걸리게 되어 시간초과를 피할 수 있다
*
* Point
* - max(B)=10^11 이므로
* long 자료형을 사용해야 한다
* + 무심코 int 자료형 사용했다가 틀렸다
*
* - 다음과 같은 입력이 주어졌을 때,
* 2 1
* 1000 1000
* 1000 1000
* + 출력은 다음과 같아야 한다
* 0 0
* 0 0
* # A^B 의 각 원소를 1,000 으로 나눈 나머지를 출력해야되니
* 문제의 설명을 자세히 읽어보면 당연한 예외처리지만...
* 질문 검색을 통해 겨우 알아낼 수 있었다 ㅠㅠ
* -> 이런 예외 케이스를 찾는 눈썰미를 좀더 키워야겠다
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <vector>
#include <map>
using namespace std;
#define endl '\n'
// Set up : Global Variables
int N;
long B;
typedef vector<vector<int>> Matrix;
map<int,Matrix> dp;
#define MOD 1000
// Set up : Functions Declaration
Matrix pow(long e);
Matrix mul(Matrix U, Matrix V);
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
cin >> N >> B;
Matrix A(N, vector<int>(N));
for (int i=0; i<N; i++)
for (int j=0; j<N; j++)
cin >> A[i][j];
// Process
/* 다음과 같은 입력들의 예외처리
* 2 1
* 1000 1000
* 1000 1000 */
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
A[i][j] %= MOD;
}
}
/* 항등행렬 */
Matrix E(N, vector<int>(N));
for (int i=0; i<N; i++) {
E[i][i] = 1;
}
dp[0] = E;
dp[1] = A;
Matrix ANS = pow(B);
// Control : Output
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
cout << ANS[i][j] << ' ';
} cout << endl;
}
}
// Helper Functions
Matrix pow(long e)
/* 행렬 A 의 e 제곱 반환 */
{
if (e == 0 || e == 1) return dp[e];
if (dp.find(e) != dp.end()) return dp[e];
/* e 가 홀수면,
* A^e = A^e = A^((e-1)/2) * A^((e-1)/2) * A
* 그러나 로직 상 코드가 너무 길어지기에 다음과 두번에 걸쳐서 계산
* A^e = A^(e-1) * A
* A^e-1 = A^((e-1)/2) * A^((e-1)/2)
* 즉, e 를 짝수로 만들어서 한번 더 계산해 주는 식으로 구현 */
return dp[e] = (e%2) ? mul(pow(e-1), pow(1)) : mul(pow(e/2), pow(e/2));
}
Matrix mul(Matrix U, Matrix V)
/* 행렬 U 와 행렬 V 의 곱을 반환 */
{
Matrix R(N, vector<int>(N, 0));
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
for (int k=0; k<N; k++) {
R[i][j] += U[i][k] * V[k][j];
} R[i][j] %= MOD;
}
}
return R;
}