structMat { int mat[MAXmat][MAXmat]; Mat() { memset(mat, 0, sizeof(mat)); } Mat(int a[MAXmat][MAXmat]) { for (re int i = 0; i < MAXmat; ++i) { for (re int j = 0; j < MAXmat; ++j) { mat[i][j] = a[i][j]; } } } inlinevoidoperator=(Mat x) { for (re int i = 0; i < MAXmat; ++i) { for (re int j = 0; j < MAXmat; ++j) { mat[i][j] = x.mat[i][j]; } } } inline Mat operator+(Mat x) { Mat ans; for (int i = 0; i < MAXmat; ++i) { for (int j = 0; j < MAXmat; ++j) { ans.mat[i][j] = (mat[i][j] + x.mat[i][j]) % MOD; } } return ans; } inline Mat operator*(Mat x) { Mat ans; for (re int i = 0; i < MAXmat; ++i) { for (re int k = 0; k < MAXmat; ++k) { int a = mat[i][k]; for (re int j = 0; j < MAXmat; ++j) { ans.mat[i][j] = (a * x.mat[k][j] + ans.mat[i][j]) % MOD; } } } return ans; } inline Mat operator^(int x) { Mat ans, base; for (re int i = 0; i < MAXmat; ++i) { ans.mat[i][i] = 1; } for (re int i = 0; i < MAXmat; ++i) { for (re int j = 0; j < MAXmat; ++j) { base.mat[i][j] = mat[i][j]; } } while (x) { if (x & 1) { ans = ans * base; } base = base * base; x >>= 1; } return ans; } };