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

using ll = long long;

template < unsigned MOD >
class Modint
{
public:
    using uint = unsigned;
    using u64 = uint64_t;
    using i64 = int64_t;

    Modint (const i64 dat = 0) : dat(dat >= 0 ? dat % MOD : (MOD - (-dat) % MOD) % MOD) {}

    constexpr Modint operator + (const Modint &v) const { return ( Modint(dat + v.dat) ); }
    constexpr Modint operator - () const { return ( Modint(-((i64)dat)) ); }
    constexpr Modint operator - (const Modint &v) const { return ( (*this) + -v ); }
    constexpr Modint operator * (const Modint &v) const { return ( Modint((u64)dat * v.dat) ); }

    constexpr Modint operator ~ () const {
        i64 a = dat, b = MOD, x1 = 1, x2 = 0, t;

        while ( b > 0 ) {
            t = a / b;
            swap(a -= t * b, b);
            swap(x1 -= t * x2, x2);
        }

        return ( Modint(x1) );
    }

    constexpr Modint operator / (const Modint &v) const { return ( (*this) * ~v ); }

    Modint &operator = (const i64 &v) { return ( (*this) = Modint < MOD > (v) ); }
    Modint &operator += (const Modint &v) { return ( (*this) = (*this) + v ); }
    Modint &operator -= (const Modint &v) { return ( (*this) = (*this) - v ); }
    Modint &operator *= (const Modint &v) { return ( (*this) = (*this) * v ); }
    Modint &operator /= (const Modint &v) { return ( (*this) = (*this) / v ); }

    constexpr Modint operator ^ (u64 n) const {
        Modint < MOD > ret(1), mul(dat);
        while ( n > 0 ) {
            if ( n & 1 ) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ( ret );
    }

    bool operator == (const Modint &v) { return ( dat == v.dat ); }
    bool operator != (const Modint &v) { return ( dat != v.dat ); }

    friend ostream& operator << (ostream &os, const Modint &p ) {
        return ( os << p.dat );
    }

    friend istream& operator >> (istream &is, Modint &p ) {
        i64 data;
        is >> data;
        p = Modint < MOD >(data);
        return ( is );
    }

private:
    uint dat;
};


template < unsigned MOD >
Modint < MOD > modFact(int n)
{
    static vector <Modint<MOD>> memo = {1, 1};
    if ( memo.size() < n ) memo.resize(n + 10, 0);
    if ( memo[n] == Modint<MOD>(0) ) {
        if ( n > 1 ) memo[n] = Modint < MOD >(n) * modFact< MOD >(n - 1);
    }
    return ( memo[n] );
}

template < unsigned MOD >
Modint < MOD > modInv(int n)
{
    static vector <Modint<MOD>> memo = {1, 1};

    if ( memo.size() < n ) memo.resize(n + 10, 0);
    if ( memo[n] == Modint<MOD>(0) ) {
        if ( n > 1 ) memo[n] = -modInv<MOD>(MOD % n) * Modint<MOD>(MOD / n);
    }
    return ( memo[n] );
}

template < unsigned MOD >
Modint < MOD > modFactInv(int n)
{
    static vector <Modint<MOD>> memo = {1, 1};

    if ( memo.size() < n ) memo.resize(n + 10, 0);
    if ( memo[n] == Modint<MOD>(0) ) {
        if ( n > 1 ) memo[n] = modInv<MOD>(n) * modFactInv<MOD>(n - 1);
    }
    return ( memo[n] );
}


template < unsigned MOD >
Modint < MOD > modChoose(int n, int r)
{
    return ( modFact<MOD>(n) * modFactInv<MOD>(r) * modFactInv<MOD>(n - r) );
}

constexpr int mod = 1000000007;
int main() {
        int X, Y;
        cin >> X >> Y;
        if ((X + Y) % 3 != 0 || (X + Y) / 3 > X || (X + Y) / 3 > Y) {
                cout << 0 << endl;
        } else {
                int n = (X + Y) / 3;
                int k = (X - n);
                cout << modChoose<mod>(n, k) << endl;
        }
        return (0);
}


Measured memory_bytes: 48220