#include <bits/stdc++.h>
using namespace std;

//C++14 (GCC 5.4.1)

#define LLINF (1LL<<60)
typedef long long ll;
#define mod 1000000007

#define repd(i,a,b) for (int i=(a);i<(b);i++)
#define rep(i,n) repd(i,0,n)
#define rrepd(i,a,b) for(int i=(a);i>=(b);i--)

template<typename T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<typename T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template < typename T > inline string toString( const T &a ) { ostringstream oss; oss << a; return oss.str(); }

#define dbg_v1(i,V) do{cout<<"-v1----\n";rep(i,V.size())cout<<" "<<i<<"\t:"<<V[i]<<endl;cout<<endl;}while(0)
#define dbg_v2(i,k,V) do{cout<<"-v2----\n";rep(i,V.size()){rep(k,V[0].size())cout<<" "<<V[i][k];cout<<endl;}}while(0)
#define lower_bound_idx(V,c) distance(V.begin(),lower_bound(V.begin(),V.end(),c))

template<uint_fast64_t modulo = 1000000007ul>
class ModInt {
    using ui64 = uint_fast64_t;
    using ll = long long;
public:
    ui64 val=0ul;
    constexpr ModInt() : val(0) {}
    constexpr ModInt(const ui64 x) : val(x % modulo) {}
    constexpr ModInt operator+(const ModInt rhs) const noexcept { return ModInt(*this) += rhs; }
    constexpr ModInt operator-(const ModInt rhs) const noexcept { return ModInt(*this) -= rhs; }
    constexpr ModInt operator*(const ModInt rhs) const noexcept { return ModInt(*this) *= rhs; }
    constexpr ModInt operator/(const ModInt rhs) const noexcept { return ModInt(*this) /= rhs; }
    constexpr ModInt operator/(const ll rhs) const noexcept { return ModInt(*this) /= rhs; }
    constexpr ModInt operator+=(const ll rhs) noexcept { auto hs = ModInt<modulo>(rhs); (*this) += hs; return *this; }
    constexpr ModInt operator-=(const ll rhs) noexcept { auto hs = ModInt<modulo>(rhs); (*this) -= hs; return *this; }
    constexpr ModInt operator*=(const ll rhs) noexcept { auto hs = ModInt<modulo>(rhs); (*this) *= hs; return *this; }
    constexpr ModInt &operator/=(ll rhs) noexcept { auto hs = ModInt<modulo>(rhs); (*this) /= hs; return *this; }

    constexpr ModInt operator+=(const ModInt rhs) noexcept {
        val += rhs.val;
        if (val >= modulo) val -= modulo;
        return *this;
    }
    constexpr ModInt operator-=(const ModInt rhs) noexcept {
        if (val < rhs.val) val += modulo;
        val -= rhs.val;
        return *this;
    }
    constexpr ModInt operator*=(const ModInt rhs) noexcept {
        val = val * rhs.val % modulo;
        return *this;
    }
    constexpr ModInt &operator/=(ModInt rhs) noexcept {
        ui64 exp = modulo - 2;
        while (exp > 0) {
            if (exp & 1ul) *this *= rhs;
            rhs *= rhs;
            exp >>= 1ul;
        }
        return *this;
    }
    constexpr ModInt &operator++() noexcept {
        val++;
        if (val >= modulo) val -= modulo;
        return *this;
    }
    constexpr ModInt &operator--() noexcept {
        if (val == 0) val += modulo;
        val--;
        return *this;
    }
    constexpr bool operator<(const ModInt rhs) const noexcept { return val < rhs.val; }
    constexpr bool operator==(const ModInt rhs) const noexcept { return this->val == rhs.val; }
    constexpr bool operator!=(const ModInt rhs) const noexcept { return !(*this == rhs); }
    friend istream &operator>>(istream &in, ModInt &m) {
        in >> m.val;
        m.val %= modulo;
        return in;
    }
    friend ostream &operator<<(ostream &out, const ModInt &p) {
        out << p.val;
        return out;
    }
    constexpr ModInt pow(ui64 p) const {
        ModInt ans(1);
        ModInt mul(val);
        while (p > 0) {
            if (p & 1ul) ans *= mul;
            mul *= mul;
            p >>= 1ul;
        }
        return ans;
    }
    constexpr static ModInt arith_sum(ModInt<modulo> a, ModInt<modulo> d, ModInt<modulo> n) noexcept {
        return (a * ModInt<modulo>(2) + (n - 1) * d) * n / ModInt<modulo>(2);
    }
    constexpr ModInt operator~() const noexcept { return pow(modulo - 2); }
};

#define needF 10000000
vector<ModInt<>> f(needF+1,0), rf(needF+1,0);//f[x]=x!

void initF() {
    f[0] = 1;
    repd(i,1,needF+1) f[i]=f[i-1]*i;
    rf[needF] = ~f[needF];
    rrepd(i, needF-1, 0) rf[i] = rf[i+1] * (i+1);
}
#define nPk(n,k) (f[(n)] * rf[(n)-(k)])
#define nCk(n,k) (f[(n)] * rf[(n)-(k)]*rf[(k)])
#define nHk(n,k) nCr((n)+(k)-1,k)


int main() {
    ios::sync_with_stdio(false);//stdoutとcoutの同期解除
    cin.tie(nullptr);//cinとcoutの同期解除
    
    initF();
    
    int X,Y,a,b;
    cin >>X>>Y;
    
    ModInt<> ans;
    a=Y*2-X;
    b=X*2-Y;
    if(a<0||b<0||a%3!=0 || b%3!=0) ans=0;
    else{
        a/=3;
        b/=3;
        ans=f[a+b] * rf[a]*rf[b];
    }

    cout << ans <<endl;
    return (0);
}

Measured memory_bytes: 156544