#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <map>
#include <numeric>
#include <functional>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>

using namespace std;

typedef long long LL;
typedef vector<LL> VL;
typedef vector<vector<LL>> VVL;
typedef vector<string> VS;

#define REPD(i,a,b) for (LL i=(a);i<(b);i++)
#define REP(i,n) REPD(i,0,n)

LL llRead(){
  LL a;
  cin >> a;
  return a;
};

string stringRead(){
  string a;
  cin >> a;
  return a;
};

vector<LL> vlRead(LL a){
  vector<LL> rv;
  REP(i, a){
    LL input;
    cin >> input;
    rv.push_back(input);
  }
  return rv;
}

vector<string> vsRead(LL a){
  vector<string> rv;
  REP(i, a){
    string input;
    cin >> input;
    rv.push_back(input);
  }
  return rv;
}
vector<vector<LL>> vvlRead(LL a, LL b){
  vector<vector<LL>> rv;
  REP(i, a){
    rv.push_back(vector<LL>());
    REP(j, b) {
      LL input;
      cin >> input;
      rv.at(i).push_back(input);
    }
  }
  return rv;
}

#if 0
#define debug(d) debug1(__LINE__,#d, d)
void debug1(LL line, const char* name, VL& v) {
  cout << line << ":" << name << ":vector<LL>(" << v.size() << ") ";
  REP(i, (LL)v.size()) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(LL line, const char* name, LL i) {
  cout << line << ":" << name << ":LL " << i << endl;;
}
void debug1(LL line, const char* name, VS& v) {
  cout << line << ":" << name << ":vector<string>(" << v.size() << ") ";
  REP(i, (LL)v.size()) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(LL line, const char* name, VVL& v) {
  cout << line << ":" << name << ":vector<vector<LL>>(" << v.size() << ") ";
  REP(i, (LL)v.size()) {
    REP(j, (LL)v.at(i).size()) {
      cout << v.at(i).at(j) << " ";
    }
    cout << ", ";
  }
  cout << endl;
}
void debug1(LL line, const char* name, char* s) {
  cout << line << ":" << name << ":char* " << s << endl;;
}
void debug1(LL line, const char* name, vector<const char*>& v) {
  cout << line << ":" << name << ":vector<const char*>(" << v.size() << ") ";
  REP(i, (LL)v.size()) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(LL line, const char* name, priority_queue<LL>& p) {
  cout << line << ":" << name << ":priority_queue<LL>(" << p.size() << ") ";
  priority_queue<LL> copy = p;
  while(!copy.empty()) {
    cout << copy.top() << " ";
    copy.pop();
  }
  cout << endl;
}
void debug1(LL line, const char* name, vector<pair<LL,LL>>& v) {
  cout << line << ":" << name << ":vector<pair<LL,LL>>(" << v.size() << ") ";
  REP(i, (LL)v.size()) {
    cout << v.at(i).first << "," << v.at(i).second << " ";
  }
  cout << endl;
}
#else
#define debug(n)
#endif

#define BASE (1000000007)

LL factm(LL n) {
  debug(n);
  LL ret = 1;
  REPD(i,2,n+1) {
    ret*=i;
    ret=ret%BASE;
  }
  debug(ret);
  return ret;
}

LL inv(LL a) {
    LL b = BASE, u = 1, v = 0;
    while (b) {
        LL t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= BASE;
    if (u < 0) u += BASE;
    return u;
}

int main(int argc, const char * argv[]) {
	cout.precision(16);
  // source code

  auto gx = llRead();
  auto gy = llRead();

  /*
  map<pair<LL,LL>, LL> memo;

  function<LL(LL,LL)> count = [&](LL x, LL y)->LL {
    if (x == gx && y == gy) {
      return 1;
    }
    if (x > gx || y > gy) {
      return 0;
    }
    auto m = memo.find(make_pair(x,y));
    if (m != memo.end()) {
      return m->second;
    }
    LL n = count(x+1,y+2) + count(x+2, y+1);
    memo[make_pair(x,y) ]=n;
    return n;
  };
  cout << count(0,0) << endl;
  */

  /*
  LL a = gx;
  LL b = 0;

  while(true) {
    if (a*2 + b> gy) {
      a-=2;
      b+=1;
      continue;
    }
    if (a*2 +b == gy) {
      break;
    }
    if (a*2+b < gy) {
      cout << 0 << endl;
    }
  }
  debug(a);
  debug(b);
  */

  // a+b*2==gx a==gx-b*2
  // a*2+b==gy a*2==gy-b a==gy/2-b/2
  // gy/2-b/2+b*2==gx gy-b+b*4==gx*2 gy+b*3==gx*2 b*3==gx*2-gy b=gx*2/3-gy/3
  // gx*2-b*2*2+b==gy gx*2-b*3==gy b*3==gx*2-gy
  // b==gy-a*2
  // a+gy*2-a*4==gx a*3==gy*2-gx
  debug(gx);
  debug(gy);
  if ((gy*2-gx)%3 != 0 || (gx*2-gy)%3 != 0) {
    cout << 0 << endl;
    return 0;
  }

  LL a = (gy*2-gx)/3;
  LL b = (gx*2-gy)/3;
  debug(a);
  debug(b);
  if (a<0 || b <0) {
    cout << 0 << endl;
    return 0;
  }
  if (a==0 || b ==0) {
    cout << 1 << endl;
    return 0;
  }
  
  LL abe = factm(a+b);
  debug(abe);
  LL ae = factm(a);
  debug(ae);
  LL be = factm(b);
  debug(be);

  if ((ae*be)%BASE == 0) {
    cout << abe << endl;
  } else {
    cout << (abe*inv((ae*be)%BASE))%BASE << endl;
  }


  return 0;
}


Measured memory_bytes: 256