CodeEff/ECCO huggingface dataset:
# Original solution
x,y=list(map(int,input().split()))
MAX_NUM = 2*10**6 + 1
pr = 10**9+7
fac  = [0 for _ in range(MAX_NUM)]
finv = [0 for _ in range(MAX_NUM)]
inv  = [0 for _ in range(MAX_NUM)]
fac[0]  = fac[1] = 1
finv[0] = finv[1] = 1
inv[1] = 1
for i in range(2,MAX_NUM):
    fac[i] = fac[i-1] * i % pr
    inv[i] = pr - inv[pr%i] * (pr // i) % pr
    finv[i] = finv[i-1] * inv[i] % pr
def c(n,k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n-k] % pr) % pr
if (x+y)%3:
    print((0))
else:
    n=(x+y)//3
    x-=n
    y-=n
    print((c(x+y,x)))


# Optimized solution
x,y=list(map(int,input().split()))
MAX_NUM = 2*10**6 + 1
MAX_NUM//=3
MAX_NUM+=1
pr = 10**9+7
fac  = [0 for _ in range(MAX_NUM)]
finv = [0 for _ in range(MAX_NUM)]
inv  = [0 for _ in range(MAX_NUM)]
fac[0]  = fac[1] = 1
finv[0] = finv[1] = 1
inv[1] = 1
for i in range(2,MAX_NUM):
    fac[i] = fac[i-1] * i % pr
    inv[i] = pr - inv[pr%i] * (pr // i) % pr
    finv[i] = finv[i-1] * inv[i] % pr
def c(n,k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n-k] % pr) % pr
if (x+y)%3:
    print((0))
else:
    n=(x+y)//3
    x-=n
    y-=n
    print((c(x+y,x)))
# Original solution
from sys import stdin, setrecursionlimit

setrecursionlimit(10 ** 9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


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

n = (X + Y) // 3
x = (2 * X - Y) // 3
y = (-X + 2 * Y) // 3
if (X + Y) % 3 or x < 0 or y < 0:
    print((0))
    exit()

MOD = 1000000007
COM_MAX = n

fac, finv, inv = [0] * (COM_MAX + 1), [0] * (COM_MAX + 1), [0] * (COM_MAX + 1)
fac[0] = fac[1] = 1
finv[0] = finv[1] = 1
inv[1] = 1

for i in range(2, COM_MAX + 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


def mod_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


print((mod_com(n, x)))


# Optimized solution
from sys import stdin, setrecursionlimit

setrecursionlimit(10 ** 9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


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

n = (X + Y) // 3
x = (2 * X - Y) // 3
y = (-X + 2 * Y) // 3
if (X + Y) % 3 or x < 0 or y < 0:
    print((0))
    exit()


def mod_com(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    if k > n - k:
        k = n - k
    if k == 0:
        return 1
    ans = 1
    for i in range(n - k + 1, n + 1):
        ans = ans * i % MOD

    inv = [0] * (k + 1)
    inv[1] = 1
    for i in range(2, k + 1):
        inv[i] = MOD - inv[MOD % i] * (MOD // i) % MOD
        ans = ans * inv[i] % MOD

    return ans


print((mod_com(n, x)))
# Original solution
from sys import stdin, setrecursionlimit

setrecursionlimit(10 ** 9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


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

n = (X + Y) // 3
x = (2 * X - Y) // 3
y = (-X + 2 * Y) // 3
if (X + Y) % 3 or x < 0 or y < 0:
    print((0))
    exit()


def mod_com(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    if k > n - k:
        k = n - k
    if k == 0:
        return 1
    ans = 1
    for i in range(n - k + 1, n + 1):
        ans = ans * i % MOD

    inv = [0] * (k + 1)
    inv[1] = 1
    for i in range(2, k + 1):
        inv[i] = MOD - inv[MOD % i] * (MOD // i) % MOD
        ans = ans * inv[i] % MOD

    return ans


print((mod_com(n, x)))


# Optimized solution
from sys import stdin, setrecursionlimit

setrecursionlimit(10 ** 9)
INF = 1 << 60


def input():
    return stdin.readline().strip()


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

n = (X + Y) // 3
x = (2 * X - Y) // 3
y = (-X + 2 * Y) // 3
if (X + Y) % 3 or x < 0 or y < 0:
    print((0))
    exit()


def mod_com(n, r):
    MOD = 1000000007
    r = min(r, n - r)
    numer = denom = 1
    for i in range(1, r + 1):
        numer = numer * (n - r + i) % MOD
        denom = denom * i % MOD
    return numer * pow(denom, MOD - 2, MOD) % MOD


print((mod_com(n, x)))
# Original solution
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60


def mod_com_once(n, r, MOD):
    if n < r:
        return 0
    if n < 0 or r < 0:
        return 0
    r = min(r, n - r)
    numer = denom = 1
    for i in range(1, r + 1):
        numer = numer * (n - r + i) % MOD
        denom = denom * i % MOD
    return numer * pow(denom, MOD - 2, MOD) % MOD


def main():
    MOD = 1000000007
    X, Y = list(map(int, readline().split()))

    p = (2 * X - Y) // 3
    q = (-X + 2 * Y) // 3

    if (X + Y) % 3 or p < 0 or q < 0:
        print((0))
        return

    print((mod_com_once(p + q, p, MOD)))
    return


if __name__ == '__main__':
    main()


# Optimized solution
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60


def mod_com_once(n, r, MOD):
    if n < r:
        return 0
    if n < 0 or r < 0:
        return 0
    r = min(r, n - r)
    numer = denom = 1
    for i in range(n - r + 1, n + 1):
        numer = numer * i % MOD
    for i in range(1, r + 1):
        denom = denom * i % MOD
    return numer * pow(denom, MOD - 2, MOD) % MOD


def main():
    MOD = 1000000007
    X, Y = list(map(int, readline().split()))

    p = (2 * X - Y) // 3
    q = (-X + 2 * Y) // 3

    if (X + Y) % 3 or p < 0 or q < 0:
        print((0))
        return

    print((mod_com_once(p + q, p, MOD)))
    return


if __name__ == '__main__':
    main()
# Original solution
mod = 10**9+7
n = 10**6

def comb(n, r):
    if 2 * r > n: return comb(n, n-r)
    return fac[n] * inv[r] * inv[n-r] % mod

x, y = list(map(int, input().split()))
if (x+y) % 3 != 0:
  print((0))
  exit()
     
a = -(x-2*y)//3
b = (2*x-y)//3 
if a<0 or b<0:
  print((0))
  exit()
  
fac = [1] * (n+2)
inv = [1] * (n+2)
for i in range(2, n+1):
    fac[i] = fac[i-1] * i % mod
inv[n] = pow(fac[n], mod - 2, mod)
for i in range(n-1, 1, -1):
    inv[i] = inv[i + 1] * (i + 1) % mod
  
print((comb(a+b, a) % mod))

# Optimized solution
mod = 10**9+7

def comb(n, r):
    if 2 * r > n: return comb(n, n-r)
    return fac[n] * inv[r] * inv[n-r] % 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()
  
fac = [1] * (n+2)
inv = [1] * (n+2)
for i in range(2, n+1):
    fac[i] = fac[i-1] * i % mod
inv[n] = pow(fac[n], mod - 2, mod)
for i in range(n-1, 1, -1):
    inv[i] = inv[i + 1] * (i + 1) % mod
  
print((comb(x+y, x) % mod))
# Original solution
x,y=list(map(int,input().split()))
mod=10**9+7
n_max=10**6+1
F,FI=[0]*(n_max+1),[0]*(n_max+1)
F[0],FI[0]=1,1
for i in range(n_max):
  F[i+1]=(F[i]*(i+1))%mod
  FI[i+1]=pow(F[i+1],mod-2,mod)
def comb(x,y):
  return (F[x]*FI[x-y]*FI[y])%mod
a,b=2*y-x,2*x-y
if a<0 or b<0:
  print((0))
elif a%3!=0 or b%3!=0:
  print((0))
else:
  a//=3
  b//=3
  print((comb(a+b,a)))


# Optimized solution
x,y=list(map(int,input().split()))
mod=10**9+7
n_max=10**6+1
F=[0]*(n_max+1)
F[0]=1
for i in range(n_max):
  F[i+1]=(F[i]*(i+1))%mod
def comb(x,y):
  return (F[x]*pow(F[x-y],mod-2,mod)*pow(F[y],mod-2,mod))%mod
a,b=2*y-x,2*x-y
if a<0 or b<0:
  print((0))
elif a%3!=0 or b%3!=0:
  print((0))
else:
  a//=3
  b//=3
  print((comb(a+b,a)))
# Original solution
class Combination:
    '''mod上の
    計算量：階乗・逆元テーブルの作成O(N)
    nCkを求めるO(1)'''
 
    def __init__(self, n, mod):
        self.fact = [1]
        for i in range(1, n + 1):
            self.fact.append(self.fact[-1] * i % mod)
        self.inv_fact = [pow(self.fact[i], mod - 2, mod) for i in range(n + 1)]
        self.mod = mod
 
    def factorial(self, k):
        """k!を求める O(1)"""
        return self.fact[k]
 
    def inverse_factorial(self, k):
        """k!の逆元を求める O(1)"""
        return self.inv_fact[k]
 
    def permutation(self, k, r):
        """kPrを求める O(1)"""
        if k < r:
            return 0
        return (self.fact[k] * self.inv_fact[r]) % self.mod
 
    def combination(self, k, r):
        """kCrを求める O(1)"""
        if k < r:
            return 0
        return (self.fact[k] * self.inv_fact[k - r] * self.inv_fact[r]) % self.mod

    def combination_large(self, k, r):
        """kCrを求める O(r) kが大きいが、r <= nを満たしているときに使用"""
        if k < r:
            return 0
        res = 1
        for l in range(r):
            res *= (k - l)
            res %= self.mod
        return (res * self.inv_fact[r]) % self.mod

x, y = list(map(int, input().split()))
mod = 10**9 + 7
comb = Combination(10**6,mod)

if (x+y)%3 != 0:
    print((0))
    exit(0)
i = (2*x-y)//3
j = (2*y-x)//3
print((comb.combination(i+j, i)))


# Optimized solution
class Combination:
    """階乗とその逆元のテーブルをO(N)で事前作成し、組み合わせの計算をO(1)で行う"""
    def __init__(self, n, mod):
        self.fact = [1]
        for i in range(1, n + 1):
            self.fact.append(self.fact[-1] * i % mod)
        self.inv_fact = [0] * (n + 1)
        self.inv_fact[n] = pow(self.fact[n], mod - 2, mod)
        for i in reversed(list(range(n))):
            self.inv_fact[i] = self.inv_fact[i + 1] * (i + 1) % mod
        self.mod = mod

    def factorial(self, k):
        """k!を求める O(1)"""
        return self.fact[k]

    def inverse_factorial(self, k):
        """k!の逆元を求める O(1)"""
        return self.inv_fact[k]

    def permutation(self, k, r):
        """kPrを求める O(1)"""
        if k < r:
            return 0
        return (self.fact[k] * self.inv_fact[k - r]) % self.mod

    def combination(self, k, r):
        """kCrを求める O(1)"""
        if k < r:
            return 0
        return (self.fact[k] * self.inv_fact[k - r] * self.inv_fact[r]) % self.mod

    def combination_large(self, k, r):
        """kCrを求める O(r) kが大きいが、r <= nを満たしているときに使用"""
        if k < r:
            return 0
        res = 1
        for l in range(r):
            res *= (k - l)
            res %= self.mod
        return (res * self.inv_fact[r]) % self.mod



x, y = list(map(int, input().split()))
mod = 10**9 + 7
comb = Combination(10**6,mod)

if (x+y)%3 != 0:
    print((0))
    exit(0)
i = (2*x-y)//3
j = (2*y-x)//3
n = i+j
r = i
if not 0 <= r <= n:
    print((0))
    exit(0)
print((comb.combination(n, r)))
# Original solution
def mod_inv(a, m):
    return pow(a,m-2,m)


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

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

n = (X + Y) // 3
nx, ny = X - n, Y - n

if nx < 0 or ny < 0:
    print((0))
    exit()

ans = 1
for i in range(1, nx + ny + 1):
    ans = ans * i % MOD
for i in range(1, nx + 1):
    ans = ans * mod_inv(i, MOD) % MOD
for i in range(1, ny + 1):
    ans = ans * mod_inv(i, MOD) % MOD

print(ans)

# Optimized solution
def mod_inv(a, m):
    return pow(a, m-2, m)


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

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

n = (X + Y) // 3
nx, ny = X - n, Y - n

if nx < 0 or ny < 0:
    print((0))
    exit()

ans = 1
for i in range(nx + 1, nx + ny + 1):
    ans = ans * i % MOD
for i in range(1, ny + 1):
    ans = ans * mod_inv(i, MOD) % MOD

print(ans)
# Original solution
MOD = 10**9 + 7
def nck(n, k):
    numer, denom = 1, 1
    for i in range(k):
        numer = numer * (n - i) % MOD
        denom = denom * (k - i) % MOD
    return numer * pow(denom, MOD-2, MOD) % MOD

x, y = list(map(int, input().split()))
# (1, 2) 動く回数をm回、(2, 1) 動く回数をn回とする
n = -1
for m in range(min(x//1, y//2) + 1):
    rx = x - m
    ry = y - 2 * m
    if rx == ry * 2:
        n = ry
        break

if n == -1:
    print((0))
else:
    print((nck(m+n, min(m, n))))


# Optimized solution
def nck(n, k):
    numer, denom = 1, 1
    for i in range(k):
        numer = numer * (n-i) % MOD
        denom = denom * (k-i) % MOD
    return numer * pow(denom, MOD-2, MOD) % MOD

x, y = list(map(int, input().split()))
MOD = 10 ** 9 + 7

i = 2 * y - x
j = 2 * x - y
if i % 3 != 0 or j % 3 != 0 or i < 0 or j < 0:
    print((0))
else:
    i, j = i // 3, j // 3
    print((nck(i+j, min(i, j))))
# Original solution
import math
import itertools

x,y=list(map(int, input().split())) 
v=x+y
if v%3!=0:
    print((0))
    exit()

if (v//3-abs(x-y))%2!=0:
    print((0))
    exit()

v1=(v//3-abs(x-y))//2+abs(x-y)
v2=v//3-v1

if v2<0:
    print((0))
    exit()

def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

a = cmb(v//3,v1)
a//(math.factorial(v2))

print((a%(10**9+7)))






# Optimized solution
x,y= list(map(int, input().split()))
a=min(x,y)
b=max(x,y)
mod=pow(10,9)+7
if b-a>a or (a-(b-a))%3!=0:
    print((0))

else:
    r=(a-(b-a))//3
    l=((a-(b-a))//3)+(b-a)
    c=1
    d=1
    for i in range(r):
        c=(c*(l+r-i))%mod
        d=(d*(r-i))%mod
    ans=c*pow(d,mod-2,mod)
    print((ans%mod))
# Original solution
x, y = list(map(int, input().split()))
mod = 1000000007
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))
else:
  n = (x + y) // 3
  if n > x or n > y:
    print((0))
  else:
    nx = x - n
    comb = Combination(n)
    print((comb(n, nx)))


# Optimized solution
x, y = list(map(int, input().split()))
mod = 10**9+7
def inv(x):
        return pow(x, mod-2, mod)
def fact(x):
        f = 1 
        for i in range(1, x + 1): 
                f *= i
                f %= mod    
        return f
def comb(n, r): 
        return (fact(n) * inv(fact(n-r)) * inv(fact(r))) % mod 
if (x + y) % 3 != 0:
  print((0))
else:
  n = (x + y) // 3
  if n > x or n > y:
    print((0))
  else:
    nx = x - n
    print((comb(n, nx)))
# Original solution
x, y = list(map(int, input().split()))
diff = abs(x - y)
ref = (min(x, y) - diff)//3
total = ref*2 + diff
mod = 10**9 + 7
ans = 1

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


for i in range(min(ref, total - ref)):
    ans = ans*(total - i)%mod
    ie = pow((i + 1), (mod - 2), mod)
    ans = ans*ie%mod

print(ans)

# Optimized solution
x, y = list(map(int, input().split()))
diff = abs(x - y)
ref = (min(x, y) - diff)//3
total = ref*2 + diff
mod = 10**9 + 7
ans = 1
ie = 1

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


for i in range(min(ref, total - ref)):
    ans = ans*(total - i)%mod
    ie = ie*(i + 1)%mod

ie = pow(ie, mod - 2, mod)
ans = ans*ie%mod
print(ans)
# Original solution
def cmb(n, k, mod, fac, infac):
  k = min(k,n-k)
  return fac[n] * infac[k] * infac[n-k] % mod

def tables(mod, n):
  fac = [1, 1] 
  infac = [1, 1] 
  inverse = [0, 1] 
  for i in range(2, n+1):
    fac.append((fac[-1] * i) % mod)
    inverse.append((-inverse[mod % i] * (mod // i)) % mod)
    infac.append((infac[-1] * inverse[-1]) % mod)
  return fac,infac

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

if X > Y:
  X, Y = Y, X

move = X + Y

if move % 3 != 0:
  print((0))
else:
  total = move // 3
  n = X - total
  
  if n < 0:
    print((0))
    
  else:
    MOD = 10 ** 9 + 7
    fac, infac = tables(MOD, total)
    ans = cmb(total, n, MOD, fac, infac)
    
    print(ans)

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

con = (X + Y) // 3
dif = M - m
n = (con - dif) // 2

if (X + Y) % 3 != 0 or n < 0:
  print((0))
  
else:
  def comb(n, r):
    n += 1
    over = 1
    under = 1
    for i in range(1,r + 1):
      over = over * (n - i) % mod
      under = under * i % mod
    #powでunder ** (mod - 2) % modを実現、逆元を求めている
    return over * pow(under,mod - 2,mod) % mod
  
  ans = comb(con,n)
  
  print(ans)
# Original solution
def knight(x, y):
    mod = 10 ** 9 + 7
    x, y = min(x, y), max(x, y)

    if (x + y) % 3 != 0:
        return 0
    if y > 2 * x:
        return 0

    move = (x + y) // 3
    right = 2 * move - y
    up = move-right

    ans = 1
    for i in range(1, move + 1):
        ans *= i
        ans %= mod
    for i in range(1, right + 1):
        ans *= pow(i, mod - 2, mod)
        ans %= mod
    for i in range(1, up + 1):
        ans *= pow(i, mod - 2, mod)
        ans %= mod
    return ans


if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    ans = knight(x, y)
    print(ans)


# Optimized solution
def knight(x, y):
    mod = 10 ** 9 + 7
    x, y = min(x, y), max(x, y)

    if (x + y) % 3 != 0:
        return 0
    if y > 2 * x:
        return 0

    move = (x + y) // 3
    right = 2 * move - y
    up = move-right

    ans = 1
    for i in range(up):
        ans *= (move - i)
        ans *= pow(i + 1, mod - 2, mod)
        ans %= mod

    return ans


if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    ans = knight(x, y)
    print(ans)
# Original solution
def knight(x, y):
    mod = 10 ** 9 + 7
    x, y = min(x, y), max(x, y)

    if (x + y) % 3 != 0:
        return 0
    if y > 2 * x:
        return 0

    move = (x + y) // 3
    right = 2 * move - y
    up = move-right

    ans = 1
    for i in range(up):
        ans *= (move - i)
        ans *= pow(i + 1, mod - 2, mod)
        ans %= mod

    return ans


if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    ans = knight(x, y)
    print(ans)


# Optimized solution
def knight(x, y):
    mod = 10 ** 9 + 7
    x, y = min(x, y), max(x, y)

    if (x + y) % 3 != 0:
        return 0
    if y > 2 * x:
        return 0

    move = (x + y) // 3
    right = 2 * move - y
    up = move-right

    ans = 1
    tmp = 1
    for i in range(up):
        ans *= (move - i)
        tmp *= i + 1
        ans %= mod
        tmp %= mod
    ans *= pow(tmp, mod - 2, mod)
    return ans % mod


if __name__ == "__main__":
    x, y = list(map(int, input().split()))
    ans = knight(x, y)
    print(ans)
# Original solution
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)


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


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

if (X + Y) % 3 != 0:
    ans = 0
else:
    n = (X + Y) // 3
    r = min(X, Y) - n
    ans = cmb(n, r, mod)
print(ans)


# Optimized solution
mod = 10**9+7

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


def comb(n, r, mod):
    if r < 0 or n < r:
        return 0
    return fact[n]*pow(fact[r], mod-2, mod) * pow(fact[n-r], mod-2, mod) % mod


if (X + Y) % 3 != 0:
    ans = 0
else:
    n = (X + Y) // 3
    r = min(X, Y)-n
    # nCr
    fact = [1, 1]
    for i in range(2, n+1):
        fact.append(fact[-1] * i % mod)
    ans = comb(n, r, mod)

print(ans)
# Original solution
N, a, b = list(map(int, input().split())); a -= 1; b -= 1
P = []
Q = []
for i in range(N):
    x, y = list(map(int, input().split()))
    P.append((x-y, x+y, i))
    Q.append((x+y, x-y, i))

d = max(abs(P[a][0] - P[b][0]), abs(P[a][1] - P[b][1]))

*parent, = list(range(N))
def root(x):
    if x == parent[x]:
        return x
    y = parent[x] = root(parent[x])
    return y
def unite(x, y):
    px = root(x); py = root(y)
    if px < py:
        parent[py] = px
    else:
        parent[px] = py
C = [0]*N
D = [0]*N

def solve(P0):
    P = P0[:]
    P.sort()

    s = t = 0
    for i in range(N):
        x, y, i0 = P[i]
        while t < N and P[t][0] < x-d or (P[t][0] == x-d and P[t][1] <= y+d): t += 1
        while s < N and (P[s][0] < x-d or (P[s][0] == x-d and P[s][1] < y-d)): s += 1
        for j in range(s, t):
            j0 = P[j][2]
            unite(i0, j0)
            if abs(P0[i0][0] - P0[j0][0]) == abs(P0[i0][1] - P0[j0][1]):
                D[i0] += 1
            else:
                C[i0] += 1
solve(P)
solve(Q)

S = T = 0
r = root(a)
for i in range(N):
    if root(i) == r:
        S += C[i]; T += D[i]
print((S + T//2))


# Optimized solution
N, a, b = list(map(int, input().split())); a -= 1; b -= 1
P = []
Q = []
for i in range(N):
    x, y = list(map(int, input().split()))
    P.append((x-y, x+y, i))
    Q.append((x+y, x-y, i))

d = max(abs(P[a][0] - P[b][0]), abs(P[a][1] - P[b][1]))

*parent, = list(range(N))
def root(x):
    if x == parent[x]:
        return x
    y = parent[x] = root(parent[x])
    return y
def unite(x, y):
    px = root(x); py = root(y)
    if px < py:
        parent[py] = px
    else:
        parent[px] = py
C = [0]*N
D = [0]*N

def check(P0, i0, j0):
    return abs(P0[i0][0] - P0[j0][0]) == abs(P0[i0][1] - P0[j0][1])

def solve(P0):
    P = P0[:]
    P.sort()

    s = t = 0; prev = -1
    for i in range(N):
        x, y, i0 = P[i]
        while t < N and P[t][0] < x-d or (P[t][0] == x-d and P[t][1] <= y+d): t += 1
        while s < N and (P[s][0] < x-d or (P[s][0] == x-d and P[s][1] < y-d)): s += 1
        if s < t:
            j0 = P[s][2]
            unite(i0, j0)
            if check(P0, i0, j0):
                D[i0] += 1
            else:
                C[i0] += 1
            if s < t-1:
                j0 = P[t-1][2]
                if check(P0, i0, j0):
                    D[i0] += 1
                    C[i0] += t-s-2
                else:
                    C[i0] += t-s-1
            for j in range(max(prev, s), t-1):
                unite(P[j][2], P[j+1][2])
            prev = t-1
solve(P)
solve(Q)

S = T = 0
r = root(a)
for i in range(N):
    if root(i) == r:
        S += C[i]; T += D[i]
print((S + T//2))
# Original solution
n = int(eval(input()))
print((n*n*n))


# Optimized solution
n = int(eval(input()))
print((n**3))
# Original solution
# 2019-11-18 00:38:19(JST)
import sys
# import collections
# import math
# from string import ascii_lowercase, ascii_uppercase, digits
# from bisect import bisect_left as bi_l, bisect_right as bi_r
# import itertools
# from functools import reduce
# import operator as op
import re
# import heapq
# import array
# from scipy.misc import comb # (default: exact=False)
# import numpy as np 


def main():
    n = int(sys.stdin.readline().rstrip())
    print((n ** 3))
    
if __name__ == "__main__":
    main()


# Optimized solution
import sys

n = int(sys.stdin.readline().rstrip())

def main():
    return n ** 3

if __name__ == '__main__':
    ans = main()
    print(ans)
# Original solution
N = int(eval(input()))

print((N**3))

# Optimized solution
num = int(eval(input()))

print((num ** 3))
# Original solution
N = int(eval(input()))
print((N**3))


# Optimized solution
def main() -> None:
    print((int(eval(input())) ** 3))


if __name__ == '__main__':
    main()
# Original solution
a = int(eval(input()))
print((a**3))


# Optimized solution
a=int(eval(input()))
print((a*a*a))