Problem:
Problem D:
Life Game
You are working at a production plant of biological weapons. You are a maintainer of a terrible virus weapon
with very high reproductive power. The virus has a tendency to build up regular hexagonal colonies. So as a
whole, the virus weapon forms a hexagonal grid, each hexagon being a colony of the virus. The grid itself is in
the regular hexagonal form with
N
colonies on each edge.
The virus self-propagates at a constant speed. Self-propagation is performed simultaneously at all colonies.
When it is done, for each colony, the same number of viruses are born at every neighboring colony. Note that,
after the self-propagation, if the number of viruses in one colony is more than or equal to the limit density
M
,
then the viruses in the colony start self-attacking, and the number reduces modulo
M
.
Your task is to calculate the total number of viruses after
L
periods, given the size
N
of the hexagonal grid and
the initial number of viruses in each of the colonies.
Input
The input consists of multiple test cases.
Each case begins with a line containing three integers
N
(1 ≤
N
≤ 6),
M
(2 ≤
M
≤ 10
9
), and
L
(1 ≤
L
≤ 10
9
).
The following 2
N
- 1 lines are the description of the initial state. Each non-negative integer (smaller than
M
)
indicates the initial number of viruses in the colony. The first line contains the number of viruses in the
N
colonies
on the topmost row from left to right, and the second line contains those of
N
+ 1 colonies in the next row, and
so on.
The end of the input is indicated by a line “0 0 0”.
Output
For each test case, output the test case number followed by the total number of viruses in all colonies after
L
periods.
Sample Input
3 3 1
1 0 0
0 0 0 0
0 0 0 0 0
0 0 0 0
0 0 1
3 3 2
1 0 0
0 0 0 0
0 0 0 0 0
0 0 0 0
0 0 1
0 0 0
Output for the Sample Input
Case 1: 8
Case 2: 18

Submitted solutions:

code_snippet: #include<stdio.h>
#include<string.h>
 
int dir[18][2] =
{
    { -1, -1,}, { -1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1},
    { -1, -1,}, { -1, 0}, {0, -1}, {0, 1}, {1, -1}, {1, 0},
    { -1, 0,}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}
};
 
long long int mlen[21];
long long int msle[21];
long long int bl, m, l, sn;
long long int n;
 
long long int map[101];
long long int res[101];
long long int ret[101][101];
long long int Mat[101][101];
long long int temp[101][101];
 
void make_mlen()
{
    int i, j;
    sn = bl * 2 - 1;
 
    for( i = 0 ; i < bl; i++)
        mlen[i] = i + bl;
 
    for( j = bl - 2; j >= 0 ; j--)
        mlen[i++] = mlen[j];
 
    msle[0] = 0;
    for( i = 1; i <= sn ; i++)
        msle[i] = msle[i - 1] + mlen[i - 1];
 
    n = msle[sn];
}
 
void input()
{
    int i;
    for( i = 0 ; i < n; i++)
        scanf("%lld", &map[i]);
}
 
void make_matrix()
{
    int i, j, k, ii, jj, kk;
    memset(Mat, 0, sizeof(Mat));
 
    for( i = 0 ; i < sn; i++)
    {
        for(j = 0 ; j < mlen[i] ; j++)
        {
            Mat[msle[i] + j][msle[i] + j] = 1;
            for( k = 0 ; k < 6 ; k++)
            {
                if( i < bl - 1 )
                    kk = 0;
                else if( i == bl - 1)
                    kk = 6;
                else
                    kk = 12;
 
                ii = i + dir[kk + k][0];
                jj = j + dir[kk + k][1];
 
                if( ii < 0 || ii >= sn || jj < 0 || jj >= mlen[ii])
                    continue;
 
                Mat[msle[i] + j][msle[ii] + jj] = 1;
            }
        }
    }
}
void matmul(long long int a[][101], long long int b[][101])
{
    int i, k, j;
 
    memset(temp, 0, sizeof(temp));
 
    for(i = 0; i < n; i++)
        for(k = 0; k < n; k++)
            if(a[i][k])
                for(j = 0; j < n; j++)
                    if( b[k][j] )
                        temp[i][j] = (temp[i][j] + a[i][k] * b[k][j]) % m;
 
    memcpy(a, temp, sizeof(temp));
}
 
void init_()
{
    int i, j;
    for(i = 0; i < n; i++)
        for(j = 0; j < n; j++)
            ret[i][j] = (i == j);
}
void q_mod(int k)
{
    init_();
    for(; k ; k >>= 1)
    {
        if(k & 1)
            matmul(ret, Mat);
        matmul(Mat, Mat);
    }
}
 
long long int solve()
{
    long long int i, j, sum, ans = 0;
    for(i = 0; i < n; i++)
    {
        sum = 0;
        for( j = 0; j < n; j++)
        {
            sum = (sum + map[j] * ret[i][j]) % m;
        }
        res[i] = sum;
    }
    for( i = 0 ; i < n ; i++)
        ans += res[i]; 
    return ans;
}
 
int main()
{
    int i, j, k = 0;
    while(scanf("%lld%lld%lld", &bl, &m, &l), bl + m + l)
    {
        k++;
        make_mlen();
        make_matrix();
        input();
        q_mod(l);
        printf("Case %d: %lld\n", k, solve());
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 3192
final_rank: 5

code_snippet: // AOJ #2115
// Life Game 2025.2.10

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

ll mulmod(ll a, ll b, ll M) {
    __int128 temp = ( __int128 ) a * b;
    return (ll)(temp % M);
}

vector<vector<ll>> matmul(const vector<vector<ll>>& A,
        const vector<vector<ll>>& B, ll M) {
    int n = (int)A.size();
    vector<vector<ll>> C(n, vector<ll>(n, 0LL));
    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            __int128 sum = 0;
            for(int k=0; k<n; k++)
                sum += (__int128)A[i][k] * B[k][j];
            C[i][j] = (ll)(sum % M);
        }
    }
    return C;
}

vector<vector<ll>> matpow(vector<vector<ll>> base, ll e, ll M){
    int n = (int)base.size();
    vector<vector<ll>> ans(n, vector<ll>(n, 0LL));
    for(int i=0; i<n; i++) ans[i][i] = 1;

    while(e > 0){
        if(e & 1) ans = matmul(ans, base, M);
        base = matmul(base, base, M);
        e >>= 1;
    }
    return ans;
}

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

    ll N, M, L;
    int caseNo = 1;
    while(true){
        cin >> N >> M >> L;
        if (N==0) break;

        int totalCells = 0;
        vector<int> rowLen(2*N-1);
        for(int r=0; r<(int)(2*N-1); r++){
            if(r < (int)N) rowLen[r] = N + r;
            else           rowLen[r] = 3*N - 2 - r;
            totalCells += rowLen[r];
        }

        vector<ll> initVirus(totalCells);
        {
            int idx = 0;
            for(int r=0; r<(int)(2*N-1); r++){
                for(int c=0; c<rowLen[r]; c++){
                    ll x; 
                    cin >> x;
                    initVirus[idx++] = x;
                }
            }
        }

        vector<vector<ll>> A_mat(totalCells, vector<ll>(totalCells, 0LL));

        auto getIndex = [&](int r, int c){
            int idx = 0;
            for(int rr=0; rr<r; rr++){
                idx += rowLen[rr];
            }
            return idx + c;
        };

        for(int r=0; r<(int)(2*N-1); r++){
            for(int c=0; c<rowLen[r]; c++){
                int i = getIndex(r, c);
                

                if(c-1 >= 0){
                    int j = getIndex(r, c-1);
                    A_mat[i][j] = 1;
                }
                if(c+1 < rowLen[r]){
                    int j = getIndex(r, c+1);
                    A_mat[i][j] = 1;
                }

                if(r-1 >= 0){
                    int upperLen = rowLen[r-1];
                    if(r <= N-1){
                        if(c < upperLen){
                            int j = getIndex(r-1, c);
                            A_mat[i][j] = 1;
                        }
                        if(c-1 >= 0 && (c-1) < upperLen){
                            int j = getIndex(r-1, c-1);
                            A_mat[i][j] = 1;
                        }
                    } else {
                        if(c < upperLen){
                            int j = getIndex(r-1, c);
                            A_mat[i][j] = 1;
                        }
                        if(c+1 < upperLen){
                            int j = getIndex(r-1, c+1);
                            A_mat[i][j] = 1;
                        }
                    }
                }

                if(r+1 < (int)(2*N-1)){
                    int lowerLen = rowLen[r+1];
                    if(r < N-1){
                        if(c < lowerLen){
                            int j = getIndex(r+1, c);
                            A_mat[i][j] = 1;
                        }
                        if(c+1 < lowerLen){
                            int j = getIndex(r+1, c+1);
                            A_mat[i][j] = 1;
                        }
                    } else {
                        if(c >= 0 && c < lowerLen){
                            int j = getIndex(r+1, c);
                            A_mat[i][j] = 1;
                        }
                        if(c-1 >= 0 && c-1 < lowerLen){
                            int j = getIndex(r+1, c-1);
                            A_mat[i][j] = 1;
                        }
                    }
                }
            }
        }

        vector<vector<ll>> B(totalCells, vector<ll>(totalCells, 0LL));
        for(int i=0; i<totalCells; i++){
            for(int j=0; j<totalCells; j++) B[i][j] = A_mat[i][j];
            B[i][i] ++;
            B[i][i] %= M;
        }

        vector<vector<ll>> BL = matpow(B, L, M);

        vector<ll> xL(totalCells, 0LL);
        for(int i=0; i<totalCells; i++){
            __int128 sum = 0;
            for(int j=0; j<totalCells; j++)
                sum += (__int128)BL[i][j] * initVirus[j];
            xL[i] = (ll)(sum % M);
        }
        ll ans = 0;
        for(int i=0; i<totalCells; i++) ans += xL[i];
        cout << "Case " << caseNo++ << ": " << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3660
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define reps(i, s, n) for(int i = (s); i < n; ++i)
#define rep(i, n) reps(i, 0, n)
#define ALL(v) v.begin(), v.end()

using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;

int N, M, L;

struct hexa{
    vec pos;
    hexa(vec v = {}) : pos(3, 0){
        if(v.size() == 3) rep(i, 3) pos[i] = v[i];
        fix();
    }

    void fix(){
        while(*min_element(ALL(pos)) < 0) rep(i, 3) ++pos[i];
        while(*min_element(ALL(pos)) > 0) rep(i, 3) --pos[i];
    }

    bool ok(){
        fix();
        return *max_element(ALL(pos)) < N;
    }

    int hash() const{
        if(pos[2]){
            return N * N + (pos[2] - 1) * N * 2 + (pos[0] ? pos[0] : N + pos[1]);
        }else{
            return pos[0] * N + pos[1];
        }
    }

    void makedp(mat &dp){
        int myh = (*this).hash();
        dp[myh][myh] = 1;
        rep(i, 3){
            for(int diff : {-1, 1}){
                hexa nxt(*this);
                nxt.pos[i] += diff;
                if(nxt.ok()) dp[myh][nxt.hash()] = 1;
            }
        }
    }
};

void myinput(hexa &state, mat &dp, vec &V){
    while(state.ok()){
        //dp setting
        state.makedp(dp);
        //input
        int value; cin>>value;
        V[state.hash()] = value;
        //next
        ++state.pos[0];
        state.fix();
    }
}

mat mul(mat &a, mat &b){
    mat res(a.size(), vec(b[0].size()));
    rep(i, a.size()){
        rep(j, b[0].size()){
            rep(k, b.size()) (res[i][j] += a[i][k] * b[k][j] % M) %= M;
        }
    }
    return res;
}

ll solve(mat dp, vec V){
    int sz = dp.size();
    mat temp(sz, vec(sz, 0));
    rep(i, sz) temp[i][i] = 1;
    while(L){
        if(L&1) temp = mul(dp, temp);
        dp = mul(dp, dp);
        L >>= 1;
    }
    mat v(1);
    v[0] = V;
    mat res = mul(v, temp);
    ll Res(0);
    rep(i, sz) Res += res[0][i];
    return Res;
}

int main(){
    int num = 1;
    while(cin>>N>>M>>L, N){
        int hash_sz = N * N * 3 - N * 2;
        vec V(hash_sz);
        mat dp(hash_sz, vec(hash_sz, 0));
        for(int k = 0; k < N; ++k){
            hexa state({0, N - 1, k});
            myinput(state, dp, V);
        }

        for(int j = N - 2; j >= 0; --j){
            hexa state({0, j, N - 1});
            myinput(state, dp, V);
        }

        cout<<"Case "<<num<<": "<<solve(dp, V)<<endl;
        ++num;
    }
}
accuracy: 1
time_ms: 1170
memory_kb: 3448
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


typedef vector<ll> V;
typedef vector<V> MATRIX;

int num_station,N,M,L,case_num=1;
int SIZE,CALC_SIZE;
int diff_row[7] = {-1,-1,0,0,0,1,1},diff_col[7] = {-1,0,-1,0,1,0,1};


bool rangeCheck(int row,int col){
	if(row < 0 || row >= 2*N-1)return false;

	if(row < N){
		if(col >= 0 && col < N+row)return true;
		else{
			return false;
		}
	}else{
		if(col >= row-N+1 && col <= 2*N-2)return true;
		else{
			return false;
		}
	}
}

MATRIX calc_ans(MATRIX left, MATRIX right){
    MATRIX RET(CALC_SIZE,V(1));
    for(int row = 0; row < CALC_SIZE; row++){
        for(int col = 0; col < 1; col++){
            RET[row][col] = 0;
            for(int k = 0; k < CALC_SIZE; k++){
                RET[row][col] += left[row][k]*right[k][col];
                RET[row][col] %=M;
            }
        }
    }
    return RET;
}



MATRIX calc(MATRIX left,MATRIX right){

	MATRIX ret(CALC_SIZE,V(CALC_SIZE));

	for(int i = 0; i < CALC_SIZE; i++){
		for(int k = 0; k < CALC_SIZE; k++)ret[i][k] = 0;
	}

	for(int row = 0; row < CALC_SIZE; row++){
		for(int col = 0; col < CALC_SIZE; col++){
			for(int a = 0; a < CALC_SIZE; a++){
				ret[row][col] += left[row][a]*right[a][col];
				ret[row][col] %= M;
			}
		}
	}

	return ret;

}

MATRIX pow(MATRIX MULT,int count){

	MATRIX ret(CALC_SIZE,V(CALC_SIZE));

	for(int row = 0; row < CALC_SIZE; row++){
		for(int col = 0; col < CALC_SIZE; col++){
			if(row == col)ret[row][col] = 1;
			else{
				ret[row][col] = 0;
			}
		}
	}

	while(count > 0){
		if(count%2 == 1)ret = calc(ret,MULT);
		MULT = calc(MULT,MULT);
		count /= 2;
	}

	return ret;
}

void func(){

	SIZE = 2*N-1;

	MATRIX TATE(SIZE*SIZE,V(1));

	for(int row = 0; row < SIZE*SIZE; row++){
		TATE[row][0] = 0;
	}

	for(int row = 0; row < SIZE; row++){
		if(row < N){
			for(int col = 0; col < N+row; col++){
				scanf("%lld",&TATE[row*SIZE+col][0]);
			}
		}else{
			for(int col = row-N+1; col < SIZE; col++){
				scanf("%lld",&TATE[row*SIZE+col][0]);
			}
		}
	}

	CALC_SIZE = SIZE*SIZE;
	MATRIX POWER(CALC_SIZE,V(CALC_SIZE));

	for(int row = 0; row < SIZE; row++){
		if(row < N){
			for(int col = 0; col < N+row; col++){
				for(int k = 0; k < 7; k++){
					if(rangeCheck(row+diff_row[k],col+diff_col[k])){
						POWER[row*SIZE+col][(row+diff_row[k])*SIZE+col+diff_col[k]] = 1;
					}
				}
			}
		}else{
			for(int col = row-N+1; col < SIZE; col++){
				for(int k = 0; k < 7; k++){
					if(rangeCheck(row+diff_row[k],col+diff_col[k])){
						POWER[row*SIZE+col][(row+diff_row[k])*SIZE+col+diff_col[k]] = 1;
					}
				}
			}
		}
	}

	if(L > 1){
		POWER = pow(POWER,L);
	}

	TATE = calc_ans(POWER,TATE);

	ll ans = 0;

	for(int row = 0; row < CALC_SIZE; row++){
		ans += TATE[row][0];
	}

	printf("Case %d: %lld\n",case_num++,ans);
}


int main(){

	while(true){
		scanf("%d %d %d",&N,&M,&L);
		if(N == 0 && M == 0 && L == 0)break;

		func();
	}


	return 0;
}
accuracy: 1
time_ms: 1950
memory_kb: 3620
final_rank: 16

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;



 int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

vector<pair<int, int>>get_connect(int N, int x, int y) {
	vector<pair<int,int>>anss;
	{
		int ax=x-1;
		int ay=y;
		anss.emplace_back(ax,ay);
	}
	{
		int ax=x+1;
		int ay=y;
		anss.emplace_back(ax, ay);

	}

	//lu
	{
		int ax,ay;
		if (y < N) {
			ax=x-1;
			ay=y-1;
		}
		else {
			ax=x;
			ay=y-1;
		}
		anss.emplace_back(ax, ay);

	}

	//ru
	{
		int ax,ay;
		if (y < N) {
			ax=x;
			ay=y-1;
		}
		else {
			ax=x+1;
			ay=y-1;
		}
		anss.emplace_back(ax, ay);

	}

	//ld
	{
		int ax,ay;
		if (y < N - 1) {
			ax=x;
			ay=y+1;
		}
		else {
			ax=x-1;
			ay=y+1;
		}
		anss.emplace_back(ax, ay);

	}
	//rd
	{
		int ax,ay;
		if (y < N - 1) {
			ax=x+1;
			ay=y+1;
		}
		else {
			ax=x;
			ay=y+1;
		}
		anss.emplace_back(ax, ay);

	}
	vector<pair<int,int>>real_anss;
	for (auto ans : anss) {
		int ax(ans.first);
		int ay(ans.second);
		bool ok=true;
		if(ay<0||ay>=2*N-1)ok=false;
		if (ay < N) {
			if(ax<0||ax>=N+ay)ok=false;
		}
		else {
			if (ax < 0 || ax>=3*N-ay-2)ok=false;
		}
		if(ok)real_anss.emplace_back(ans);
	}
	return real_anss;
}


template<typename T>
vector<vector<T>> keisann(const vector<vector<T>>l, const vector<vector<T>>r) {
	vector<vector<T>>ans(l.size(), vector<T>(r[0].size()));
	assert(l[0].size() == r.size());
	for (unsigned int h = 0; h < l.size(); ++h) {
		for (unsigned int i = 0; i < r.size(); ++i) {
			for (unsigned int w = 0; w < r[0].size(); ++w) {

				ans[h][w] += l[h][i] * r[i][w];
			}
		}
	}
	return ans;
}

template<typename T>
vector<vector<T>>powgyou(vector<vector<T>>a, const long long int n) {
	assert(a.size() == a[0].size());
	if (!n) {
		vector<vector<T>>e(a.size(), vector<T>(a[0].size()));
		for (unsigned int i = 0; i < a.size(); ++i) {
			e[i][i] = 1;
		}
		return e;
	}
	if (n == 1)return a;
	else {
		vector<vector<T>>ans(a.size(), vector<T>(a[0].size(), 0));
		ans = powgyou(a, n / 2);
		ans = keisann(ans, ans);
		if (n % 2) {
			ans = keisann(ans, a);
		}
		return ans;
	}
}


int main() {
	int case_id=0;
	while (true) {
		case_id++;
		int N, M, L; cin >> N >> M >> L;
		mod=M;
		if(!N)break;
		vector<vector<int>>v(2 * N - 1);
		int num = 0;
		map<pair<int, int>, int>mp;
		for (int i = 0; i < v.size(); ++i) {
			int asize = N + i;
			if (i>=N)asize = N + (v.size() - i - 1);
			if (i <= N)v[i].resize(asize);
			else v[i].resize(asize);
			num += asize;
		}
		vector<vector<Mod>>mat(num,vector<Mod>(num));

		{
			int id = 0;
			for (int i = 0; i < v.size(); ++i) {
				for (int j = 0; j < v[i].size(); ++j) {
					mp[make_pair(i, j)] = id++;
				}
			}
		}

		for (int i = 0; i < v.size(); ++i) {
			for (int j = 0; j < v[i].size(); ++j) {
				int now_id = mp[make_pair(i, j)];
				mat[now_id][now_id]=true;
				auto connect(get_connect(N, j, i));
				for (auto con : connect) {
					int next_id = mp[make_pair(con.second, con.first)];
					mat[now_id][next_id] = true;
				}
			}
		}

		vector<vector<Mod>>start(1, vector<Mod >(num));
		{
			int id = 0;
			for (int i = 0; i < v.size(); ++i) {
				for (int j = 0; j < v[i].size(); ++j) {
					int k; cin >> k;
					start[0][id++] = k;
				}
			}
		}
		vector<vector<Mod>>ans_mat = keisann(start, powgyou(mat, L));
		long long int ans = 0;
		for (int i = 0; i < ans_mat.size(); ++i) {
			for (int j = 0; j < ans_mat[i].size(); ++j) {
				ans += ans_mat[i][j].num;
			}
		}
		cout <<"Case "<<case_id<<": "<< ans << endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 3910
memory_kb: 13168
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;

typedef vector<int> vec;
typedef vector<vec> mat;

mat multi(const mat& A, const mat& B, int mod) {
  mat C(A.size(), vec(B[0].size()));
  for(int i = 0; i < A.size(); i++) {
    for(int j = 0; j < B.size(); j++) {
      for(int k = 0; k < B[0].size(); k++) {
	(C[i][k] += A[i][j]*B[j][k]) %= mod;
      }
    }
  }
  return C;
}

mat power(mat A, int n, int mod) {
  mat B(A.size(), vec(A.size()));
  for(int i = 0; i < A.size(); i++) B[i][i] = 1;
  while(n > 0) {
    if(n & 1) B = multi(B, A, mod);
    A = multi(A, A, mod);
    n >>= 1;
  }
  return B;
}

int dy[] = {-1, -1, 0, 0, 1, 1};
int dx[] = {-1, 0, -1, 1, 0, 1};
//int xx[40], yy[40];
//int mas[40][40];
int xx[100], yy[100];
int mas[40][40];

signed main(){
  int N, M, L;
  int tt = 0;
  while(cin >> N >> M >> L, N || M || L) {
    tt++;
    int num = 0;
    int s = 0, t = N-1;
    //vector<pair<int, int> > pos;
    //map<pair<int, int>, int> id;
    memset(xx, -1, sizeof(xx));
    memset(yy, -1, sizeof(yy));
    memset(mas, -1, sizeof(mas));
    for(int i = 0; i < N+N-1; i++) {
      if(i < N) t++;
      else s++;
      for(int j = s; j < t; j++) {
	//cout << num << " " << xx[num] << endl;
	//assert(xx[num] == -1);
	yy[num] = i, xx[num] = j;
	//cout << xx[num] << " " << j << endl;
	mas[i][j] = num;
	//pos.push_back(make_pair(i, j));
	//id[make_pair(i, j)] = num;
	num++;
      }
    }
    mat X(num, vec(1, 0));
    for(int i = 0; i < num; i++){
      cin >> X[i][0];
    }

    mat A(num, vec(num, 0));
    for(int i = 0; i < num; i++) {
      int x = xx[i], y = yy[i];
      //int x, y; tie(x, y) = pos[i];
      //cout << x << " " << xx[i] << endl;
      //assert(x == xx[i] && y == yy[i]);
      for(int j = 0; j < 6; j++) {
	int nx = x + dx[j], ny = y + dy[j];
	if(0 <= nx && nx < N+N-1 &&
	   0 <= ny && ny < N+N-1 &&
	   mas[ny][nx] != -1) {
	  //assert(id.count(make_pair(ny, nx)));
	  A[i][mas[ny][nx]] = 1;
	}
      }
      A[i][i] = 1;
    }

    auto res = power(A, L, M);
    auto ans = multi(res, X, M);
    int out = 0;
    for(int i = 0; i < ans.size(); i++) out += ans[i][0];
    cout << "Case " << tt << ": " << out << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 3256
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for(int i = (int)(s); i < (int)(n); i++)
#define min(...) min({__VA_ARGS__})
#define max(...) max({__VA_ARGS__})

template<class T1, class T2> void chmin(T1 &a, T2 b){if(a>b)a=b;}
template<class T1, class T2> void chmax(T1 &a, T2 b){if(a<b)a=b;}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

typedef vector<int> vec;
typedef vector<vec> mat;

mat multi(const mat& A, const mat& B, const int& mod)
{
  mat C(A.size(), vec(B[0].size()));
  for(int i = 0; i < A.size(); i++) {
    for(int j = 0; j < B.size(); j++) {
      for(int k = 0; k < B[0].size(); k++) {
	(C[i][k] += A[i][j] * B[j][k]) %= mod;
      }
    }
  }
  return C;
}

mat power(mat A, int n, int mod)
{
  mat B(A.size(), vec(A.size()));
  for(int i = 0; i < A.size(); i++) B[i][i] = 1;
  while(n > 0) {
    if(n & 1) B = multi(B, A, mod);
    A = multi(A, A, mod);
    n >>= 1;
  }
  return B;
}

int dy[] = {-1, -1, 0, 0, 1, 1};
int dx[] = {-1, 0, -1, 1, 0, 1};

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int N, M, L;
  for(int T = 1; cin >> N >> M >> L, N || M || L; T++) {
    int num = 0;
    vector<pint> pos;
    map<pint, int> id;
    int s = 0, t = N-1;
    rep(i, N+N-1) {
      if(i < N) t++;
      else s++;
      reps(j, s, t) {
	pos.push_back(make_pair(i, j));
	id[make_pair(i, j)] = num++;
      }
    }
    mat X(num, vec(1));
    rep(i, num) cin >> X[i][0];
    mat A(num, vec(num));
    rep(i, num) {
      int y, x;
      tie(y, x) = pos[i];
      rep(j, 6) {
	int ny = y + dy[j], nx = x + dx[j];
	if(id.count(make_pair(ny, nx))) {
	  A[i][id[make_pair(ny, nx)]] = 1;
	}
      }
      A[i][i] = 1;
    }
    mat Y = power(A, L, M);
    mat Z = multi(Y, X, M);
    int ans = 0;
    rep(i, Z.size()) ans += Z[i][0];
    cout << "Case " << T << ": " << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 3252
final_rank: 11

code_snippet: #include <bits/stdc++.h>
//#include <unordered_map>
#define N 111
#define ID(x, y) (pre[(x)-1]+(y-1))
#define CHECK(x, y) ((x)>0 && (x)<= 2 * n - 1 && (y)>0 && (y)<=(linelimit))
using namespace std;
typedef long long LL;
LL n, mod, m, l;
LL a[N][N], b[N][N], c[N][N], mat[N][N], pre[N];
void mul(LL A[N][N],LL B[N][N],LL t[N][N],LL n,LL m,LL l)
{
    LL tmp[N][N];
    for(LL i=0;i<n;i++)
        for(LL j=0;j<l;j++){
            tmp[i][j]=0;
            for(LL k=0;k<m;k++)
                tmp[i][j]=(tmp[i][j]+A[i][k]*B[k][j]%mod)%mod;
        }
    for(LL i=0;i<n;i++)
        for(LL j=0;j<l;j++)
            t[i][j]=tmp[i][j];
}
void expo(LL p[N][N],LL e[N][N],LL k,LL n)
{
    if(k!=1){
        for(LL i = 0; i < n; ++i)
            for(LL j = 0; j < n; ++j)
                e[i][j] = (i == j);
        while(k){
            if(k&1)
                mul(e,p,e,n,n,n);
            mul(p,p,p,n,n,n);
            k>>=1;
        }
    }else {
        for(LL i=0;i<n;i++)
            for(LL j=0;j<n;j++)
                e[i][j]=p[i][j];
    }
}
void addOneP(LL idx, LL x, LL y, LL linelimit)
{
    if(CHECK(x, y)) b[ID(x, y)][idx] = 1;
}
int main()
{
    LL cas = 1;
    while(~scanf("%lld%lld%lld", &n, &mod, &l) && (n || mod || l))
    {
        m = n;
        LL add = 1;
        LL num = 0;
        pre[0] = 0;
        for(LL i=1; i <= 2 * n -1; i++){
            pre[i] = m + pre[i-1];
            for(LL j=1;j<=m;j++)
                scanf("%lld", &mat[i][j]), a[0][num++] = mat[i][j]%mod;
            if(i == n) add = -1;
            m += add;
        }
        memset(b, 0, sizeof(b));
        m = n, add = 1;
        for(LL i=1; i <= 2 * n -1; i++){
            for(LL j=1;j<=m;j++)
            {
                addOneP(ID(i, j), i, j, m);
                addOneP(ID(i, j), i, j - 1, m);
                addOneP(ID(i, j), i, j + 1, m);
                addOneP(ID(i, j), i - 1, j, m - add);
                addOneP(ID(i, j), i + 1, j, m + (i < n ? 1 : -1));
                if(i < n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j + 1, m + 1);
                if(i == n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
                if(i > n) addOneP(ID(i, j), i - 1, j + 1, m + 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
            }
            if(i == n) add = -1;
            m += add;
        }
        expo(b, c, l, num);
        mul(a, c, b, 1, num, num);
        LL ans = 0;
        for(LL i=0;i<num;i++)
            ans += b[0][i];
        printf("Case %lld: %lld\n", cas++, ans);
    }
    return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 1472
final_rank: 8

code_snippet: #include <bits/stdc++.h>
//#include <unordered_map>
#define N 111
#define ID(x, y) (pre[(x)-1]+(y-1))
#define CHECK(x, y) ((x)>0 && (x)<= 2 * n - 1 && (y)>0 && (y)<=(linelimit))
using namespace std;
long long n, mod, m, l;
long long a[N][N], b[N][N], c[N][N], mat[N][N], pre[N];
void mul(long long A[N][N],long long B[N][N],long long t[N][N],long long n,long long m,long long l)
{
    long long tmp[N][N];
    for(long long i=0;i<n;i++)
        for(long long j=0;j<l;j++){
            tmp[i][j]=0;
            for(long long k=0;k<m;k++)
                tmp[i][j]=(tmp[i][j]+A[i][k]*B[k][j]%mod)%mod;
        }
    for(long long i=0;i<n;i++)
        for(long long j=0;j<l;j++)
            t[i][j]=tmp[i][j];
}
void expo(long long p[N][N],long long e[N][N],long long k,long long n)
{
    if(k!=1){
        for(long long i = 0; i < n; ++i)
            for(long long j = 0; j < n; ++j)
                e[i][j] = (i == j);
        while(k){
            if(k&1)
                mul(e,p,e,n,n,n);
            mul(p,p,p,n,n,n);
            k>>=1;
        }
    }else {
        for(long long i=0;i<n;i++)
            for(long long j=0;j<n;j++)
                e[i][j]=p[i][j];
    }
}
void addOneP(long long idx, long long x, long long y, long long linelimit)
{
    if(CHECK(x, y)) b[ID(x, y)][idx] = 1;
}
int main()
{
    long long cas = 1;
    while(~scanf("%lld%lld%lld", &n, &mod, &l) && (n || mod || l))
    {
        m = n;
        long long add = 1;
        long long num = 0;
        pre[0] = 0;
        for(long long i=1; i <= 2 * n -1; i++){
            pre[i] = m + pre[i-1];
            for(long long j=1;j<=m;j++)
                scanf("%lld", &mat[i][j]), a[0][num++] = mat[i][j]%mod;
            if(i == n) add = -1;
            m += add;
        }
        memset(b, 0, sizeof(b));
        m = n, add = 1;
        for(long long i=1; i <= 2 * n -1; i++){
            for(long long j=1;j<=m;j++)
            {
                addOneP(ID(i, j), i, j, m);
                addOneP(ID(i, j), i, j - 1, m);
                addOneP(ID(i, j), i, j + 1, m);
                addOneP(ID(i, j), i - 1, j, m - add);
                addOneP(ID(i, j), i + 1, j, m + (i < n ? 1 : -1));
                if(i < n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j + 1, m + 1);
                if(i == n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
                if(i > n) addOneP(ID(i, j), i - 1, j + 1, m + 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
            }
            if(i == n) add = -1;
            m += add;
        }
        expo(b, c, l, num);
        mul(a, c, b, 1, num, num);
        long long ans = 0;
        for(long long i=0;i<num;i++)
            ans += b[0][i];
        printf("Case %lld: %lld\n", cas++, ans);
    }
    return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 1472
final_rank: 8

code_snippet: #include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
//#include <unordered_map>
#define N 111
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
#define ID(x, y) (pre[(x)-1]+(y-1))
#define CHECK(x, y) ((x)>0 && (x)<= 2 * n - 1 && (y)>0 && (y)<=(linelimit))
using namespace std;
typedef pair<long long,long long> PII;
const long long INF=0x3f3f3f3f;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("D:/in.txt","r",stdin);
        //freopen("D:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}

long long n, mod, m, l;
long long a[N][N], b[N][N], c[N][N], mat[N][N], pre[N];
void printfm(long long A[N][N],long long n,long long m)
{
    for(long long i=0;i<n;i++)
        for(long long j=0;j<m;j++)
        {
            printf("%I64d%c",A[i][j],(j==m-1)?'\n':' ');
        }
    printf("\n");
}
void mul(long long A[N][N],long long B[N][N],long long t[N][N],long long n,long long m,long long l)//A ???n*m????????????B???m*l?????????,t???????????????
{
    long long tmp[N][N];//???????????¢??????
    for(long long i=0;i<n;i++)
        for(long long j=0;j<l;j++){
            tmp[i][j]=0;
            for(long long k=0;k<m;k++)
                tmp[i][j]=(tmp[i][j]+A[i][k]*B[k][j]%mod)%mod;
        }
    for(long long i=0;i<n;i++)
        for(long long j=0;j<l;j++)
            t[i][j]=tmp[i][j];
}
void expo(long long p[N][N],long long e[N][N],long long k,long long n)//P???n*n????????????k?????????k?¬???????e???????????????
{
    if(k!=1){
        for(long long i = 0; i < n; ++i)
            for(long long j = 0; j < n; ++j)
                e[i][j] = (i == j);
        while(k)
        {
            if(k&1)
                mul(e,p,e,n,n,n);
            mul(p,p,p,n,n,n);
            k>>=1;
        }
    }else {
        for(long long i=0;i<n;i++)
            for(long long j=0;j<n;j++)
                e[i][j]=p[i][j];
    }
    //printfm(e,n,n);
}
void addOneP(long long idx, long long x, long long y, long long linelimit)
{
    if(CHECK(x, y)){
        b[ID(x, y)][idx] = 1;
    }
}
int main()
{
    //Open();
    long long cas = 1;
    while(~scanf("%lld%lld%lld", &n, &mod, &l) && (n || mod || l))
    {
        m = n;
        long long add = 1;
        long long num = 0;
        pre[0] = 0;
        for(long long i=1; i <= 2 * n -1; i++){
            pre[i] = m + pre[i-1];
            for(long long j=1;j<=m;j++)
                scanf("%lld", &mat[i][j]), a[0][num++] = mat[i][j]%mod;
            if(i == n) add = -1;
            m += add;
        }
        memset(b, 0, sizeof(b));
        m = n, add = 1;
        for(long long i=1; i <= 2 * n -1; i++){
            for(long long j=1;j<=m;j++)
            {
//                cout<<ID(i, j)<<endl;
                addOneP(ID(i, j), i, j, m);
                addOneP(ID(i, j), i, j - 1, m);
                addOneP(ID(i, j), i, j + 1, m);
                addOneP(ID(i, j), i - 1, j, m - add);
                addOneP(ID(i, j), i + 1, j, m + (i < n ? 1 : -1));
                if(i < n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j + 1, m + 1);
                if(i == n) addOneP(ID(i, j), i - 1, j - 1, m - 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
                if(i > n) addOneP(ID(i, j), i - 1, j + 1, m + 1), addOneP(ID(i, j), i + 1, j - 1, m - 1);
            }
            if(i == n) add = -1;
            m += add;
        }
        expo(b, c, l, num);
        mul(a, c, b, 1, num, num);
        long long ans = 0;
        for(long long i=0;i<num;i++)
            ans += b[0][i];
        printf("Case %lld: %lld\n", cas++, ans);
    }
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 1460
final_rank: 7

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 6;
const int MAX_W = 2 * MAX_N - 1;
const int MAX_H = 2 * MAX_N - 1;
const int MAX_GN = 3 * MAX_N * MAX_N - 3 * MAX_N + 1;

/* typedef */

typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> mtx;

/* global variables */

int n, l;
ll m;
int gn, h, wws[MAX_W];
int pmap[MAX_H][MAX_W];

/* subroutines */

void initmat(mtx& m0) {
  for (int i = 0; i < gn; i++) fill(m0[i].begin(), m0[i].end(), 0LL);
}

void mulmat(mtx& mm, const mtx& m0, const mtx& m1) {
  for (int i = 0; i < gn; i++)
    for (int j = 0; j < gn; j++) {
      ll& mij = mm[i][j];
      mij = 0;
      for (int k = 0; k < gn; k++)
        mij = (mij + m0[i][k] * m1[k][j]) % m;
    }
}

void mulmatvec(vl& vv, const mtx& mm, const vl& v0) {
  for (int i = 0; i < gn; i++) {
    vv[i] = 0;
    for (int j = 0; j < gn; j++)
      vv[i] = (vv[i] + mm[i][j] * v0[j]) % m;
  }
}

void powmat(mtx& mm, mtx m0, int e) {
  mtx m1(gn, vl(gn, 0LL));
  initmat(mm);
  for (int i = 0; i < gn; i++) mm[i][i] = 1LL;

  while (e > 0) {
    if (e & 1) {
      mulmat(m1, mm, m0);
      mm = m1;
    }

    mulmat(m1, m0, m0);
    m0 = m1;

    e >>= 1;
  }
}

void printmat(const mtx& mm) {
  for (int i = 0; i < gn; i++) {
    for (int j = 0; j < gn; j++) cout << mm[i][j] << ' ';
    cout << endl;
  }
}

/* main */

int main() {
  for (int cn = 1;; cn++) {
    cin >> n >> m >> l;
    if (n == 0) break;

    // gn = 2*sum_(i=n)^(n-2)i + 2n - 1 = 2(3n-2)(n-1)/2+2n-1
    // = 3n^2-3n-2n+2+2n-1 = 3n^2-3n+1

    gn = 3 * n * n - 3 * n + 1;

    vl vec(gn);
    for (int i = 0; i < gn; i++) cin >> vec[i];

    h = 2 * n - 1;
    
    for (int y = 0; y < n; y++)
      wws[y] = wws[h - 1 - y] = n + y;

    memset(pmap, -1, sizeof(pmap));
    int pos = 0;
    for (int y = 0; y < h; y++)
      for (int x = 0; x < wws[y]; x++)
	pmap[y][x] = pos++;
    
    mtx m0(gn, vl(gn, 0));
    
    for (int y = 0; y < n - 1; y++)
      for (int x = 0; x < wws[y]; x++) {
	int p0 = pmap[y][x];
	if (y > 0) {
	  if (x - 1 >= 0) m0[p0][pmap[y - 1][x - 1]] = 1;
	  if (x < wws[y - 1]) m0[p0][pmap[y - 1][x]] = 1;
	}
	if (x - 1 >= 0) m0[p0][pmap[y][x - 1]] = 1;
	m0[p0][p0] = 1;
	if (x + 1 < wws[y]) m0[p0][pmap[y][x + 1]] = 1;
	m0[p0][pmap[y + 1][x]] = 1;
	m0[p0][pmap[y + 1][x + 1]] = 1;
      }

    int y0 = n - 1;
    for (int x = 0; x < wws[y0]; x++) {
      int p0 = pmap[y0][x];
      if (y0 - 1 >= 0) {
	if (x - 1 >= 0) m0[p0][pmap[y0 - 1][x - 1]] = 1;
	if (x < wws[y0 - 1]) m0[p0][pmap[y0 - 1][x]] = 1;
      }
      if (x - 1 >= 0) m0[p0][pmap[y0][x - 1]] = 1;
      m0[p0][p0] = 1;
      if (x + 1 < wws[y0]) m0[p0][pmap[y0][x + 1]] = 1;
      if (y0 + 1 < h) {
	if (x - 1 >= 0) m0[p0][pmap[y0 + 1][x - 1]] = 1;
	if (x < wws[y0 + 1]) m0[p0][pmap[y0 + 1][x]] = 1;
      }
    }

    for (int y = n; y < h; y++)
      for (int x = 0; x < wws[y]; x++) {
	int p0 = pmap[y][x];
	m0[p0][pmap[y - 1][x]] = 1;
	m0[p0][pmap[y - 1][x + 1]] = 1;
	if (x - 1 >= 0) m0[p0][pmap[y][x - 1]] = 1;
	m0[p0][p0] = 1;
	if (x + 1 < wws[y]) m0[p0][pmap[y][x + 1]] = 1;
	if (y + 1 < h) {
	  if (x - 1 >= 0) m0[p0][pmap[y + 1][x - 1]] = 1;
	  if (x < wws[y + 1]) m0[p0][pmap[y + 1][x]] = 1;
	}
      }
    //printmat(m0);

    mtx mm(gn, vl(gn));
    powmat(mm, m0, l);
    //printmat(mm);

    vl vv(gn);
    mulmatvec(vv, mm, vec);

    ll sum = 0;
    for (int i = 0; i < gn; i++) sum += vv[i];

    printf("Case %d: %lld\n", cn, sum);
  }

  return 0;
}
accuracy: 1
time_ms: 960
memory_kb: 1480
final_rank: 3

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int p[20][20];
int q[210];
int dx[]={0,0,0,1,1,-1,-1};
int dy[]={0,1,-1,1,0,0,-1};
long long mat[210][210];
long long val[210][210];
long long tmp[210][210];
int main(){
	int T=0;
	int a,b,c;
	while(scanf("%d%d%d",&a,&b,&c),a){
		long long mod=b;
		for(int i=0;i<20;i++)for(int j=0;j<20;j++)
			p[i][j]=-1;
		int sz=0;
		for(int i=0;i<a;i++){
			for(int j=0;j<a+i;j++){
				scanf("%d",q+sz);
				p[i][j]=sz++;
			}
		}
		for(int i=a;i<a*2-1;i++){
			for(int j=i-a+1;j<a*2-1;j++){
				scanf("%d",q+sz);
				p[i][j]=sz++;
			}
		}
		for(int i=0;i<sz;i++)for(int j=0;j<sz;j++){
			mat[i][j]=0;
			val[i][j]=0;
			if(i==j)val[i][j]=1;
		}
		for(int i=0;i<20;i++){
			for(int j=0;j<20;j++){
				if(!~p[i][j])continue;
				int at=p[i][j];
				for(int k=0;k<7;k++){
					int tx=i+dx[k];int ty=j+dy[k];
					if(tx<0||ty<0)continue;
					if(!~p[tx][ty])continue;
					mat[p[tx][ty]][at]++;
				}
			}
		}
		while(c){
			if(c%2){
				for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)tmp[i][j]=0;
				for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)for(int k=0;k<sz;k++)
					tmp[i][j]=(tmp[i][j]+mat[i][k]*val[k][j])%mod;
				for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)val[i][j]=tmp[i][j];
			}
			c/=2;
			for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)tmp[i][j]=0;
			for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)for(int k=0;k<sz;k++)
				tmp[i][j]=(tmp[i][j]+mat[i][k]*mat[k][j])%mod;
			for(int i=0;i<sz;i++)for(int j=0;j<sz;j++)mat[i][j]=tmp[i][j];
		}
		
		long long ret=0;
		for(int i=0;i<sz;i++){
			long long v=0;
			for(int j=0;j<sz;j++){
				v=(v+val[i][j]*q[j])%mod;
			}
			ret+=v;
		}
		printf("Case %d: %lld\n",++T,ret);
	}
}
accuracy: 1
time_ms: 940
memory_kb: 1488
final_rank: 2

code_snippet: #include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100;
const int dx[] = {-1, -1, 0, 1, 1, 0};
const int dy[] = {-1, 0, 1, 1, 0, -1};

int m, n, l;
int tot;
int id[N][N];
long long c[N];

struct Mat
{
	int a[N][N];
	void clear() {
		memset(a, 0, sizeof a);
	}
};

int valid(int x, int y)
{
	return x >= 0 && y >= 0 && id[x][y] >= 0;
}

Mat operator * (const Mat &a, const Mat &b)
{
	Mat ret;
	for(int i = 0; i < tot; ++ i) {
		for(int j = 0; j < tot; ++ j) {
			ret.a[i][j] = 0;
			for(int k = 0; k < tot; ++ k) {
				ret.a[i][j] = (ret.a[i][j] + (long long)a.a[i][k] * b.a[k][j]) % m;
			}
		}
	}
	return ret;
}

Mat operator ^ (Mat a, int l)
{
	Mat ret;
	ret.clear();
	for(int i = 0; i < tot; ++ i) {
		ret.a[i][i] = 1;
	}
	for( ; l; l >>= 1, a = a * a) {
		if (l & 1)
			ret = ret * a;
	}
	return ret;
}

void solve()
{
	tot = 0;
	int cur = n;
	memset(id, -1, sizeof id);
	for(int i = 0; i < n; ++ i) {
		for(int j = 0; j < cur; ++ j) {
			id[i][j] = tot ++;
		}
		cur ++;
	}
	-- cur;
	for(int i = 0; i < n - 1; ++ i) {
		for(int j = i + 1; j < cur; ++ j) {
			id[i + n][j] = tot ++;
		}
	}

	Mat a;
	a.clear();
	for(int i = 0; i < 2 * n; ++ i) {
		for(int j = 0; j < 2 * n; ++ j) {
			if (id[i][j] >= 0) {
				a.a[id[i][j]][id[i][j]] ++;
				for(int d = 0; d < 6; ++ d) {
					int ni = i + dx[d];
					int nj = j + dy[d];
					if (valid(ni, nj)) {
						a.a[id[i][j]][id[ni][nj]] ++;
					}
				}
			}
		}
	}

	/*
	cout << "!!" << endl;
	for(int i = 0; i < tot; ++ i) {
		for(int j = 0; j < tot; ++ j) {
			cout << a.a[i][j] << ' ';
		}
		cout << endl;
	}
	cout << "!!" << endl;
	for(int i = 0; i < tot; ++ i) {
		for(int j = 0; j < tot; ++ j) {
			cout << a.a[i][j] << ' ';
		}
		cout << endl;
	}
	*/
	a = a ^ l;

	int x;
	memset(c, 0, sizeof c);
	for(int i = 0; i < tot; ++ i) {
		scanf("%d", &x);
		for(int j = 0; j < tot; ++ j) {
			(c[j] += (long long)x * a.a[i][j]) %= m;
		}
	}
	long long ret = 0;
	for(int i = 0; i < tot; ++ i) {
		ret += c[i];
	}
	cout << ret << endl;
}

int main()
{
	int test = 0;
	for( ; cin >> n >> m >> l && (n || m || l); ) {
		printf("Case %d: ", ++ test);
		solve();
	}
}
accuracy: 1
time_ms: 990
memory_kb: 1472
final_rank: 4

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long lli;
typedef lli elm;
typedef vector<vector<elm> > mat;

const int H = 20;
const int W = 20;
const int di[6] = {0,1,1,0,-1,-1};
const int dj[6] = {1,1,0,-1,-1,0};

lli N, M, L;
vector<lli> V;
int G[H][W];

mat getE(int n) {
  mat e(n, vector<elm>(n, 0));
  for(int i = 0; i < n; ++i) {
    e[i][i] = 1;
  }
  return e;
}

mat multiply(const mat &a, const mat &b) {
  if(a.size() == 0 || b.size() == 0 ||
     a[0].size() != b.size()) return mat();
  int s = a.size();
  int t = b.size();
  int u = b[0].size();
  mat c(s, vector<elm>(u, 0));
  for(int i = 0; i < s; ++i) {
    for(int j = 0; j < u; ++j) {
      for(int k = 0; k < t; ++k) {
        c[i][j] += (a[i][k] * b[k][j])%M;
        c[i][j] %= M;
      }
    }
  }
  return c;
}

mat pow(const mat &a, const lli &n) {
  if(n == 0) return getE(a.size());
  mat b = pow(multiply(a, a), n/2);
  if(n & 1) return multiply(b, a);
  else return b;
}

int main() {
  while(cin >> N >> M >> L && (N|M|L)) {
    fill(G[0], G[H], -1);
    V.clear();
    for(int i = 0; i < N; ++i) {
      for(int j = 0; j < i+N; ++j) {
        int a;
        cin >> a;
        G[i][j] = V.size();
        V.push_back(a);
      }
    }
    for(int i = 0; i < N-1; ++i) {
      for(int j = 0; j < 2*N-2-i; ++j) {
        int a;
        cin >> a;
        G[N+i][j+i+1] = V.size();
        V.push_back(a);
      }
    }
    mat X(1, V);
    mat A(V.size(), vector<lli>(V.size(), 0LL));
    for(int i = 0; i < H; ++i) {
      for(int j = 0; j < W; ++j) {
        if(G[i][j] == -1) continue;
        int a = G[i][j];
        A[a][a] = 1;
        for(int k = 0; k < 6; ++k) {
          int ni = i + di[k];
          int nj = j + dj[k];
          if(ni < 0 || ni >= H) continue;
          if(nj < 0 || nj >= W) continue;
          if(G[ni][nj] == -1) continue;
          int b = G[ni][nj];
          A[a][b] = 1;
        }
      }
    }

    X = multiply(X, pow(A,L));
    lli res = 0;
    for(int i = 0; i < X[0].size(); ++i) {
      res += X[0][i];
    }
    static int tc = 0;
    cout << "Case " << ++tc << ": " << res << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1420
memory_kb: 3452
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
typedef long long lli;
typedef vector<lli> vec;
typedef vector<vec> mat;
 
const lli N = 6;
 
lli n, M, L;
 
mat mul(mat &A, mat &B){
  mat C(A.size(), vec(B[0].size()));
  for(lli i=0;i<A.size();i++){
    for(lli k=0;k<B.size();k++){
      for(lli j=0;j<B[0].size();j++){
        C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M;
      }
    }
  }
  return C;
}
 
mat pow(mat A, lli n){
  mat B(A.size(), vec(A.size()));
  for(lli i=0;i<A.size();i++){
    B[i][i] = 1;
  }
  while(n > 0){
    if(n & 1) B = mul(B, A);
    A = mul(A, A);
    n >>= 1;
  }
  return B;
}
 
lli dy[6] = {-1, -1, 0, 0, 1, 1};
lli dx[6] = {-1, 0, -1, 1, 0, 1};
 
int main(){
  int time = 0;
  while(cin >> n >> M >> L && (n|M|L)){
    int size = (2 * n - 1);
    mat dat(size, vec(size, -1));
    int d = 0;
    int t_size = n;
    for(int i=0;i<2*n-1;i++){
      int in;
      if(i >= n) d++;
      for(int j=0;j<t_size;j++){
        cin >> dat[i][j+d];
      }
      if(i + 1 < n) t_size++;
      else t_size--;
    }
    mat A(size*size, vec(size*size, 0));
    for(int i=0;i<size;i++){
      for(int j=0;j<size;j++){
        if(dat[i][j] == -1) continue;
        A[i*size+j][i*size+j] = 1;
        for(int k=0;k<6;k++){
          int ny = i + dy[k];
          int nx = j + dx[k];
          if(ny < 0 || ny >= size) continue;
          if(nx < 0 || nx >= size) continue;
          if(dat[ny][nx] == -1) continue;
          A[i*size+j][ny*size+nx] = 1;
        }
      }
    }
    mat B(size*size, vec(1, 0));
    for(int i=0;i<size;i++){
      for(int j=0;j<size;j++){
        B[i*size+j][0] = max(0LL, dat[i][j]);
      }
    }
    A = pow(A, L);
    A = mul(A, B);
    lli ans = 0;
    for(int i=0;i<A.size();i++){
      for(int j=0;j<A[i].size();j++){
        ans += A[i][j];
      }
    }
    cout << "Case " << ++time << ": " << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1640
memory_kb: 1696
final_rank: 12

code_snippet: #include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cassert>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)
#define MAX 1000
using namespace std;
typedef long long ll;
typedef vector<ll> VI;
typedef vector<VI> VVI;
typedef VVI matrix;

const int diff = 100;
int dx[] = { 0,1,1,0,-1,-1};
int dy[] = {-1,0,1,1, 0,-1};
int N,L,min_x,min_y,max_x,max_y;
int Index[MAX][MAX];
ll M;

matrix identity(int n)
{
  matrix A(n,vector<ll>(n));
  for(int i=0;i<n;i++) A[i][i] = 1;
  return A;
}

vector<ll> multi(const matrix& A,const vector<ll>& B)
{
  vector<ll> ret(A.size());
  for(int i=0;i<A.size();++i)
    for(int j=0;j<A[0].size();++j)
      ret[i] += (A[i][j]*B[j])%M;
  return ret;
}

matrix multi(const matrix& A,const matrix& B)
{
  matrix C(A.size(),vector<ll>(B[0].size()));
  for(int i=0;i<C.size();++i)
    for(int j=0;j<C[i].size();++j)
      for(int k=0;k<A[i].size();++k)
	C[i][j] = (C[i][j]+(A[i][k]*B[k][j])%M)%M;
  return C;
}

matrix pow(const matrix& A,int e)
{
  return !e?identity(A.size()):
    (e%2?multi(A,pow(A,e-1)):pow(multi(A,A),e/2));
}


int main()
{
  int CNT = 1;
  while(cin >> N >> M >> L,N|M|L)
    {
      min_x = min_y = 999;
      max_x = max_y = 0;
      rep(i,MAX)rep(j,MAX)Index[i][j] = inf;

      int x = diff;
      int y = diff;
      int add = 0;
      int size = 0;
      vector<ll> b;

      rep(i,2*N-1)
	{
	  int nx = x,ny = y;
	  rep(j,N+add)
	    {
	      int value;
	      cin >> value;
	      b.push_back(value);
	      Index[ny][nx] = size;
	      size++;
	      nx += dx[1];
	      ny += dy[1];
	    }
	  if(i < N-1)add++;
	  else       add--;
	  if(i < N-1)
	    {
	      x += dx[3], y += dy[3];
	    }
	  else 
	    {
	      x += dx[2], y += dy[2];
	    }
	}

      matrix A = identity(size);

      REP(i,diff,diff+2*N)
	{
	  REP(j,diff,diff+2*N)
	    {
	      if(Index[i][j] == inf)continue;
	      int cur = Index[i][j];
	      rep(k,6)
		{
		  int nx = j + dx[k];
		  int ny = i + dy[k];
		  if(Index[ny][nx] == inf)continue;
		  int next = Index[ny][nx];
		  A[cur][next] = 1;
		}
	    }
	}
  
      A = pow(A,L);
 
      vector<ll> c = multi(A,b);
      ll ans = 0;
      rep(i,c.size())ans += c[i]%M;

      cout << "Case " << CNT++ << ": " << ans << endl;

    }
  return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 7292
final_rank: 17

code_snippet: #include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cassert>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)
#define MAX 1000
using namespace std;
typedef long long ll;
typedef vector<ll> VI;
typedef vector<VI> VVI;
typedef VVI matrix;

const int diff = 500;
int dx[] = { 0,1,1,0,-1,-1};
int dy[] = {-1,0,1,1, 0,-1};
int N,L,min_x,min_y,max_x,max_y;
int Index[MAX][MAX];
ll M;

matrix identity(int n)
{
  matrix A(n,vector<ll>(n));
  for(int i=0;i<n;i++) A[i][i] = 1;
  return A;
}

vector<ll> multi(const matrix& A,const vector<ll>& B)
{
  vector<ll> ret(A.size());
  for(int i=0;i<A.size();++i)
    for(int j=0;j<A[0].size();++j)
      ret[i] += (A[i][j]*B[j])%M;
  return ret;
}

matrix multi(const matrix& A,const matrix& B)
{
  matrix C(A.size(),vector<ll>(B[0].size()));
  for(int i=0;i<C.size();++i)
    for(int j=0;j<C[i].size();++j)
      for(int k=0;k<A[i].size();++k)
	C[i][j] = (C[i][j]+(A[i][k]*B[k][j])%M)%M;
  return C;
}

matrix pow(const matrix& A,int e)
{
  return !e?identity(A.size()):
    (e%2?multi(A,pow(A,e-1)):pow(multi(A,A),e/2));
}


int main()
{
  int CNT = 1;
  while(cin >> N >> M >> L,N|M|L)
    {
      min_x = min_y = 999;
      max_x = max_y = 0;
      rep(i,MAX)rep(j,MAX)Index[i][j] = inf;

      int x = diff;
      int y = diff;
      int add = 0;
      int size = 0;
      vector<ll> b;

      rep(i,2*N-1)
	{
	  int nx = x,ny = y;
	  rep(j,N+add)
	    {
	      int value;
	      cin >> value;
	      b.push_back(value);
	      Index[ny][nx] = size;
	      size++;
	      nx += dx[1];
	      ny += dy[1];
	    }
	  if(i < N-1)add++;
	  else       add--;
	  if(i < N-1)
	    {
	      x += dx[3], y += dy[3];
	    }
	  else 
	    {
	      x += dx[2], y += dy[2];
	    }
	}

      matrix A = identity(size);

      REP(i,diff,diff+2*N)
	{
	  REP(j,diff,diff+2*N)
	    {
	      if(Index[i][j] == inf)continue;
	      int cur = Index[i][j];
	      rep(k,6)
		{
		  int nx = j + dx[k];
		  int ny = i + dy[k];
		  if(Index[ny][nx] == inf)continue;
		  int next = Index[ny][nx];
		  A[cur][next] = 1;
		}
	    }
	}
      /*
      cout << "A=--------" << endl;
      rep(i,A.size())
	{
	  rep(j,A[i].size())
	    {
	      cout << A[i][j] << " ";
	    }
	  cout << endl;
	}

      rep(i,b.size())
	{
	  cout << "b[" << i << "] = " << b[i] << endl;
	}
      */
      A = pow(A,L);

   
      vector<ll> c = multi(A,b);
      ll ans = 0;
      rep(i,c.size())
	{
	  ans += c[i]%M;
	  //cout << "c[" << i << "] = " << c[i] << endl;
	}
      cout << "Case " << CNT++ << ": " << ans << endl;

    }
  return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 7296
final_rank: 18

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
typedef vector<ll> Array;
typedef vector<Array> Matrix;

// 正方行列の掛け算 O(N^3)
Matrix mul(const Matrix &a, const Matrix &b){
  const int N = a.size();
  Matrix res(N, Array(N, 0));
  for(int i = 0; i < N; i++){
    for(int j = 0; j < N; j++){
      for(int k = 0; k < N; k++){
        res[i][j] += a[i][k] * b[k][j];
        res[i][j] %= MOD;
      }
    }
  }
  return res;
}
// サイズNの単位行列
Matrix Mat_E(int N){
  Matrix res(N, Array(N, 0));
  for(int i = 0; i < N; i++){
    res[i][i] = 1;
  }
  return res;
}
// 正方行列の累乗 O(M^3 * logn)
Matrix pow(const Matrix &a, long long n){
  const int M = a.size();
  if(n == 0) return Mat_E(M);
  Matrix res = pow(mul(a, a), n / 2);
  if(n & 1) res = mul(res, a);
  return res;
}

void make_mat(int x1, int y1, int dx[6], int dy[6], Matrix& mat, map< pair<int, int>, int >& to_index){
  int u = to_index[make_pair(x1, y1)];
  REP(r, 6) {
    int x2 = x1 + dx[r];
    int y2 = y1 + dy[r];
    if(to_index.count(make_pair(x2, y2))){
      int v = to_index[make_pair(x2, y2)];
      mat[u][v] = 1;
    }
  }
}
int main(){
  int N, M, L;
  int CASENUM = 1;
  while(cin >> N >> M >> L && N){
    printf("Case %d: ", CASENUM++);
    MOD = M;
    map< pair<int, int>, int > to_index;
    vector<int> init;
    REP(y, 2 * N - 1){
      REP(x, 2 * N - 1 - abs(y - (N - 1))){
        int X; cin >> X;
        int T = to_index.size();
        assert(init.size() == T);
        init.push_back(X);
        to_index[make_pair(x, y)] = T;
      }
    }
    int T = to_index.size();
    Matrix mat(T, Array(T, 0));
    REP(i, T) mat[i][i] = 1;
    REP(y1, 2 * N - 1){
      REP(x1, 2 * N - 1 - abs(y1 - (N - 1))){
        int dy[6] = {-1, -1, 0, 1, 1, 0};
        if(y1 < N - 1){
          int dx[6] = {-1, 0, 1, 1, 0, -1};
          make_mat(x1, y1, dx, dy, mat, to_index);
        }else if(y1 == N - 1){
          int dx[6] = {-1, 0, 1, 0, -1, -1};
          make_mat(x1, y1, dx, dy, mat, to_index);
        }else{
          int dx[6] = {0, 1, 1, 0, -1, -1};
          make_mat(x1, y1, dx, dy, mat, to_index);
        }
      }
    }
    mat = pow(mat, L);
    /*
    REP(i, T) {
      REP(j, T) cout << mat[i][j] << " ";
      cout << endl;
    }
    cout << endl;
    */
    //REP(i, T) cout << init[i] << " "; cout << endl;
    vector<ll> terminal(T);
    REP(i, T) REP(j, T) terminal[i] = (terminal[i] + mat[i][j] * init[j]) % M;
    /*
    REP(y1, 2 * N - 1){
      REP(x1, 2 * N - 1 - abs(y1 - (N - 1))){
        cout << terminal[to_index[ make_pair(x1, y1) ]] << " ";
      }
      cout << endl;
    }
    */
    ll ans = 0;
    REP(i, T) ans += terminal[i];
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 940
memory_kb: 3404
final_rank: 13

code_snippet: #include<cstdio>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

typedef long long ll;

const int dx[]={1,0,-1,-1,0,1},dy[]={0,1,1,0,-1,-1};

ll M;

const int N_MAX=91;

template<class T>
void mul(int n,const T A[N_MAX][N_MAX],const T x[N_MAX],T y[N_MAX]){
	static T z[N_MAX];
	rep(i,n){
		z[i]=0;
		rep(j,n) z[i]=(z[i]+A[i][j]*x[j])%M;
	}
	rep(i,n) y[i]=z[i];
}

template<class T>
void mul(int n,const T A[N_MAX][N_MAX],const T B[N_MAX][N_MAX],T C[N_MAX][N_MAX]){
	static T tmp[N_MAX][N_MAX];
	rep(i,n) rep(j,n) {
		tmp[i][j]=0;
		rep(k,n) tmp[i][j]=(tmp[i][j]+A[i][k]*B[k][j])%M;
	}
	rep(i,n) rep(j,n) C[i][j]=tmp[i][j];
}

template<class T>
void pow(int n,const T A[N_MAX][N_MAX],ll m,T B[N_MAX][N_MAX]){
	static T tmp[N_MAX][N_MAX];
	rep(i,n) rep(j,n) {
		tmp[i][j]=A[i][j];
		B[i][j]=(i==j?1:0);
	}
	for(int t=0;m>0;t++){
		if(m&(1LL<<t)){
			mul(n,B,tmp,B);
			m-=1LL<<t;
		}
		mul(n,tmp,tmp,tmp);
	}
}

int main(){
	int buf1[20][20],*buf2[20],buf3[20][20],*buf4[20];
	rep(i,20){
		buf2[i]=buf1[i]+10;
		buf4[i]=buf3[i]+10;
	}
	int **ini=buf2+10;
	int **idx=buf4+10;

	for(int cas=1,n,L;scanf("%d%lld%d",&n,&M,&L),n;cas++){
		for(int i=9;i>=-10;i--) for(int j=-10;j<10;j++) idx[i][j]=-1;

		int N=0;
		for(int i=n-1;i>=0;i--) for(int j= -n+1 ;j<n-i;j++) scanf("%d",ini[i]+j), idx[i][j]=N++;
		for(int i= -1;i>-n;i--) for(int j=-n-i+1;j< n ;j++) scanf("%d",ini[i]+j), idx[i][j]=N++;

		ll A[N_MAX][N_MAX]={},x[N_MAX]={};
		for(int i=9;i>=-10;i--) for(int j=-10;j<10;j++) if(idx[i][j]!=-1) {
			x[idx[i][j]]=ini[i][j];
			A[idx[i][j]][idx[i][j]]=1;
			rep(k,6){
				int y=i+dy[k],x=j+dx[k];
				if(idx[y][x]!=-1){
					A[idx[i][j]][idx[y][x]]=1;
				}
			}
		}
		pow(N,A,L,A);
		mul(N,A,x,x);

		ll ans=0;
		rep(i,N) ans+=x[i];
		printf("Case %d: %lld\n",cas,ans);
	}

	return 0;
}
accuracy: 1
time_ms: 950
memory_kb: 1232
final_rank: 1

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int MOD;

template <class T>
vector<vector<T> > matrixProduct(const vector<vector<T> >& x, const vector<vector<T> >& y)
{
    int a = x.size();
    int b = x[0].size();
    int c = y[0].size();
    vector<vector<T> > z(a, vector<T>(c, 0));
    for(int i=0; i<a; ++i){
        for(int j=0; j<c; ++j){
            for(int k=0; k<b; ++k){
                z[i][j] += x[i][k] * y[k][j];
                z[i][j] %= MOD;
            }
        }
    }
    return z;
}

template <class T>
vector<vector<T> > matrixPower(const vector<vector<T> >& x, int k)
{
    int n = x.size();
    vector<vector<T> > y(n, vector<T>(n, 0));
    for(int i=0; i<n; ++i)
        y[i][i] = 1;

    vector<vector<T> > z = x;
    while(k > 0){
        if(k & 1)
            y = matrixProduct(y, z);
        z = matrixProduct(z, z);
        k >>= 1;
    }
    return y;
}

int dy[] = {0, -1, -1, 0, 0, 1, 1};
int dx[] = {0, -1, 0, -1, 1, 0, 1};

int main()
{
    for(int d=1; ; ++d){
        int n, l;
        cin >> n >> MOD >> l;
        if(n == 0)
            return 0;

        vector<vector<int> > cell(2*n+1, vector<int>(2*n+1, -1));
        for(int i=0; i<n-1; ++i){
            for(int j=0; j<n+i; ++j){
                cin >> cell[i+1][j+1];
            }
        }
        for(int i=0; i<n; ++i){
            for(int j=0; j<2*n-1-i; ++j){
                cin >> cell[i+n][i+j+1];
            }
        }

        n = 2 * n + 1;
        vector<vector<long long> > a(n*n, vector<long long>(n*n, 0));
        vector<vector<long long> > b(n*n, vector<long long>(1, 0));
        for(int i=0; i<n; ++i){
            for(int j=0; j<n; ++j){
                if(cell[i][j] == -1){
                    cell[i][j] = 0;
                    continue;
                }

                b[i*n+j][0] = cell[i][j];
                for(int k=0; k<7; ++k){
                    int y = i + dy[k];
                    int x = j + dx[k];
                    a[i*n+j][y*n+x] = 1;
                }
            }
        }

        a = matrixPower(a, l);
        vector<vector<long long> > c = matrixProduct(a, b);

        long long ret = 0;
        for(int i=0; i<n*n; ++i)
            ret += c[i][0];
        cout << "Case " << d << ": " << ret << endl;
    }
}
accuracy: 1
time_ms: 6370
memory_kb: 2132
final_rank: 19