struct Matrix { LL mat[MAXN][MAXN]; int r,c; Matrix (int r = 0 ,int c = 0) { init(r,c); } void init(int r = 0,int c = 0) { this -> r = r; this -> c = c; memset(mat,0,sizeof(mat)); } Matrix operator * (const Matrix &rhs) const { Matrix ret(r,rhs.c); for (int k = 0 ; k < c ; k++) { for (int i = 0 ; i < r ; i++) { if (mat[i][k] == 0) continue; for (int j = 0 ; j < rhs.c ; j++) ret.mat[i][j] = (ret.mat[i][j] + mat[i][k] * rhs.mat[k][j]) % M; } } return ret; } }; Matrix pow_mat(Matrix x,LL cnt) { Matrix ret(max(x.r,x.c),max(x.r,x.c)); for (int i = 0 ; i < max(ret.r,ret.c) ; i++) ret.mat[i][i] = 1; while (cnt) { if (cnt & 1) ret = ret * x; x = x * x; cnt >>= 1; } return ret; }