CodeEff/ECCO huggingface dataset:
# 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()))


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

count = (x+y)//3
x -= count
y -= count

ans = cmb(x+y, min(x, y), mod)
print(ans)

# Optimized solution
def nCr(n,r,mod = 10**9+7):
    r = min(n-r,r)
    numer = denom = 1
    for i in range(1,r+1):
        numer = numer * (n+1-i) %mod
        denom = denom * i % mod
    return numer * pow(denom,mod-2,mod) %mod


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


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

count = (x+y)//3
x -= count
y -= count

if x<0 or y<0:
    print((0))
    exit()

ans = nCr(x+y, x)
print(ans)
# Original solution
#lにa回、rにb回進む
x,y = list(map(int,input().split()))
#x = a +2b
#y = 2a+b
#x+y = 3a+3b
#a+b = (x+y)/3
#b=x-a+b
b = x-(x+y)/3
a = (x-2*b)
ans = 0
#print("a:{} b:{}".format(a,b))
if a<0 or b<0 or b-int(b)>0.00001 or a-int(a)>0.00001:
  print(ans)
  exit()
 
MAX = 1000000;
MOD = 1000000007;
 
fac = [0 for i in range(MAX)]
finv = [0 for i in range(MAX)]
inv = [0 for i in range(MAX)]
 
#テーブルを作る前処理
def COMinit():
    fac[0],fac[1] = 1,1
    finv[0],finv[1] = 1,1
    inv[1] = 1
    for i in range(2,MAX):
      fac[i] = fac[i - 1] * i % MOD
      inv[i] = MOD - inv[MOD%i] * (MOD // i) % MOD
      finv[i] = finv[i - 1] * inv[i] % MOD
 
#二項係数計算
def COM(n,k):
  if n < k:
    return 0
  if n < 0 or k < 0:
    return 0
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD
 
COMinit()
print((COM(int(a+b),int(a))))

# Optimized solution
#lにa回、rにb回進む
x,y = list(map(int,input().split()))
#x = a +2b
#y = 2a+b
#x+y = 3a+3b
#a+b = (x+y)/3
#b=x-a+b
b = x-(x+y)/3
a = (x-2*b)
ans = 0
#print("a:{} b:{}".format(a,b))
if a<0 or b<0 or b-int(b)>0.00001 or a-int(a)>0.00001:
  print(ans)
  exit()

MAX = int(a+b)+1
MOD = 1000000007

fac = [0 for i in range(MAX)]
finv = [0 for i in range(MAX)]
inv = [0 for i in range(MAX)]

#テーブルを作る前処理
def COMinit():
    fac[0],fac[1] = 1,1
    finv[0],finv[1] = 1,1
    inv[1] = 1
    for i in range(2,MAX):
      fac[i] = fac[i - 1] * i % MOD
      inv[i] = MOD - inv[MOD%i] * (MOD // i) % MOD
      finv[i] = finv[i - 1] * inv[i] % MOD

#二項係数計算
def COM(n,k):
  if n < k:
    return 0
  if n < 0 or k < 0:
    return 0
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD

COMinit()
print((COM(int(a+b),int(a))))
# Original solution
from sys import stdin, setrecursionlimit


def initialize_cmb(m, mod=10 ** 9 + 7):
    fac = [1]
    finv = [1]
    inv = [0] * (m + 1)
    if m >= 1:
        fac.append(1)
        finv.append(1)
        inv[1] = 1
        pre_fac = 1
        pre_finv = 1
        for i in range(2, m + 1):
            pre_fac = pre_fac * i % mod
            fac.append(pre_fac)
            inv[i] = mod - inv[mod % i] * (mod // i) % mod
            pre_finv = pre_finv * inv[i] % mod
            finv.append(pre_finv)
    return fac, finv


def cmb(n, k, fac, finv, mod=10 ** 9 + 7):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod


def main():
    mod = 10 ** 9 + 7
    input = stdin.buffer.readline
    x, y = list(map(int, input().split()))

    if (x + y) % 3 != 0 or 2 * x < y or 2 * y < x:
        print((0))
    else:
        fac, finv = initialize_cmb((x + y) // 3, mod)

        x_min = (x + y) // 3

        print((cmb((x + y) // 3, x - x_min, fac, finv, mod)))


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()


# Optimized solution
from sys import stdin, setrecursionlimit


def cmb(n, r, mod=10 ** 9 + 7):
    r = min(r, n - r)
    x = y = 1
    for i in range(r):
        x *= n - i
        x %= mod
        y *= i + 1
        y %= mod
    return x * pow(y, mod - 2, mod) % mod


def main():
    mod = 10 ** 9 + 7
    input = stdin.buffer.readline
    x, y = list(map(int, input().split()))

    if (x + y) % 3 != 0 or 2 * x < y or 2 * y < x:
        print((0))
    else:

        x_min = (x + y) // 3

        print((cmb((x + y) // 3, x - x_min, mod)))


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()
# Original solution
X, Y = list(map(int, input().split()))
mod = 10**9 + 7

if (X + Y) % 3 != 0 or X > 2*Y or Y > 2*X:
    print((0))
else:
    n2x = (2*X - Y) // 3
    n1x = (2*Y - X) // 3
    n = n2x + n1x

    # nCn2xを求める
    def combs(n,n2x):
        invs = [1] * (n+1)
        nfac = 1
        for i in range(1, n+1):
            nfac = nfac * i % mod
            invs[i] = pow(nfac, mod-2, mod)
        return nfac * invs[n2x] * invs[n-n2x] % mod

    print((combs(n, n2x)))


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

if (X + Y) % 3 != 0 or X > 2*Y or Y > 2*X:
    print((0))
else:
    n2x = (2*X - Y) // 3
    n1x = (2*Y - X) // 3
    n = n2x + n1x

    # nCn2xを求める
    def combs(n,n2x,mod):
        facs = [1] * (n+1)
        # invs = [1] * (n+1)
        nfac = 1
        for i in range(1, n+1):
            nfac = nfac * i % mod
            facs[i] = nfac
            # invs[i] = pow(nfac, mod-2, mod)
        return nfac * (pow(facs[n2x], mod-2, mod) * pow(facs[n-n2x], mod-2, mod)) % mod

    print((combs(n, n2x, mod)))
# Original solution
X,Y=list(map(int,input().split()))
def cmb(n, r, p):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % p

p = 10 ** 9 + 7
N = 10 ** 6
fact = [1, 1]
factinv = [1, 1]
inv = [0, 1]
 
for i in range(2, N + 1):
    fact.append((fact[-1] * i) % p)
    inv.append((-inv[p % i] * (p // i)) % p)
    factinv.append((factinv[-1] * inv[-1]) % p)

if (X+Y)%3:
    ans=0
else:
    N=(X+Y)//3
    if N<=X<=2*N and N<=Y<=2*N:
        ans=cmb(N,X-N,p)
    else:
        ans=0

print(ans)

# Optimized solution
def com(n,r,m):
 f=[1,1]
 for i in range(2,n+1):
  f.append(f[i-1]*i%m)
 return f[n]*pow(f[r]*f[n-r]%m,m-2,m)%m
 
mod=10**9+7
x,y=list(map(int,input().split()))
z=(x+y)//3
if (x+y)%3 or abs(x-y)>z:
 ans=0
else:
    ans=com(z,x-z,mod)
print(ans)
# Original solution
import sys
input = sys.stdin.readline

def egcd(a, b):
    if a == 0:
        return b, 0, 1
    else:
        g, y, x = egcd(b % a, a)
        return g, x - (b // a) * y, y

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def combination(n, r, mod=10**9+7):
    r = min(r, n-r)
    res = 1
    for i in range(r):
        res = res * (n - i) * modinv(i+1, mod) % mod
    return res

X, Y = [int(x) for x in input().strip().split()]
p = (X, 2 * X)
n1 = X
n2 = 0
f = True
while p != (X, Y):
    n1 -= 2
    n2 += 1
    p = (n1 + 2 * n2, 2 * n1 + n2)
    if p[1] <= 0:
        f = False
        break

if n1 < 0 or n2 < 0:
    print((0))
else:
    print((combination(n1 + n2, n1) % (10 ** 9 + 7)))

# Optimized solution
import sys
input = sys.stdin.readline

def egcd(a, b):
    if a == 0:
        return b, 0, 1
    else:
        g, y, x = egcd(b % a, a)
        return g, x - (b // a) * y, y

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def combination(n, r, mod=10**9+7):
    r = min(r, n-r)
    res = 1
    for i in range(r):
        res = res * (n - i) * modinv(i+1, mod) % mod
    return res

X, Y = [int(x) for x in input().strip().split()]
p = (X, 2 * X)
n1 = X
n2 = 0
f = True
while p != (X, Y):
    n1 -= 2
    n2 += 1
    p = (n1 + 2 * n2, 2 * n1 + n2)
    if p[1] <= 0:
        f = False
        break

if n1 < 0 or n2 < 0:
    print((0))
else:
    print((combination(n1 + n2, n1)))
# 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

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

if (2*y-x)%3==0:
    a=(2*y-x)//3
    b=(2*x-y)//3
    mod = 10**9+7 #出力の制限
    N = a+b
    r=min(a,b)
    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 )

    print((cmb(N,r,mod)))
else:
    print((0))

# Optimized solution
def cmb(n,r,mod):
    r=min(r,n-r)
    if r==0:
        return 1
    elif r<0:
        return 0
    else:
        X=1
        Y=1
        for i in range(r):
            X*=n-i
            X%=mod
            Y*=i+1
            Y%=mod
        Y=pow(Y,mod-2,mod)
        X*=Y
        return X%mod

if __name__ == "__main__":
    X,Y=list(map(int,input().split()))
    if (2*Y-X)%3!=0 or (2*X-Y)%3!=0:
        print((0))
    else:
        xd=(2*X-Y)//3
        yd=(2*Y-X)//3
        print((cmb(xd+yd,yd,10**9+7)))
# Original solution
x, y = list(map(int, input().split()))
if (x + y)%3 != 0:
    print((0))
else:
    k = (x + y)//3
    if k <= x <= 2*k:
        MOD = 10**9 + 7
        fac = [0]*(k + 1)
        finv = [0]*(k + 1)
        inv = [0]*(k + 1)
        fac[0] = 1; fac[1] = 1; finv[0] =1; finv[1] = 1; inv[1] = 1
        for i in range(2, k + 1):
            fac[i] = fac[i - 1] * i % MOD
            inv[i] = MOD - inv[MOD%i] * (MOD // i) % MOD
            finv[i] = finv[i - 1] * inv[i] % MOD
        
        i = x - k
        print((fac[k] * (finv[i] * finv[k - i] % MOD) % MOD))
    else:
        print((0))

# Optimized solution
# 拡張ユークリッド互除法を用いて逆元を求める
def modinv(a, m):
    b = m; x0 = 1; x1 = 0
    while b:
        q = a//b
        a, b = b, a%b
        x0, x1 = x1, x0 - q*x1
    return x0%m 


x, y = list(map(int, input().split()))
if (x + y)%3 != 0:
    print((0))
else:
    k = (x + y)//3
    if k <= x <= 2*k:
        i = min(x - k, 2*k - x)
        # 結局 コンビネーションkCiに帰着
        MOD = 10**9 + 7
        # まず階乗のmodを求める
        fac = [1]*(k + 1)
        for j in range(2, k + 1):
            fac[j] = fac[j - 1]*j%MOD
        # 次に階乗の逆元を求める
        finv = [0]*(k + 1)
        #finv[k] = pow(fac[k], MOD - 2, MOD) # fac[k]の逆元, フェルマーの小定理
        finv[k] = modinv(fac[k], MOD)
        for j in range(k, i, - 1):
            finv[j - 1] = finv[j]*j%MOD

        print((fac[k] * (finv[i] * finv[k - i] % MOD) % MOD))
    else:
        print((0))
# Original solution
# D - Knight

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

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

# https://qiita.com/derodero24/items/91b6468e66923a87f39f
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] % mod * 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 )

if a%1 != 0 or b%1 != 0:
    print((0))
else:
    ans = cmb(int(a+b), int(min(a,b)), mod)
    print(ans)


# Optimized solution
# D - Knight

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

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

# https://qiita.com/derodero24/items/91b6468e66923a87f39f
# を一部修正
def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] % mod * g2[n-r] % mod

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

if a%1 != 0 or b%1 != 0:
    print((0))
else:
    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 )

    ans = cmb(int(a+b), int(min(a,b)), mod)
    print(ans)
# Original solution
mod = 10**9+7

def pow(n, x):
  if x == 0:
    return 1
  elif x % 2 == 0:
    return pow(n * n % mod, x // 2)
  else:
    return n * pow(n * n % mod, x // 2) % mod

def comb(n, r):
  p, q = 1, 1
  for i in range(r):
    p = p * (n-i) % mod
    q = q * (i+1) % mod
  return p * pow(q, mod-2) % mod

x, y = list(map(int, input().split()))
m = abs(x - y)
n = (x + y) // 3
if (x + y) % 3 == 0 and n >= m:
  print((comb(n, (n + m) // 2)))
else:
  print((0))

# Optimized solution
mod = 10**9+7

def comb(n, r):
  p, q = 1, 1
  for i in range(r):
    p = p * (n-i) % mod
    q = q * (i+1) % mod
  return p * pow(q, mod-2, mod) % mod

x, y = list(map(int, input().split()))
m = abs(x - y)
n = (x + y) // 3
if (x + y) % 3 == 0 and n >= m:
  print((comb(n, (n - m) // 2)))
else:
  print((0))
# Original solution
X,Y=list(map(int,input().split()))

import sys
if (2*Y-X)%3!=0 or (2*X-Y)%3!=0:
  print((0))
  sys.exit()
if (2*Y-X)<0 or (2*X-Y)<0:
  print((0))
  sys.exit()
x=(2*Y-X)//3
y=(2*X-Y)//3
#(x+y)Cxを求める
fac=[0 for i in range(x+y+1)]
inv=[0 for i in range(x+y+1)]
finv=[0 for i in range(x+y+1)]
#初期条件
p=1000000007
fac[0]=fac[1]=1
inv[1]=1
finv[0]=finv[1]=1
#テーブルの作成
for i in range(2,x+y+1):
  fac[i]=fac[i-1]*i%p
  #p=(p//a)*a+(p%a) a^(-1)=-(p//a)*(p%a)^(-1)
  inv[i]=(-(p//i)*inv[p%i])%p
  finv[i]=finv[i-1]*inv[i]%p
#求める

print(((fac[x+y]*finv[x]%p)*finv[y]%p))




# Optimized solution
#(i,j)→（i+1,j+2）をx回、(i,j)→（i+2,j+1）がy回あるとすると
#x=(2Y-X)//3,y=(2X-Y)//3、となる
#これが整数or非負なら(x+y)Cxを求めればいい

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

  
#それ以外なら存在する
x=(2*Y-X)//3
y=(2*X-Y)//3
#(x+y)Cxを求める

fac=[0 for i in range(x+y+1)]
inv=[0 for i in range(x+y+1)]
finv=[0 for i in range(x+y+1)]
#初期条件
fac[0]=fac[1]=1
inv[1]=1
finv[0]=finv[1]=1
p=1000000007
for i in range(2,x+y+1):
  fac[i]=(fac[i-1]*i)%p
  #p=(p//a)*a+(p%a) pの世界で　a^(-1)=-(p//a)*inv[p%a]
  inv[i]=(-(p//i)*inv[p%i])%p
  finv[i]=(finv[i-1]*inv[i])%p

print(((fac[x+y]*finv[x]%p)*finv[y]%p))
# Original solution
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()

def modfact(n):
    fact=[1]*(n+1)
    invfact=[1]*(n+1)
    for i in range(1,n+1):
        fact[i]=i*fact[i-1]%MOD
    invfact[n]=pow(fact[n],MOD-2,MOD)
    for i in range(n-1,-1,-1):
        invfact[i]=invfact[i+1]*(i+1)%MOD
    return fact,invfact

def resolve():
    x,y=list(map(int,input().split()))
    if((x+y)%3):
        print((0))
        return

    z=(x+y)//3
    if(x-z<0 or y-z<0):
        print((0))
        return
    
    fact,invfact=modfact(z)
    print((fact[z]*invfact[x-z]%MOD*invfact[y-z]%MOD))
resolve()

# Optimized solution
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()

class modfact(object):
    def __init__(self,n):
        fact=[1]*(n+1)
        invfact=[1]*(n+1)
        for i in range(1,n+1):
            fact[i]=i*fact[i-1]%MOD
        invfact[n]=pow(fact[n],MOD-2,MOD)
        for i in range(n-1,-1,-1):
            invfact[i]=invfact[i+1]*(i+1)%MOD
        self.__fact=fact
        self.__invfact=invfact

    def fact(self,n):
        return self.__fact[n]

    def invfact(self,n):
        return self.__invfact[n]

    def comb(self,n,k):
        if(k<0 or n-k<0): return 0
        return (self.fact(n)*self.invfact(k)*self.invfact(n-k))%MOD

def resolve():
    x,y=list(map(int,input().split()))
    if((x+y)%3):
        print((0))
        return
    z=(x+y)//3
    mf=modfact(z)
    print((mf.comb(z,x-z)))
resolve()
# Original solution
[x,y]=list(map(int,input().split()))
if ((x%3)+(y%3))%3!=0:
	print((0))
else:
	n=int((x+y)/3)
	r=y-n
	if r<0 or r>n:
		print((0))
	else:
		if r>n-r:
			r=n-r
		mod=1000000007
		kaijo=[1]
		for i in range(1,n+1):
			kaijo.append(kaijo[-1]*i%mod) #これで、kaijo[i]=i!となる。
		gyakugen=[pow(kaijo[n-r],mod-2,mod)]
		for i in reversed(list(range(1,n-r+1))):
			gyakugen.append(gyakugen[-1]*i%mod) #これで、gyakugen[i]=n-r-iの逆元となる
		kotae=kaijo[n]*gyakugen[0]*gyakugen[n-2*r]%mod

		print(kotae)

# Optimized solution
[x,y]=list(map(int,input().split()))

#nCrのmodを求める
def nCrmod(n,r,mod):
	if r<0 or r>n:
		ans=0
	else:
		if r>n-r:
			r=n-r
		kaijo=[1] #階乗リスト作成
		for i in range(1,n+1):
			kaijo.append(kaijo[-1]*i%mod) #これで、kaijo[i]≡i!となる。
		gyakugen=[pow(kaijo[n-r],mod-2,mod)] #逆限リスト作成
		for i in reversed(list(range(1,n-r+1))):
			gyakugen.append(gyakugen[-1]*i%mod) #これで、gyakugen[i]=n-r-iの逆元 となる。
		ans=kaijo[n]*gyakugen[0]*gyakugen[n-2*r]%mod
	return(ans)


if ((x%3)+(y%3))%3!=0:
	print((0))
else:
	n=int((x+y)/3)
	r=y-n
	mod=1000000007
	print((nCrmod(n,r,mod)))
# Original solution
X,Y = list(map(int, input().split()))

class Combination:
    """
    O(n)の前計算を1回行うことで，O(1)でnCr mod mを求められる
    n_max = 10**6のとき前処理は約950ms (PyPyなら約340ms, 10**7で約1800ms)
    使用例：
    comb = Combination(1000000)
    print(comb(5, 3))  # 10
    """
    def __init__(self, n_max, mod=10**9+7):
        self.mod = mod
        self.modinv = self.make_modinv_list(n_max)
        self.fac, self.facinv = self.make_factorial_list(n_max)

    def __call__(self, n, r):
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def make_factorial_list(self, n):
        # 階乗のリストと階乗のmod逆元のリストを返す O(n)
        # self.make_modinv_list()が先に実行されている必要がある
        fac = [1]
        facinv = [1]
        for i in range(1, n+1):
            fac.append(fac[i-1] * i % self.mod)
            facinv.append(facinv[i-1] * self.modinv[i] % self.mod)
        return fac, facinv

    def make_modinv_list(self, n):
        # 0からnまでのmod逆元のリストを返す O(n)
        modinv = [0] * (n+1)
        modinv[1] = 1
        for i in range(2, n+1):
            modinv[i] = self.mod - self.mod//i * modinv[self.mod%i] % self.mod
        return modinv
      
if (X+Y) % 3 > 0:
  print((0))
  exit(0)
  
K = (X+Y)//3

if X < K or Y < K:
  print((0))
  exit(0)

comb = Combination(int(1e6+10))
print((comb(K, X-K)))

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

class Combination:
    """
    O(n)の前計算を1回行うことで，O(1)でnCr mod mを求められる
    n_max = 10**6のとき前処理は約950ms (PyPyなら約340ms, 10**7で約1800ms)
    使用例：
    comb = Combination(1000000)
    print(comb(5, 3))  # 10
    """
    def __init__(self, n_max, mod=10**9+7):
        self.mod = mod
        self.modinv = self.make_modinv_list(n_max)
        self.fac, self.facinv = self.make_factorial_list(n_max)

    def __call__(self, n, r):
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def make_factorial_list(self, n):
        # 階乗のリストと階乗のmod逆元のリストを返す O(n)
        # self.make_modinv_list()が先に実行されている必要がある
        fac = [1]
        facinv = [1]
        for i in range(1, n+1):
            fac.append(fac[i-1] * i % self.mod)
            facinv.append(facinv[i-1] * self.modinv[i] % self.mod)
        return fac, facinv

    def make_modinv_list(self, n):
        # 0からnまでのmod逆元のリストを返す O(n)
        modinv = [0] * (n+1)
        modinv[1] = 1
        for i in range(2, n+1):
            modinv[i] = self.mod - self.mod//i * modinv[self.mod%i] % self.mod
        return modinv
      
if (X+Y) % 3 > 0:
  print((0))
  exit(0)
  
K = (X+Y)//3

if X < K or Y < K:
  print((0))
  exit(0)

comb = Combination(K+10)
print((comb(K, X-K)))
# Original solution
x, y = list(map(int, input().split()))

MOD = int(1.0e+9 + 7)
DP_max = 3333334

DP = []

X = int((2 * y - x) / 3)
Y = int((2 * x - y) / 3)

def cmb(n, r, p):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % p

p = 10 ** 9 + 7
N = 10 ** 6  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % p)
    inv.append((-inv[p % i] * (p // i)) % p)
    factinv.append((factinv[-1] * inv[-1]) % p)

if((2 * y - x) % 3 != 0 or (2 * x - y) % 3 != 0 or
   (2 * y - x) < 0 or (2 * x - y) < 0):
    print((0))
else:
    print((cmb(X + Y, Y, MOD)))

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

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

X = int((2 * y - x) / 3)
Y = int((2 * x - y) / 3)

MOD = int(1.0e+9 + 7)
N = int(7.0e+5) # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % MOD)
    inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
    factinv.append((factinv[-1] * inv[-1]) % MOD)

if((2 * y - x) % 3 != 0 or (2 * x - y) % 3 != 0 or
   (2 * y - x) < 0 or (2 * x - y) < 0):
    print((0))
else:
    print((cmb(X + Y, Y, MOD)))
# Original solution
import math
a,b=list(map(int,input().split()))
x=max(a,b)
y=min(a,b)
p=abs(x-y)

P = 10**9 + 7
N = 1000000
inv_t = [0]+[1]
for i in range(2,N):
  inv_t += [inv_t[P % i] * (P - int(P / i)) % P]

if (x+y)%3!=0:
    print((0))
elif x>y*2:
    print((0))
else:
    n=(x+y)//3
    q=(2*x-y)//3
    r=(2*y-x)//3
    
    #print(math.factorial(q+r)//math.factorial(q)//math.factorial(r)%(10**9+7))
    ans=1
    qq=1
    rr=1
    for i in range(1,q+r+1):
        ans*=i
        ans%=10**9+7
    for i in range(1,q+1):
        ans*=inv_t[i]
        ans%=10**9+7

    P = 10**9 + 7
    N = r+2
    inv_t = [0]+[1]
    for i in range(2,N):
        inv_t += [inv_t[P % i] * (P - int(P / i)) % P]

    for i in range(1,r+1):
        ans*=inv_t[i]
        ans%=10**9+7
            
            
    print(ans)


# Optimized solution
import math
a,b=list(map(int,input().split()))
x=max(a,b)
y=min(a,b)
p=abs(x-y)

if (x+y)%3!=0:
    print((0))
elif x>y*2:
    print((0))
else:
    n=(x+y)//3
    q=(2*x-y)//3
    r=(2*y-x)//3
    
    #print(math.factorial(q+r)//math.factorial(q)//math.factorial(r)%(10**9+7))
    ans=1
    qq=1
    rr=1
    P = 10**9 + 7
    N = max(q,r)+2
    inv_t = [0]+[1]
    for i in range(2,N):
        inv_t += [inv_t[P % i] * (P - int(P / i)) % P]
    for i in range(1,q+r+1):
        ans*=i
        ans%=10**9+7
    for i in range(1,q+1):
        ans*=inv_t[i]
        ans%=10**9+7
    for i in range(1,r+1):
        ans*=inv_t[i]
        ans%=10**9+7
            
            
    print(ans)