#include <bits/stdc++.h>
#define GET_REP(_1, _2, _3, NAME, ...) NAME
#define rep(...) GET_REP(__VA_ARGS__, irep, _rep)(__VA_ARGS__)
#define rep1(...) GET_REP(__VA_ARGS__, irep1, _rep1)(__VA_ARGS__)
#define _rep(i, n) irep (i, 0, n)
#define _rep1(i, n) irep1(i, 1, n)
#define irep(i, a, n) for (int i = a; i < (int)(n); ++i)
#define irep1(i, a, n) for (int i = a; i <= (int)(n); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define rrep1(i, n) for (int i = (int)(n); i >= 1; --i)
#define allrep(X, x) for (auto &&X : x)
#define all(x) begin(x), end(x)
#ifdef LOCAL
  #include "../../Lib/cout_container.hpp"
  #define debug(x) cout << #x " => " << (x) << endl
#else
  #define debug(x) 0
#endif
using lint = long long;
constexpr int    INF  = 1 << 28;
constexpr lint   INFL = 1LL << 60;
constexpr int    MOD  = (int)1e9 + 7;
constexpr double EPS  = 1e-9;
using namespace std;
namespace { struct INIT { INIT() { cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(15); } } INIT; }

template <long long mod_num>
class ModInt {
  long long x;

  public:
  constexpr ModInt(const long long num = 0) : x(num % mod_num) { if (x < 0) x += mod_num; }
  constexpr bool   operator==(const ModInt &r) const { return this->x == r.x; }
  constexpr bool   operator!=(const ModInt &r) const { return this->x != r.x; }
  constexpr bool   operator<(const ModInt &r) const { return this->x < r.x; }
  constexpr bool   operator>(const ModInt &r) const { return this->x > r.x; }
  constexpr bool   operator<=(const ModInt &r) const { return this->x <= r.x; }
  constexpr bool   operator>=(const ModInt &r) const { return this->x >= r.x; }
  constexpr ModInt operator+(const ModInt &r) const { return ModInt(*this) += r; }
  constexpr ModInt operator-(const ModInt &r) const { return ModInt(*this) -= r; }
  constexpr ModInt operator*(const ModInt &r) const { return ModInt(*this) *= r; }
  constexpr ModInt operator/(const ModInt &r) const { return ModInt(*this) /= r; }
  friend ModInt operator+(const long long &l, const ModInt &r) { return ModInt(l) += r; }
  friend ModInt operator-(const long long &l, const ModInt &r) { return ModInt(l) -= r; }
  friend ModInt operator*(const long long &l, const ModInt &r) { return ModInt(l) *= r; }
  friend ModInt operator/(const long long &l, const ModInt &r) { return ModInt(l) /= r; }
  constexpr ModInt &operator++() { return *this += 1; }
  constexpr ModInt &operator--() { return *this -= 1; }
  constexpr ModInt &operator+=(const ModInt &r) {
    x += r.x;
    if (x >= mod_num) x -= mod_num;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &r) {
    if (x < r.x) x += mod_num;
    x -= r.x;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &r) {
    x = x * r.x % mod_num;
    return *this;
  }
  constexpr ModInt &operator/=(const ModInt &r) {
    *this *= r.inverse();
    return *this;
  }
  constexpr ModInt inverse(void) const {
    long long a = x, b = mod_num, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
  constexpr ModInt pow(long long n) const { return pow(x, n); }
  static ModInt pow(long long x, long long n) {
    ModInt ret(1), mul(x);
    while (n) {
      if (n & 1) ret *= mul;
      mul *= mul;
      n  >>= 1;
    }
    return ret;
  }
  friend istream &operator>>(istream &is, ModInt &r) {
    long long n;
    is >> n;
    r = ModInt(n);
    return is;
  }
  friend ostream &operator<<(ostream &os, const ModInt &r) { return os << r.x; }
  explicit operator int() const { return x; }
  explicit operator long long() const { return x; }
  explicit operator double() const { return x; }
};

class CombinationMod {
  int mod;
  vector<long long> fac, finv, inv;

  public:
  CombinationMod(int max_n, int prime_mod) : fac(vector<long long>(max_n + 1)), finv(vector<long long>(max_n + 1)), inv(vector<long long>(max_n + 1)), mod(prime_mod) {
    fac[0]  = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1]  = 1;
    for (int i = 2; i < max_n + 1; i++) {
      fac[i]  = fac[i - 1] * i % mod;
      inv[i]  = mod - inv[mod % i] * (mod / i) % mod;
      finv[i] = finv[i - 1] * inv[i] % mod;
    }
  }
  long long comb(int n, int r) {
    if (n < r) return 0;
    if (n < 0 || r < 0) return 0;
    return fac[n] * (finv[r] * finv[n - r] % mod) % mod;
  }
};

using mint = ModInt<MOD>;
int main(void) {
  int x, y;
  cin >> x >> y;
  CombinationMod cm(max(x, y), MOD);
  if ((x + y) % 3) {
    cout << 0 << endl;
    return 0;
  }
  int  allnum = (x + y) / 3;
  lint cnt = 0;
  rep (i, x + 1) {
    int xleft = x - i, yleft = y - 2 * i;
    if (yleft < 0 || xleft & 1) continue;
    int ynum = xleft / 2;
    if (ynum != yleft) continue;
    cnt += cm.comb(allnum, i);
  }
  cout << cnt << endl;
  return 0;
}

Measured memory_bytes: 23680