#ifndef _GLIBCXX_NO_ASSERT #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #endif // C++ #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 #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif using namespace std; #define rep(i, n) for(int i = 0; i < n; i++) #define revrep(i, n) for(int i = n-1; i >= 0; i--) typedef long long ll; typedef pair Pint; typedef pair P; typedef vector vec; typedef vector mat; //typedef pair> P; //typedef tuple T; ll INFL = 1000000000000000010;//10^18 = 2^60 int INF = 1000000000;//10^9 ll MOD = 1000000007; //vector dy = {0,0,1,-1}; //vector dx = {1,-1,0,0}; mat mul_mat(mat &A, mat &B){ mat res(A.size(), vec(B[0].size())); rep(i, A.size())rep(k, B.size())rep(j, B[0].size()){ res[i][j] = (res[i][j] + (A[i][k] * B[k][j]) % MOD) % MOD; } return res; } mat pow_mat(mat &A, ll n){ mat res(A.size(), vec(A.size())); rep(i, A.size()) res[i][i] = 1; while(n > 0){ if(n&1) res = mul_mat(res, A); A = mul_mat(A, A); n >>= 1; } return res; } int main(void){ ll N, M; cin >> N >> M; mat A(2, vec(2)); A[0][0] = 1; A[0][1] = 1; A[1][0] = 1; A[1][1] = 0; A = pow_mat(A, M); mat B(4, vec(4, 0)); for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ B[i][j] = A[i][j]; } } B[2][0] = 1; B[3][1] = 1; B[2][2] = 1; B[3][3] = 1; B = pow_mat(B, N); cout << (B[0][1] + B[2][1]) % MOD << endl; }