#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;
#define repeat(i, a, b) for(int i = (a); (i) < (b); ++(i))
#define rep(i, n) repeat(i, 0, n)

struct IoSetup {
#define endl '\n'
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        // cout << fixed << setprecision(20);
        // cerr << fixed << setprecision(20);
    }
} iosetup;

// BEGIN CUT HERE
namespace edamat {

constexpr std::uint_fast64_t totient(std::uint_fast64_t x) noexcept {
    using u64 = std::uint_fast64_t;
    u64 ret = x;
    for(u64 i = static_cast<u64>(2); i * i <= x; ++i) {
        if(x % i == static_cast<u64>(0)) {
            ret -= ret / i;
            x /= i;
            while(x % i == static_cast<u64>(0)) {
                x /= i;
            }
        }
    }
    if(x != static_cast<u64>(1)) {
        ret -= ret / x;
    }
    return ret;
}

template <std::uint_fast64_t Modulus,
          std::uint_fast64_t InverseExp =
              totient(Modulus) - static_cast<std::uint_fast64_t>(1)>
class modint {
    using u64 = std::uint_fast64_t;

    static_assert(Modulus < static_cast<u64>(1) << static_cast<u64>(32),
                  "Modulus must be less than 2**32");

    u64 a;

    constexpr modint &negate() noexcept {
        if(a != static_cast<u64>(0)) {
            a = Modulus - a;
        }
        return *this;
    }

   public:
    constexpr modint(const u64 x = static_cast<u64>(0)) noexcept
        : a(x % Modulus) {}
    constexpr u64 &value() noexcept { return a; }
    constexpr const u64 &value() const noexcept { return a; }
    constexpr modint operator+() const noexcept { return modint(*this); }
    constexpr modint operator-() const noexcept {
        return modint(*this).negate();
    }
    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 modint rhs) noexcept {
        a += rhs.a;
        if(a >= Modulus) {
            a -= Modulus;
        }
        return *this;
    }
    constexpr modint &operator-=(const modint rhs) noexcept {
        if(a < rhs.a) {
            a += Modulus;
        }
        a -= rhs.a;
        return *this;
    }
    constexpr modint &operator*=(const modint rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    constexpr modint &operator/=(modint rhs) noexcept {
        u64 exp = InverseExp;
        while(exp) {
            if(exp % static_cast<u64>(2) != static_cast<u64>(0)) {
                *this *= rhs;
            }
            rhs *= rhs;
            exp /= static_cast<u64>(2);
        }
        return *this;
    }
    constexpr bool operator==(const modint rhs) const noexcept {
        return a == rhs.a;
    }
    constexpr bool operator!=(const modint rhs) const noexcept {
        return a != rhs.a;
    }
};

template <class T, std::uint_fast64_t v>
class modint_constant {
   public:
    static constexpr T value = static_cast<T>(v);

    using value_type = T;
};
template <class T, std::uint_fast64_t v>
constexpr T modint_constant<T, v>::value;

}  // namespace edamat
using modint = edamat::modint<1000000007>;
// END CUT HERE

// extended Euclidean Algorithm
// ax + by = gcd(a, b)
// return : gcd(a, b)
template <typename Integer = int_fast64_t>
constexpr Integer extgcd(Integer a, Integer b, Integer &x, Integer &y) {
    Integer u = 0, v = 1, q = 0, tmp = 0;
    x = v = 1;
    y = u = 0;

    while(b) {
        q = a / b;
        x ^= u ^= x ^= u;
        u = u - q * x;
        y ^= v ^= y ^= v;
        v = v - q * y;
        a ^= b ^= a ^= b;
        b = b - q * a;
    }

    return a;
}

// mod inverse(設計が変わるかもしれません)
// return : val^(-1) mod MOD
template <uint_fast64_t MOD, typename Integer = int_fast64_t>
constexpr Integer modinv(Integer val) {
    int_fast64_t ret = 0, tmp = 0;

    extgcd<int_fast64_t>(static_cast<int_fast64_t>(val),
                         static_cast<int_fast64_t>(MOD), ret, tmp);

    return static_cast<Integer>(ret > 0 ? ret % MOD : (MOD - (-ret % MOD)));
}

// const expression factorial mod MOD
template <std::size_t N, std::uint_fast64_t MOD>
struct Fact {
    std::uint_fast64_t val[N + 1];

    constexpr Fact() : val() {
        val[0] = 1;
        for(std::size_t i = 1; i <= N; ++i) val[i] = val[i - 1] * i % MOD;
    }
};

// const expression factorial inverse mod MOD
template <std::size_t N, std::uint_fast64_t MOD, std::uint_fast64_t F>
struct IFact {
    std::uint_fast64_t val[N + 1];

    constexpr IFact() : val() {
        val[N] = F;
        for(std::size_t i = N; i; --i) val[i - 1] = val[i] * i % MOD;
    }
};

constexpr std::uint_fast64_t MOD = 1000000007, maxN = 2000000;

constexpr auto fact = Fact<maxN, MOD>();
constexpr auto ifact = IFact<maxN, MOD, modinv<MOD>(fact.val[maxN])>();

// const expression binomial mod MOD
constexpr std::uint_fast64_t binommod(std::uint_fast64_t n,
                                      std::uint_fast64_t r) {
    if(r < 0 || r > n) return 0;
    return fact.val[n] * (ifact.val[r] * ifact.val[n - r] % MOD) % MOD;
}

void ABC145_D() {
    auto ng = []() {
        cout << 0 << endl;
        exit(0);
    };

    i64 X, Y;
    cin >> X >> Y;
    if((X + Y) % 3 != 0) ng();
    modint ans(1);
    i64 x = X - (X + Y) / 3, y = Y - (X + Y) / 3;
    cout << binommod(x + y, y) << endl;
};

int main() {
    ABC145_D();
    return 0;
};


Measured memory_bytes: 256