#include<bits/stdc++.h>
template <class T>
T inverse(T a, T m) {
    T u=0,v=1;
    while(a!=0){
        T t=m/a;
        m-=t*a;std::swap(a,m);
        u-=t*v;std::swap(u,v);
    }
    assert(m==1);
    return u;
}
template <class T>
class modular {
    public:
        int value;
        constexpr modular() = default;
        constexpr modular(const modular&) = default;
        constexpr modular(modular&&) = default;
        modular& operator=(const modular&) = default;
        modular& operator=(modular&&) = default;
        template <class U>modular (const U& x) {value = normalize(x);}

        template <class U>
        static int normalize(const U& x) {
            int v=static_cast<int>(-mod()<=x&&x<mod()?x:x%mod());
            if(v<0)v+=mod();
            return v;
        }

        template <class U> explicit operator U()const{return static_cast<U>(value);}
        constexpr static auto mod(){return T::value;}

        auto&operator+=(const modular&other) {if((value+=other.value)>=mod())value-=mod();return *this;}
        auto&operator-=(const modular& other){if ((value-=other.value)<0)value+=mod();return *this;}
        template <class U>auto& operator+=(const U& other){return*this+=modular(other);}
        template <class U>auto& operator-=(const U& other){return*this-=modular(other);}
        auto operator-()const{return modular(-value);}
        auto&operator++(){return*this+=1;}
        auto&operator--(){return*this-=1;}
        auto operator++(int){modular result(*this);operator++();return result;}
        auto operator--(int){modular result(*this);operator--();return result;}

        template <class U = T>
        auto&operator*=(const modular&rhs){value=normalize(static_cast<std::int64_t>(value)*static_cast<std::int64_t>(rhs.value));return *this;}
        auto&operator/=(const modular&rhs){return*this*=modular(inverse(rhs.value, mod()));}
};
template<class T>struct is_modular:std::false_type{};
template<class T>struct is_modular <modular<T>>:std::true_type{};
template<class T>constexpr bool is_modular_v=is_modular<T>::value;

template<class t> bool operator==(const modular<t>& lhs, const modular<t>& rhs){return lhs()==rhs();}
template<class T,class U>bool operator==(const modular<T>& lhs, U rhs){return lhs==modular<T>(rhs);}
template<class T,class U>bool operator==(U lhs, const modular<T>& rhs){return modular<T>(lhs)==rhs;}

template<class T> bool operator!=(const modular<T>& lhs, const modular<T>& rhs){return !(lhs == rhs);}
template<class T,class U> bool operator!=(const modular<T>& lhs, U rhs){return !(lhs==rhs);}
template<class T,class U> bool operator!=(U lhs, const modular<T>& rhs){return !(lhs==rhs);}

template<class T> modular<T> operator+(const modular<T>& lhs, const modular<T>& rhs){return modular<T>(lhs)+=rhs;}
template<class T,class U> modular<T> operator+(const modular<T>& lhs, U rhs){return modular<T>(lhs)+=rhs;}
template<class T,class U> modular<T> operator+(U lhs, const modular<T>& rhs){return modular<T>(lhs)+=rhs;}

template<class T> modular<T> operator-(const modular<T>& lhs, const modular<T>& rhs){return modular<T>(lhs)-=rhs;}
template<class T,class U> modular<T> operator-(const modular<T>& lhs, U rhs){return modular<T>(lhs)-=rhs;}
template<class T,class U> modular<T> operator-(U lhs, const modular<T>& rhs){return modular<T>(lhs)-=rhs;}

template<class T> modular<T> operator*(const modular<T>& lhs, const modular<T>& rhs){return modular<T>(lhs)*=rhs;}
template<class T,class U> modular<T> operator*(const modular<T>& lhs, U rhs){return modular<T>(lhs)*=rhs;}
template<class T,class U> modular<T> operator*(U lhs, const modular<T>& rhs){return modular<T>(lhs)*=rhs;}

template<class T> modular<T> operator/(const modular<T>& lhs, const modular<T>& rhs){return modular<T>(lhs)/=rhs;}
template<class T, class U> modular<T> operator/(const modular<T>& lhs, U rhs){return modular<T>(lhs)/=rhs;}
template<class T, class U> modular<T> operator/(U lhs, const modular<T>& rhs){return modular<T>(lhs)/=rhs;}

template<class T, class U>
modular<T> power (const modular<T>& a, U b) {
    assert(b>=0);
    modular<T>x=a,ret=1;
    for (;b>0;b/=2){
        if(b%2==1)ret*=x;
        x*=x;
    }
    return ret;
}

template <class T>std::string to_string(const modular<T>& a) {
    return std::to_string(a.value);
}
template <class T>auto operator<<
(std::ostream& os, const T& a)->std::enable_if_t<is_modular_v<T>, std::ostream&>{
    return os << a.value;
}
template <class T>auto operator>>
(std::istream& is, T& a)-> std::enable_if_t<is_modular_v<T>, std::istream&> {
    long long x;is>>x;
    a=T(x);
    return is;
}

constexpr int mod = 1'000'000'007;
using mint = modular<std::integral_constant<std::decay_t<decltype(mod)>, mod>>;

template < typename Value >
class factorials {
        std::vector< Value > fact, finv;

    public:
        factorials()=default;

        void build(int n) {
            fact.resize(n), finv.resize(n);
            fact.at(0) = 1;
            for (int i = 1; i < n; i++) fact.at(i) = fact.at(i - 1) * Value(i);
            finv.at(n - 1) = Value(1) / fact.at(n - 1);
            for (int i = n - 2; i >= 0; i--) finv.at(i) = finv.at(i + 1) * Value(i + 1);
        }
        auto operator()    (int i) const {return fact.at(i);}
        auto inv                 (int i) const {return finv.at(i);}
        auto binom(int i, int j) const {
            assert(0 <= i);
            if (j < 0 ||i < j) return Value(0);
            return fact.at(i) * finv.at(j) * finv.at(i - j);
        }
        auto deal(int i, int j) const
            { return binom(i + j - 1, j - 1); }
};

int main(){
    int x,y;std::cin>>x>>y;
    if((x+y)%3){
        std::cout<<0<<std::endl;
        return 0;
    }
    int n=(x+y)/3;
    int k=(n+(x-y))/2;
    factorials<mint>fact;
    fact.build(n+1);
    std::cout<<fact.binom(n,k)<<std::endl;
}



Measured memory_bytes: 5504