#include #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include #include #include #include #include using namespace std; #define FOR(i,a,b) for (int i = a; i <= b; i++) #define REP(i,n) FOR(i,0,n-1) #define CLR(a,x) memset(a,x,sizeof(a)) #define pb push_back #define mp make_pair #define Inf 1000000000 #define Mi 1000000007 #define N 70 typedef double ld; typedef unsigned long long ll; typedef int i; typedef vector vi; typedef vector vvi; int min (int a, int b) {if (a < b) return a; return b;} int Abs(int a) {if (a < 0) return -a; else return a;} //class for matrix class TMatr{ public: int n;//length and width of matrix. cause the matrix is quadratic it's the same ll A[N][N]; TMatr operator * (TMatr b); }; TMatr res; TMatr TMatr::operator * (TMatr b)//operator of multiplying matrixes { res.n = n; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++){ res.A[i][j] = 0; for (int k = 0; k < n; k++) res.A[i][j] = (res.A[i][j] + (this->A[i][k] * b.A[k][j]) % Mi) % Mi; //res[i][j] = sum(a[i][k]*b[k][j]), k = 0..n-1 } return res; } bool bit[4]; //this function returns true if we can put two masks together and false otherway bool CanGo (int mask1, int mask2, int len)//mask1 and mask2 - two masks, len - their length { for (int i = 0; i < len - 1; i++) { //the ith bit from the end of first mask(numeration from 0) bit[0] = (mask1 >> i) & 1; //the i+1th bit from the end of first mask(numeration from 0) bit[1] = (mask1 >> (i + 1)) & 1; //the ith bit from the end of second mask(numeration from 0) bit[2] = (mask2 >> i) & 1; //the i+1th bit from the end of second mask(numeration from 0) bit[3] = (mask2 >> (i + 1)) & 1; if (bit[0] && bit[1] && bit[2] && bit[3]) return false; //if all bits are 1 (cells are black) return false if (!bit[0] && !bit[1] && !bit[2] && !bit[3]) return false;//if all bits are 0 (cells are white) return false too } return true;//if there weren't rectangle 2*2 of all bits 0 or all bits 1 we should return true } TMatr A; TMatr B; int n; ll m; int main () { //freopen ("input.txt", "r", stdin); //freopen ("output.txt", "w", stdout); cin >> n >> m; //assert (n >= 1 && n <= 6); //assert (m >= 1 && m < (1LL << 63)); int k = 1 << n; A.n = k; for (int m1 = 0; m1 < k; m1++) for (int m2 = 0; m2 < k; m2++) A.A[m1][m2] = CanGo(m1, m2, n);//fill the matrix D. D[i][j] = true if we can put masks i and j together and false otherway B.n = k; CLR(B.A, 0); for (int i = 0; i < k; i++) B.A[i][i] = 1;//single matrix m--; //binary power while (m){ if (m & 1) B = B * A; A = A * A; m >>= 1; } ll ans = 0; //answer is sum of values in all cells of result matrix for (int i = 0; i < k; i++) for (int j = 0; j < k; j++) ans = (ans + B.A[i][j]) % Mi; printf ("%d\n", ans); return 0; }