CodeEff/ECCO huggingface dataset:
# Original solution
from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf,comb
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(eval(input()))
def MAP()   : return list(map(int,input().split()))
def LIST()  : return list(MAP())

def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

mod = 10**9+7 #出力の制限
N = 10**6
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

x, y = MAP()
a = 2*x - y
b = 2*y - x

if a >= 0 and b >= 0 and a % 3 == 0 and b % 3 == 0:
    a //= 3
    b //= 3
    ans = cmb(a+b, a, 10**9+7)
else:
    ans = 0

print(ans)

# Optimized solution
from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf,comb
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(eval(input()))
def MAP()   : return list(map(int,input().split()))
def LIST()  : return list(MAP())

def mycmb(n,r,p):
    r = min(r,n-r)
    if r == 0:
        return 1
    over = reduce(lambda x,y:x*y%p,list(range(n,n-r,-1)))
    under = reduce(lambda x,y:x*y%p,list(range(1,r+1)))
    return (over * pow(under,p-2,p))%p

x, y = MAP()
a = 2*x - y
b = 2*y - x

if a >= 0 and b >= 0 and a % 3 == 0 and b % 3 == 0:
    a //= 3
    b //= 3
    ans = mycmb(a+b, a, 10**9+7)
else:
    ans = 0

print(ans)
# Original solution
class ModComb:
    def __init__(self, MAX, mod=10 ** 9 + 7):
        fac = [1, 1]
        finv = [1, 1]
        inv = [0, 1]
        for i in range(2, MAX):
            fac.append(fac[i - 1] * i % mod)
            inv.append(mod - inv[mod % i] * (mod // i) % mod)
            finv.append(finv[i - 1] * inv[i] % mod)
        self.fac, self.finv, self.mod = fac, finv, mod

    def nCk(self, n, k):
        if n < k or n < 0 or k < 0:
            return 0
        fac, finv, mod = self.fac, self.finv, self.mod
        return fac[n] * (finv[k] * finv[n - k] % mod) % mod

mod = 10 ** 9 + 7
mc = ModComb(3 * 10 ** 6, mod)

X, Y = list(map(int, input().split()))
if (2 * X - Y) % 3 != 0 or (X - 2 * Y) % 3 != 0:
    print((0))
    quit()

b = (2 * X - Y) // 3
a = (-X + 2 * Y) // 3

print((mc.nCk(a + b, a)))

# Optimized solution
def nCk(n, k, mod=10 ** 9 + 7):
    def xgcd(a, b):
        if b == 0:
            return (a, 1, 0)
        g, x, y = xgcd(b, a % b)
        return (g, y, x - (a // b) * y)
    p, q = 1, 1
    for i in range(n - k + 1, n + 1):
        p = (p * i) % mod
    for i in range(2, k + 1):
        q = (q * i) % mod
    return p * (xgcd(q, mod)[1] % mod) % mod


X, Y = list(map(int, input().split()))

b = (2 * X - Y) // 3
a = (-X + 2 * Y) // 3

if (X + Y) % 3 != 0 or a < 0 or b < 0:
    print((0))
else:
    print((nCk(a + b, a)))
# Original solution
def main():
    def nCk(n, k, mod=10 ** 9 + 7):
        def xgcd(a, b):
            if b == 0:
                return (1, 0)
            x, y = xgcd(b, a % b)
            return (y, x - (a // b) * y)
        p, q = 1, 1
        for i in range(n - k + 1, n + 1):
            p = (p * i) % mod
        for i in range(2, k + 1):
            q = (q * i) % mod
        return p * (xgcd(q, mod)[0] % mod) % mod


    X, Y = list(map(int, input().split()))

    b = (2 * X - Y) // 3
    a = (-X + 2 * Y) // 3

    if (X + Y) % 3 != 0 or a < 0 or b < 0:
        print((0))
    else:
        print((nCk(a + b, a)))

main()


# Optimized solution
def nCk(n, k, mod=10 ** 9 + 7):
    if n < k:
        return 0
    k = min(k, n - k)
    numer = 1
    for x in range(n - k + 1, n + 1):
        numer = (numer * x) % mod
    denom = 1
    for x in range(1, k + 1):
        denom = (denom * x) % mod
    return numer * pow(denom, mod - 2, mod) % mod

X, Y = list(map(int, input().split()))

b = (2 * X - Y) // 3
a = (-X + 2 * Y) // 3

if (X + Y) % 3 != 0 or a < 0 or b < 0:
    print((0))
else:
    print((nCk(a + b, a)))
# Original solution
def comb_mod(n,r,m):
    ans = 1
    for i in range(1,r+1):
        ans *= (n-i+1) % m
        ans *= pow(i,m-2,m) % m
        ans = ans % m
    return ans
x,y = list(map(int,input().split()))
m = 10**9+7
n = (x+y)//3
c = 0
if x*0.5 <= y <= 2*x and (x+y)%3 == 0:
    r = x - n
    c = comb_mod(n,r,m)
else:
    ans = 0
print(c)


# Optimized solution
def comb_mod(n,r,m):
    ans = 1
    for i in range(1,r+1):
        ans *= (n-i+1) % m
        ans *= pow(i,m-2,m) % m
        ans = ans % m
    return ans

x,y = list(map(int,input().split()))
m = 10**9+7
if x > 2*y or 2*x < y or (x+y)%3 != 0:
    ans = 0
else:
    n = (x+y)//3
    r = x-n
    ans = comb_mod(n,r,m)
print(ans)
# Original solution
M=10**9+7
x,y=list(map(int,input().split()))
ans=0
if (x+y)%3==0:
  a=(2*y-x)//3
  b=(2*x-y)//3
  if a>=0 and b>=0:
    f1,f2=1,1
    for i in range(a+1,a+b+1):
      f1*=i
      f1%=M
    for i in range(1,b+1):
      f2*=i
      f2%=M
    ans=f1*pow(f2,M-2,M)

print((ans%M))

# Optimized solution
X,Y=list(map(int,input().split()))
if 2*Y<X or 2*X<Y:
  print((0))
  exit()
if not((X%3==0 and Y%3==0) or (X%3==1 and Y%3==2) or (X%3==2 and Y%3==1)):
  print((0))
  exit()
P=10**9+7
A=(2*Y-X)//3
B=(2*X-Y)//3
num = 1
for i in range(A+1, A+B+1):
  num=num*i%P
den = 1
for j in range(1, B+1):
  den = den*j%P
den = pow(den,P-2,P)
print(((num*den)%P))
# Original solution
mod = 10**9 + 7

def nCk(n,k,p):
    global mod
    k = min(k, n-k)
    
    X = 1
    for i in range(k):
        X = X * (n - i) % p
        X = X * pow(i + 1, p - 2, p) % p
    return X

X,Y = list(map(int, input().split()))

ans = 0
if X <= 2*Y and Y <= 2*X and (X + Y) % 3 == 0:
    a = (2*Y-X) // 3
    b = (2*X-Y) // 3
    ans = nCk(a + b, b, mod)
print(ans)

# Optimized solution
X,Y = list(map(int, input().split()))
mod = 10**9 + 7

def nCk(n,k,p):
    fact    = [1,1] + [0]*(n-1)
    inv     = [0,1] + [0]*(n-1)
    factinv = [1,1] + [0]*(n-1)
    
    for i in range(2, n+1):
        fact[i] = i * fact[i-1] % p
        inv[i] = - inv[p % i] * (p // i) % p
        factinv[i] = factinv[i-1] * inv[i] % p
    
    return fact[n] * factinv[k] * factinv[n-k] % p

ans = 0
if (X + Y) % 3 == 0 and X <= 2*Y and Y <= 2*X:
    a = (2*Y - X) // 3
    b = (2*X - Y) // 3
    ans = nCk(a+b, a, mod)
print(ans)
# Original solution
def comb(n, r, p):
    x, y = 1, 1
    for i in range(n, n - r, -1):
        x *= i
        y *= i + r - n
        x %= p
        y %= p
    return pow(y, p - 2, p) * x % p

x, y = list(map(int, input().split()))
n = (x + y) // 3
p = 10 ** 9 + 7
if (x + y) % 3 == 0:
    r = 0
    if x > y:
        x, y = y, x
    while True:
        if 2 * x == y:
            break
        r += 1
        x -= 2
        y -= 1
    print((comb(n, r, p)))
else:
    print((0))

# Optimized solution
def comb(n, r, p):
    x, y = 1, 1
    for i in range(n, n - r, -1):
        x *= i
        y *= i + r - n
        x %= p
        y %= p
    return pow(y, p - 2, p) * x % p

x, y = list(map(int, input().split()))
n = (x + y) // 3
p = 10 ** 9 + 7
if (x + y) % 3 == 0 and max(x, y) <= 2 * min(x, y):
    r = 0
    if x > y:
        x, y = y, x
    a = (2 * x - y) // 3
    r = min(a, n - a)
    print((comb(n, r, p)))
else:
    print((0))
# Original solution
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline

mod = 10**9+7
def comb(n, k):
    c = 1
    for i in range(k):
        c *= n - i
        c %= mod
    d = 1
    for i in range(1, k + 1):
        d *= i
        d %= mod
    return (c * pow(d, mod - 2, mod)) % mod


x,y = list(map(int, input().split()))

if (x + y) % 3 != 0:
    print((0))
    exit()

n = (x + y) // 3
x -= n
y -= n
if x < 0 or y < 0:
    print((0))
    exit()

print((comb(x + y, x)))


# Optimized solution
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline

mod = 10**9+7
def comb(n, k):
    c = 1
    for i in range(k):
        c *= n - i
        c %= mod
    d = 1
    for i in range(1, k + 1):
        d *= i
        d %= mod
    return (c * pow(d, mod - 2, mod)) % mod


x,y = list(map(int, input().split()))

if (x + y) % 3 != 0:
    print((0))
    exit()

# 公式解説解答
# n = (x + y) // 3
# x -= n
# y -= n
# if x < 0 or y < 0:
#     print(0)
#     exit()
# print(comb(x + y, x))

# x = 2a + b
# y = a + 2b
# 連立方程式を解いてa,bを求める
# あとはa,bの同じものを含む順列(a+b)!/a!b!
a = (2 * x - y) // 3
b = (-x + 2 * y) // 3
if a < 0 or b < 0:
    print((0))
    exit()
print((comb((x + y) // 3, a)))
# Original solution
def comb(n, k, mod):
    if k > (n // 2):
        k = n - k
    a = 1
    for i in range(k):
        a *= (n - i)
        a %= mod
    for i in range(k - 1):
        a = (a * pow(k - i, mod - 2, mod)) % mod

    return a

X, Y = list(map(int, input().split()))
ans = 0
mod = 10 ** 9 + 7
if X > Y:
    X, Y = Y, X
##Yのほうが大きいとして考える
if not (X + Y) % 3 == 0 or Y > 2 * X:
    ans = 0
else:
    n = (X + Y) // 3
    d = Y - X
    a = 2*n - X
    ans = comb(n, a, mod)
print(ans)


# Optimized solution
def comb(n, k, mod):
    if k > (n // 2):
        k = n - k
    a = 1
    for i in range(k):
        a = (a * (n - i)) % mod
    b = 1
    for i in range(k - 1):
        b = (b *(k - i)) % mod
    a = (a * pow(b, mod - 2, mod)) % mod
    return a


X, Y = list(map(int, input().split()))
ans = 0
mod = 10 ** 9 + 7
if X > Y:
    X, Y = Y, X
##Yのほうが大きいとして考える
if not (X + Y) % 3 == 0 or Y > 2 * X:
    ans = 0
else:
    n = (X + Y) // 3
    d = Y - X
    a = 2*n - X
    ans = comb(n, a, mod)
print(ans)
# Original solution
X,Y=list(map(int,input().split()))
mod=10**9+7
if (X+Y)%3!=0:
    print((0));exit()
if X*2<Y or Y*2<X:
    print((0));exit()
t=(X+Y)//3
f=[1]
for i in range(1,t+100):
    f.append(f[-1]*i%mod)
def comb(a,b,m):
    return f[a]*pow(f[b],m-2,m)*pow(f[a-b],m-2,m)%m
print((comb(t,X-t,mod)))


# Optimized solution
M=10**9+7
x,y=list(map(int,input().split()))
ans=0
if (x+y)%3==0:
  a=(2*y-x)//3
  b=(2*x-y)//3
  if a>=0 and b>=0:
    f1,f2=1,1
    for i in range(a+1,a+b+1):
      f1*=i
      f1%=M
    for i in range(1,b+1):
      f2*=i
      f2%=M
    ans=f1*pow(f2,M-2,M)

print((ans%M))
# Original solution
fac = [0] * 700000
finv = [0] * 700000
inv = [0] * 700000
mod = 1000000007

fac[0] = fac[1] = 1
finv[0] = finv[1] = 1
inv[1] = 1
for i in range(2, 700000):
    fac[i] = fac[i - 1] * i % mod
    inv[i] = mod - inv[mod % i] * (mod // i) % mod
    finv[i] = finv[i - 1] * inv[i] % mod

x, y = list(map(int, input().split()))

if (x + y) % 3 == 0:
    k = (2 * x - y) // 3
    l = (2 * y - x) // 3
    if k >= 0 and l >= 0:
        print((fac[k + l] * (finv[k] * finv[l] % mod) % mod))
    else:
        print((0))
else:
    print((0))


# Optimized solution
mod = 10 ** 9 + 7
ans = 0

x, y = list(map(int, input().split()))

if (x + y) % 3 == 0:
    k = (2 * x - y) // 3
    l = (2 * y - x) // 3
    if k >= 0 and l >= 0:
        fac = [1] * (k + l + 1)
        for i in range(2, k + l + 1):
            fac[i] = fac[i - 1] * i % mod
        ans = fac[k + l] * (pow(fac[k], mod - 2, mod) * pow(fac[l], mod - 2, mod) % mod) % mod

print(ans)
# Original solution
x,y = list(map(int,input().split()))
ans = 0
mod = 10**9+7

if (x+y)%3 == 0:
    m = (2*y-x)//3
    n = (2*x-y)//3
    if m >= 0 and n >= 0:
        fac = [1]*(m+n+1)
        for i in range(2,m+n+1): 
            fac[i] = fac[i-1]*i % mod
        ans = fac[m+n]*(pow(fac[m],mod-2,mod)*pow(fac[n],mod-2,mod)%mod)%mod

print(ans)

# Optimized solution
def comb(n,k,mod):
    x = y = 1
    for i in range(min(k,n-k)):
        x = x*(n-i)%mod
        y = y*(i+1)%mod
    return x * pow(y, mod-2, mod) % mod

x,y = list(map(int,input().split()))
ans = 0
mod = 10**9+7
if (x+y)%3 == 0:
    a = (-x+2*y)//3
    b = (2*x-y)//3
    if a >= 0 and b >= 0: ans = comb(a+b,a,mod)
print(ans)
# Original solution
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

mod = 10**9+7 #出力の制限
N = 10**6
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )



x, y = list(map(int,input().split()))

a =  (  2 * x -  y )
b =  ( - x + 2 * y )

if a % 3 != 0 or b % 3 != 0:
    print((0))
    exit(0)

a = int(a/3)
b = int(b/3)

# print(a, b)

mod = 10**9 + 7 

ans = cmb((a+b),a,mod)

print(ans)

# Optimized solution
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

mod = 10**9+7 #出力の制限
N = 10**6
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

x, y = list(map(int,input().split()))

a =    2 * x -  y 
b =   - x + 2 * y 

ans = 0
if a % 3 == 0 and b % 3 == 0:
    a = a//3
    b = b//3
    ans = cmb(a+b, a, mod)
print(ans)
# Original solution
x,y = list(map(int,input().split()))

class ModComb:
    def __init__(self, MAX, mod=10 ** 9 + 7):
        fac = [1, 1]
        finv = [1, 1]
        inv = [0, 1]
        for i in range(2, MAX):
            fac.append(fac[i - 1] * i % mod)
            inv.append(mod - inv[mod % i] * (mod // i) % mod)
            finv.append(finv[i - 1] * inv[i] % mod)
        self.fac, self.finv, self.mod = fac, finv, mod
 
    def nCk(self, n, k):
        if n < k or n < 0 or k < 0:
            return 0
        fac, finv, mod = self.fac, self.finv, self.mod
        return fac[n] * (finv[k] * finv[n - k] % mod) % mod

if (x+y)%3!=0:
    print((0))
else:
    a = (2*x - y) // 3
    b = (2*y - x) // 3

    mod = 10 ** 9 + 7
    mc = ModComb(1000000, mod=mod) 

    print((mc.nCk(a + b, a) % mod))

# Optimized solution
X,Y = list(map(int,input().split()))

n = (-X+2*Y)//3
m = (2*X-Y)//3

mod = 10**9+7 #出力の制限
N = max(n+m,n)
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )
    
if (-X+2*Y)%3 == 0 and (2*X-Y)%3 == 0:
    print((cmb(n+m,n,mod)))
else:
    print((0))
# Original solution
X,Y = list(map(int,input().split()))

n = (-X+2*Y)//3
m = (2*X-Y)//3

mod = 10**9+7 #出力の制限
N = max(n+m,n)
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )
    
if (-X+2*Y)%3 == 0 and (2*X-Y)%3 == 0:
    print((cmb(n+m,n,mod)))
else:
    print((0))

# Optimized solution
X,Y = list(map(int,input().split()))

n = (-X+2*Y)//3
m = (2*X-Y)//3
MOD = 10**9+7
    
def comb(n,r,MOD):
    x = n+1
    y = min(r,n-r)
    
    numer = 1
    denom = 1
    
    for i in range(1,r+1):
        numer = numer*(x-i)%MOD
        denom = denom*(i)%MOD
    
    return numer * pow(denom,MOD-2,MOD) % MOD
  
import sys

if n < 0 or m < 0:
    print((0))
    sys.exit()
if (X+Y)%3 != 0:
    print((0))
    sys.exit()
    
print((comb(n+m,n,MOD)))
# Original solution
def cmb(n, r, mod):
    if (r < 0 or r > n):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod
 
mod = 10**9+7  
nums = 10**6 # 制約に合わせよう
g1, g2, inverse = [1, 1] , [1, 1], [0, 1]
 
for num in range(2, nums + 1):
    g1.append((g1[-1] * num) % mod)
    inverse.append((-inverse[mod % num] * (mod//num)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)
    
x, y = list(map(int, input().split()))
if (x+y)%3 or 2*x<y or 2*y<x:
    print((0))
else:
    print((cmb((x+y)//3,(2*x-y)//3, mod)))

# Optimized solution
def nCr(n, r, mod):
    x, y = 1, 1
    for r_ in range(1, r+1):
        x = x*(n+1-r_)%mod
        y = y*r_%mod
    return x*pow(y, mod-2, mod)%mod

x, y = list(map(int, input().split()))
mod = 10**9+7
if (x+y)%3 or 2*x<y or 2*y<x:
    print((0))
else:
    print((nCr((x+y)//3,(2*x-y)//3, mod)))
# Original solution
MAX = 1000010
finv = [0] * MAX
inv = [0] * MAX
def COMinit():
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MAX):
        inv[i] = MOD - inv[MOD%i] * (MOD//i) % MOD
        finv[i] = finv[i-1] * inv[i] % MOD

def COM(n, k):
    res = 1
    for i in range(k):
        res = res * (n-i) % MOD
    return res * finv[k] % MOD

MOD = 10**9+7
x, y = list(map(int, input().split()))
s, t = (-x+2*y)/3, (2*x-y)/3

if s < 0 or t < 0:
    ans = 0
elif not (s.is_integer() and t.is_integer()):
    ans = 0
else:
    s, t = int(s), int(t)
    COMinit()
    ans = COM((s+t), s)

print(ans)

# Optimized solution
MOD = 10**9+7
MAX = 1000010
finv = [0] * MAX
inv = [0] * MAX
def COMinit():
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MAX):
        inv[i] = MOD - inv[MOD%i] * (MOD//i) % MOD
        finv[i] = finv[i-1] * inv[i] % MOD
def COM(n, k):
    res = 1
    for i in range(k):
        res = res * (n-i) % MOD
    return res * finv[k] % MOD

x, y = list(map(int, input().split()))
if (x+y)%3 != 0:
    ans = 0
else:
    s, t = (-x+2*y)//3, (2*x-y)//3
    if s < 0 or t < 0:
        ans = 0
    else:
        COMinit()
        ans = COM((s+t), s)

print(ans)
# Original solution
MOD = 10**9+7
X, Y = sorted(list(map(int, input().split())))

if (X+Y)%3 != 0:
    print((0))
    exit()

if (2*X < Y):
    print((0))
    exit()

W = X - ((X+Y)//3)
H = Y - ((X+Y)//3)

mx = 10**6
fact = [1] * (mx+1) # 階乗を格納するリスト
def inv(n): # MODを法とした逆元
    return pow(n, MOD-2, MOD)
for i in range(mx):
    fact[i+1] = fact[i] * (i+1) % MOD # 階乗を計算
ans = (fact[W+H] * inv(fact[W]) * inv(fact[H])) % MOD # comb(W+H,W) = (W+H)!/(W!H!)
print (ans)

# Optimized solution
MOD = 10**9+7
X, Y = list(map(int, input().split()))
if (X > Y):
    X, Y = Y, X

if (X+Y)%3 != 0:
    print((0))
    exit()

if (2*X < Y):
    print((0))
    exit()

W = X - ((X+Y)//3)
H = Y - ((X+Y)//3)

mx = 10**6
fact = [1] * (mx+1) # 階乗を格納するリスト
def inv(n): # MODを法とした逆元
    return pow(n, MOD-2, MOD)
for i in range(mx):
    fact[i+1] = fact[i] * (i+1) % MOD # 階乗を計算
ans = (fact[W+H] * inv(fact[W]) * inv(fact[H])) % MOD # comb(W+H,W) = (W+H)!/(W!H!)
print (ans)
# Original solution
def num_combinations_mod(n, r, mod, num_max=10**6):
    # if this functions is called twice or more, init process should be placed before calling this function to
    # save time.
    if r > n:
        return 0
    elif r == n:
        return 1
    elif r < 0 or n < 0:
        return 0
    f_mod, f_mod_inv = num_combinations_mod_init(num_max, mod)
    return f_mod[n] * (f_mod_inv[r] * f_mod_inv[n-r] % mod) % mod


def num_combinations_mod_init(num_max, mod):
    factorials_mod = dict()
    factorials_mod_inv = dict()
    factorials_mod[0] = 1
    factorials_mod[1] = 1
    factorials_mod_inv[0] = 1
    factorials_mod_inv[1] = 1
    mod_inv = dict()
    mod_inv[1] = 1
    for i in range(2, num_max):
        factorials_mod[i] = factorials_mod[i - 1] * i % mod
        mod_inv[i] = mod - mod_inv[mod % i] * (mod // i) % mod
        factorials_mod_inv[i] = factorials_mod_inv[i - 1] * mod_inv[i] % mod
    return factorials_mod, factorials_mod_inv


def get(num1, num2):
    if num1 > num2:
        num = num2
    else:
        num = num1
    return num_combinations_mod(num1+num2, num, 10**9+7)


def main(X, Y):
    if (X + Y) % 3 != 0:
        return 0

    total = (X + Y) // 3
    n_moveB = (2 * X - Y) // 3
    n_moveA = total - n_moveB
    answer = get(n_moveA, n_moveB)

    return answer


X, Y = list(map(int, input().split(" ")))
print((main(X, Y)))

# Optimized solution
def num_combinations_mod2(n, r, mod=10 ** 9 + 7):
    # mod must be a prime.
    # nCr = (n! / (n-r)!) * (r!)^-1
    # a = n! / (n-r)!
    # b = (r!)^-1
    if r > n:
        return 0
    if r < 0 or n < 0:
        return 0
    r = min(r, n - r)
    a = 1
    b = 1
    for i in range(1, r + 1):
        a = a * (n + 1 - i) % mod
        b = b * i % mod
    return a * pow(b, mod - 2, mod) % mod


def main(x, y):
    if (x + y) % 3 != 0:
        return 0

    total = (x + y) // 3
    n = (2 * x - y) // 3
    m = total - n
    answer = num_combinations_mod2(m+n, n, 10**9+7)
    return answer


X, Y = list(map(int, input().split(" ")))
print((main(X, Y)))
# Original solution
def nCr(n,r):
  dividend,divisor = 1,1
  for i in range(r):
    dividend *= n-i
    divisor *= 1+i
    dividend %= MOD
    divisor %= MOD

  return (dividend * pow(divisor, MOD-2, MOD)) % MOD

X,Y = list(map(int,input().split()))
INF = 10**15
MOD = 10**9+7

if (X+Y)%3!=0:
  print((0))
  exit()

n = (-X + 2*Y) // 3
m = (2*X - Y) // 3

if n<0 or m<0:
  print((0))
  exit()

print((nCr(n+m, n)))

# Optimized solution
def nCr(n,r):
  dividend = 1
  divisor = 1
  MOD = 10**9+7
  d1 = n
  for i in range(1,r+1):
    dividend *= d1
    divisor *= i
    d1 -= 1
    dividend %= MOD
    divisor %= MOD

  return (dividend * pow(divisor, MOD-2, MOD)) % MOD

X,Y = list(map(int,input().split()))

if (X+Y) % 3 != 0:
  print((0))
  exit()

n = (-X+2*Y) // 3
m = (2*X-Y) // 3

if n<0 or m<0:
  print((0))
else:
  print((nCr(n+m, n)))
# Original solution
MOD = 10 ** 9 + 7


def prepare(n):
    global MOD
    modFacts = [0] * (n + 1)
    modFacts[0] = 1
    for i in range(n):
        modFacts[i + 1] = (modFacts[i] * (i + 1)) % MOD

    invs = [1] * (n + 1)
    invs[n] = pow(modFacts[n], MOD - 2, MOD)
    for i in range(n, 1, -1):
        invs[i - 1] = (invs[i] * i) % MOD

    return modFacts, invs


dest = list(map(int, input().split()))

p = (2, 1)
q = (1, 2)
num_p = 0
num_q = 0

while dest[0] and dest[1]:
    if dest[0] >= dest[1]:
        dest[0] -= p[0]
        dest[1] -= p[1]
        num_p += 1
    else:
        dest[0] -= q[0]
        dest[1] -= q[1]
        num_q += 1

modFacts, invs = prepare(num_p + num_q)

if dest == [0, 0]:
    n = num_p + num_q
    r = min(num_p, num_q)
    ans = (modFacts[n] * invs[n - r] * invs[r]) % MOD
else:
    ans = 0

print(ans)


# Optimized solution
MOD = 10 ** 9 + 7


def prepare(n):
    global MOD
    modFacts = [0] * (n + 1)
    modFacts[0] = 1
    for i in range(n):
        modFacts[i + 1] = (modFacts[i] * (i + 1)) % MOD

    invs = [1] * (n + 1)
    invs[n] = pow(modFacts[n], MOD - 2, MOD)
    for i in range(n, 1, -1):
        invs[i - 1] = (invs[i] * i) % MOD

    return modFacts, invs


X, Y = list(map(int, input().split()))
if (X + Y) % 3 == 0 and 2 * Y - X >= 0 and 2 * X - Y >= 0:
    p = (2 * Y - X) // 3
    q = (2 * X - Y) // 3
    n = p + q
    r = min(p, q)
    modFacts, invs = prepare(n)
    ans = (modFacts[n] * invs[n - r] * invs[r]) % MOD
else:
    ans = 0

print(ans)