// #define _GLIBCXX_DEBUG // for STL debug (optional) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using ll = long long int; using int64 = long long int; template void chmax(T &a, T b) {a = max(a, b);} template void chmin(T &a, T b) {a = min(a, b);} template void chadd(T &a, T b) {a = a + b;} int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; const ll INF = 1001001001001001LL; const ll MOD = 998244353LL; int nxt[5][5][5][5][5][5]; int to_int(int a, int b, int c, int K) { int res = a; res = res * K + b; res = res * K + c; return res; } // 行列ライブラリ // Verified: TopCoder SRM 704 Div.2 (ModEquationEasy) // 行列の積 と 累乗(繰り返し二乗法) // Matrix Library Begin (C++11) template using Matrix = vector< vector >; template void init_mat(Matrix &A, int h, int w) { A.resize(h, vector(w, 0)); } template Matrix calc_mat(Matrix A, Matrix B) { Matrix C(A.size(), vector(B[0].size())); for(int i=0; i Matrix mat_pow(Matrix A, ll n) { Matrix B(A.size(), vector(A.size())); for(int i=0; i 0) { if(n & 1) B = calc_mat(B, A); A = calc_mat(A, A); n >>= 1; } return B; } // N * M 行列のランクを求める // 整数行列でも基本変形時に分数になるので double 型に限定しています // 位数 2 の有限体では (演算を xor とかに直した形で) 確認済み、他は未 Verify なのでもしかしたらやばいかもしれない int mat_rank(Matrix A) { int N = A.size(), M = A[0].size(); int res = 0; for(int i=0; i max_elem) { max_elem = abs(A[j][i]); piv = j; } } // res 行目を piv 行目に変えて、行基本変形 if(piv < 0) continue; swap(A[res], A[piv]); // res 行目を正規化 // F_2 の場合はここは不要 { double div = A[res][i]; for(int k=0; k> N >> K; int64 dim = K * K * K; for(int a=0; a mat; init_mat(mat, dim, dim); for(int a=0; a vec; init_mat(vec, dim, 1); vec[0][0] = 1; int64 ans = 0; vec = calc_mat(mat_pow(mat, N), vec); for(int i=0; i