#include using namespace std; template vector> mat_mul(vector> a, vector> b) { vector> c(a.size(), vector(b[0].size())); for (int i = 0; i < a.size(); ++i) for (int j = 0; j < b.size(); ++j) for (int k = 0; k < b[j].size(); ++k) c[i][k] = c[i][k] + a[i][j] * b[j][k]; return c; } template vector> mat_inv(vector> a) { if (a.size() == 2) { T t = a[0][0] * a[1][1] - a[0][1] * a[1][0]; return {{a[1][1] / t, -a[0][1] / t}, {-a[1][0] / t, a[0][0] / t}}; } return assert(false), a; } template vector> mat_sub(vector> a, vector> b) { vector> c(a.size(), vector(a[0].size())); for (int i = 0; i < a.size(); ++i) for (int j = 0; j < a[0].size(); ++j) c[i][j] = a[i][j] - b[i][j]; return c; } template vector> mat_pow(vector> a, long long p) { vector> r(a.size(), vector(a.size())); for (int i = 0; i < r.size(); ++i) r[i][i] = 1; for (; p; p >>= 1) { if (p & 1) r = mat_mul(r, a); a = mat_mul(a, a); } return r; } template struct ModInt { int val; ModInt(int v = 0) : val((v % mod + mod) % mod) {} ModInt(long long v) : val((v % mod + mod) % mod) {} ModInt &operator=(int v) { return val = (v % mod + mod) % mod, *this; } ModInt &operator=(const ModInt &oth) { return val = oth.val, *this; } ModInt operator+(const ModInt &oth) const { int u = (val + oth.val) % mod; return u < 0 ? u + mod : u; } ModInt operator-(const ModInt &oth) const { int u = (val - oth.val) % mod; return u < 0 ? u + mod : u; } ModInt operator*(const ModInt &oth) const { return 1LL * val * oth.val % mod; } ModInt operator/(const ModInt &oth) const { function modinv = [&](int a, int b, int x, int y) { if (b == 0) return x < 0 ? x + mod : x; return modinv(b, a - a / b * b, y, x - a / b * y); }; return *this * modinv(oth.val, mod, 1, 0); } ModInt operator-() const { return mod - val; } }; signed main() { const int MOD = int(1e9 + 7); long long N; cin >> N; int M; cin >> M; vector>> I = {{1, 0}, {0, 1}}; vector>> T = {{1, 1}, {1, 0}}; vector>> TM = mat_pow(T, M); vector>> TMN = mat_pow(TM, N); vector>> A0 = {{1}, {0}}; cout << mat_mul(mat_mul(TM, mat_mul(mat_sub(I, TMN), mat_inv(mat_sub(I, TM)))), A0)[1][0].val << endl; return 0; }