#include <bits/stdc++.h>
#define ll long long int
#define itn int
#define endl "\n"
#define mod 1000000007
#define MAX 500005
#include<iomanip>
#define fast ios_base :: sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL)
#define test int t; cin >> t; while(t--)
#define inp(n) int n;cin >> n;
#define mp make_pair
#define pb push_back
#define bsearch binary_search
#define lbound lower_bound
#define ubound upper_bound
#define all(n) n.begin(), n.end()
#define forl(i,a,b) for(l i=a;i<b;i++)



//s

using namespace std;
//int a[1000007];
//vector <int> sievev;
//void sieve()
//{
//    for(int i=0;i<=1000006;i++)
//    a[i] = 1;
//
//    a[0]=a[1]=0;
//    for(int i=2;i<=1000;i++)
//    {
//        if(a[i] == 1)
//        {
//            sievev.push_back(i);
//            for(int j=2*i;j<=1000000;j=j+i)
//            a[j] = 0;
//        }
//    }
//    for(int i=1001;i<=1000000;i++)
//        if(a[i]==1)
//            sievev.push_back(i);
//}
//
//template<class typ> class SegTree{int n,N; typ *arr,*tree; int built=0; public: SegTree(typ a[],int nn) { n = nn; arr = new typ[n]; arr = a; N = 100000; tree = new typ[N*2]; } SegTree(int nn){ n = nn; arr = new typ[n]; N = 100000; tree = new typ[N*2];} typ& operator[](int i){return arr[i];} void build(){ for (int i=0; i<n; i++) tree[n+i] = arr[i]; for (int i = n - 1; i > 0; --i) tree[i] = tree[i<<1] + tree[i<<1 | 1]; built=1;} void update(int p, typ value){if(!built) build(); tree[p+n] = value; p = p+n; for (int i=p; i > 1; i >>= 1) tree[i>>1] = tree[i] + tree[i^1];} typ query(int l, int r){ if(!built) build(); typ res = 0; for (l += n, r += n+1; l < r; l >>= 1, r >>= 1){ if (l&1) res += tree[l++]; if (r&1) res += tree[--r];} return res;}};
//
//int fpow(int x,int n)
//{
//    if(n==1)
//        return x;
//    if(n==0)
//        return 1;
//    if(n%2==0){
//    int y = fpow(x,n/2);
//    return (y*y);
//    }
//    return (x*fpow(x,n-1));
//}
//
//int fpowmod(int x, int y, int p)
//{
//    int res = 1;
//
//    x = x % p;
//
//    while (y > 0)
//    {
//        if (y & 1)
//            res = (res*x) % p;
//
//        y = y>>1;
//        x = (x*x) % p;
//    }
//    return res;
//}
//
//int modInv(int n, int p)
//{
//    return fpowmod(n, p-2, p);
//}
//
//
//void calcFac(int fac[], int n, int p)
//{
//    fac[0] = 1;
//        for (int i=1 ; i<=n; i++)
//            fac[i] = fac[i-1]*i%p;
//}

//int fac[MAX];
//int power(int x, int y, int p)
//{
//    int res = 1;      // Initialize result
//
//    x = x % p;  // Update x if it is more than or
//                // equal to p
//
//    while (y > 0)
//    {
//        // If y is odd, multiply x with result
//        if (y & 1)
//            res = (res*x) % p;
//
//        // y must be even now
//        y = y>>1; // y = y/2
//        x = (x*x) % p;
//    }
//    return res;
//}
  
// Returns n^(-1) mod p
//int modInverse(int n, int p)
//{
//    return power(n, p-2, p);
//}
  
// Returns nCr % p using Fermat's little
// theorem.
//int nCrModPFermat(int n, int r, int p)
//{
//   // Base case
//   if (r==0)
//      return 1;
//
//    // Fill factorial array so that we
//    // can find all factorial of r, n
//    // and n-r
//
//
//
//    return (fac[n]* modInverse(fac[r], p) % p *
//            modInverse(fac[n-r], p) % p) % p;

//}

//bool swa( aa e, aa eb)
//{
//    if(e.a<eb.a)return true;
//    else return false;
//
//}
//bool ss(aa r, aa s)
//{
//    if(r.b<s.b)return true;
//    else return false;
//
//}
void swap(ll* a,ll* b)
{
    ll temp=*a;
    *a=*b;
    *b=temp;
}
ll sol(ll x)
{ll ans=0;
    return ans;
} // One by constructs remaining rows of Pascal
   ll power(ll x,ll y,ll p)
   {
      ll res = 1;      // Initialize result
     
       x = x % p;  // Update x if it is more than or
                   // equal to p
     
       while (y > 0)
       {
           // If y is odd, multiply x with result
           if (y & 1)
               res = (res*x) % p;
     
           // y must be even now
           y = y>>1; // y = y/2
           x = (x*x) % p;
       }
       return res;
   }
     
   // Returns n^(-1) mod p
ll modInverse(ll n, ll p)
   {
       return power(n, p-2, p);
   }
     
   // Returns nCr % p using Fermat's little
   // theorem.
   ll nCrModPFermat(ll n,ll r,ll p)
   {
      // Base case
      if (r==0)
         return 1;
     
       // Fill factorial array so that we
       // can find all factorial of r, n
       // and n-r
      ll fac[n+1];
       fac[0] = 1;
       for (ll i=1 ; i<=n; i++)
           fac[i] = fac[i-1]*i%p;
     
       return (fac[n]* modInverse(fac[r], p) % p *
               modInverse(fac[n-r], p) % p) % p;
   }
int32_t main() {
  
    
    fast;
//    fac[0] = 1;
//    for (int i=1 ; i<=n; i++)
//        fac[i] = fac[i-1]*i%p;

   
//    test{
//
// }
    ll x,y;
    cin>>x>>y;
   
    if((x+y)%3!=0)
    {
        cout<<"0"<<endl;
        return 0;
    }
    else
    {
        ll s=x+y;
        s=s/3;
        ll mmin=s;
        ll mmax=2*s;
        if(x>mmax||x<mmin||y>mmax||y<mmin)
        {
            cout<<"0"<<endl;
            return 0;
        }
        else
        {
            mmin=min(x,y);
            mmax=max(x,y);
            x=mmin-s;
            y=s-x;
            cout<< nCrModPFermat(x+y,x, 1000000007);
           
        
        }
    }
    return 0;
}


Measured memory_bytes: 5504