#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
using ll = long long;
ll ipow(ll x, ll p) {
  ll ret = 1, piv = x;
  while (p) {
    if (p & 1) ret = ret * piv % mod;
    piv = piv * piv % mod;
    p >>= 1;
  }
  return ret;
}
vector<int> berlekamp_massey(vector<int> x) {
  vector<int> ls, cur;
  int lf, ld;
  for (int i = 0; i < x.size(); i++) {
    ll t = 0;
    for (int j = 0; j < cur.size(); j++) {
      t = (t + 1ll * x[i - j - 1] * cur[j]) % mod;
    }
    if ((t - x[i]) % mod == 0) continue;
    if (cur.empty()) {
      cur.resize(i + 1);
      lf = i;
      ld = (t - x[i]) % mod;
      continue;
    }
    ll k = -(x[i] - t) * ipow(ld, mod - 2) % mod;
    vector<int> c(i - lf - 1);
    c.push_back(k);
    for (auto &j : ls) c.push_back(-j * k % mod);
    if (c.size() < cur.size()) c.resize(cur.size());
    for (int j = 0; j < cur.size(); j++) {
      c[j] = (c[j] + cur[j]) % mod;
    }
    if (i - lf + (int)ls.size() >= (int)cur.size()) {
      tie(ls, lf, ld) = make_tuple(cur, i, (t - x[i]) % mod);
    }
    cur = c;
  }
  for (auto &i : cur) i = (i % mod + mod) % mod;
  return cur;
}
int get_nth(vector<int> rec, vector<int> dp, ll n) {
  int m = rec.size();
  vector<int> s(m), t(m);
  s[0] = 1;
  if (m != 1)
    t[1] = 1;
  else
    t[0] = rec[0];
  auto mul = [&rec](vector<int> v, vector<int> w) {
    int m = v.size();
    vector<int> t(2 * m);
    for (int j = 0; j < m; j++) {
      for (int k = 0; k < m; k++) {
        t[j + k] += 1ll * v[j] * w[k] % mod;
        if (t[j + k] >= mod) t[j + k] -= mod;
      }
    }
    for (int j = 2 * m - 1; j >= m; j--) {
      for (int k = 1; k <= m; k++) {
        t[j - k] += 1ll * t[j] * rec[k - 1] % mod;
        if (t[j - k] >= mod) t[j - k] -= mod;
      }
    }
    t.resize(m);
    return t;
  };
  while (n) {
    if (n & 1) s = mul(s, t);
    t = mul(t, t);
    n >>= 1;
  }
  ll ret = 0;
  for (int i = 0; i < m; i++) ret += 1ll * s[i] * dp[i] % mod;
  return ret % mod;
}
int guess_nth_term(vector<int> x, ll n) {
  if (n < x.size()) return x[n];
  vector<int> v = berlekamp_massey(x);
  if (v.empty()) return 0;
  return get_nth(v, x, n);
}
struct elem {
  int x, y, v;
};
vector<int> get_min_poly(int n, vector<elem> M) {
  vector<int> rnd1, rnd2;
  mt19937 rng(0x14004);
  auto randint = [&rng](int lb, int ub) {
    return uniform_int_distribution<int>(lb, ub)(rng);
  };
  for (int i = 0; i < n; i++) {
    rnd1.push_back(randint(1, mod - 1));
    rnd2.push_back(randint(1, mod - 1));
  }
  vector<int> gobs;
  for (int i = 0; i < 2 * n + 2; i++) {
    int tmp = 0;
    for (int j = 0; j < n; j++) {
      tmp += 1ll * rnd2[j] * rnd1[j] % mod;
      if (tmp >= mod) tmp -= mod;
    }
    gobs.push_back(tmp);
    vector<int> nxt(n);
    for (auto &i : M) {
      nxt[i.x] += 1ll * i.v * rnd1[i.y] % mod;
      if (nxt[i.x] >= mod) nxt[i.x] -= mod;
    }
    rnd1 = nxt;
  }
  auto sol = berlekamp_massey(gobs);
  reverse(sol.begin(), sol.end());
  return sol;
}
ll det(int n, vector<elem> M) {
  vector<int> rnd;
  mt19937 rng(0x14004);
  auto randint = [&rng](int lb, int ub) {
    return uniform_int_distribution<int>(lb, ub)(rng);
  };
  for (int i = 0; i < n; i++) rnd.push_back(randint(1, mod - 1));
  for (auto &i : M) {
    i.v = 1ll * i.v * rnd[i.y] % mod;
  }
  auto sol = get_min_poly(n, M)[0];
  if (n % 2 == 0) sol = mod - sol;
  for (auto &i : rnd) sol = 1ll * sol * ipow(i, mod - 2) % mod;
  return sol;
}
ll n, m;
int main() {
  cin >> n >> m;
  if (n > m) swap(n, m);
  if (n >= 3) {
    cout << 0;
    return 0;
  }
  if (n == 1) {
    cout << 2;
    return 0;
  }
  cout << get_nth({0, 1, 1}, {2, 6, 8}, m - 1);
  return 0;
}
