{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
import           Data.Proxy                   (Proxy (..))
import           Data.Ratio                   ((%))
import           Data.Vector.Unboxed          (Unbox)
import           Data.Vector.Unboxing         (Unboxable)
import qualified Data.Vector.Unboxing         as V
import qualified Data.Vector.Unboxing.Mutable as VM
import           GHC.TypeLits                 (KnownNat, Nat, natVal)

main :: IO ()
main = do
  [x, y] <- map read . words <$> getLine
  print $ solve x y

solve :: Int -> Int -> MInt
solve x y
  | (x + y) `mod` 3 /= 0 = 0
  | otherwise            = comb c (n + m) n
  where n = (-x + y * 2) `div` 3
        m = (x * 2 - y) `div` 3
        c = combination $ n + m :: MComb

-- Modulo Library
newtype Mod a (n :: Nat) = Mod { unMod :: a }
  deriving (Eq, Ord)

modulo :: forall n a. (Integral a, KnownNat n) => a -> Mod a n
modulo a = Mod . mod a $ modulus @n

modulus :: forall n a. (Integral a, KnownNat n) => a
modulus = fromInteger $ natVal (Proxy @n)

instance Show a => Show (Mod a n) where
  show (Mod a) = show a

instance (Integral a, KnownNat n) => Num (Mod a n) where
  fromInteger = modulo . fromInteger

  Mod a + Mod b = modulo $ a + b
  Mod a * Mod b = modulo $ a * b

  abs    (Mod a) = modulo $ abs a
  signum (Mod a) = modulo $ signum a
  negate (Mod a) = modulo $ negate a

instance (Integral a, KnownNat n) => Enum (Mod a n) where
  succ (Mod x)
    | x == unMod (maxBound :: Mod a n) =
        errorWithoutStackTrace "Prelude.Enum.succ{Mod}: tried to take `succ' of maxBound"
    | otherwise           = Mod $ x + 1

  pred (Mod x)
    | x == unMod (minBound :: Mod a n) =
        errorWithoutStackTrace "Prelude.Enum.pred{Mod}: tried to take `pred' of minBound"
    | otherwise            = Mod $ x - 1

  toEnum = fromIntegral
  fromEnum = fromIntegral . unMod

  enumFrom     x   = enumFromTo     x maxBound
  enumFromThen x y = enumFromThenTo x y bound
    where
      bound | fromEnum y >= fromEnum x = maxBound
            | otherwise                = minBound

instance (Integral a, KnownNat n) => Bounded (Mod a n) where
  maxBound = Mod $ pred (modulus @n)
  minBound = 0

instance (Integral a, KnownNat n) => Real (Mod a n) where
  toRational (Mod a) = toInteger a % 1

instance (Integral a, KnownNat n) => Integral (Mod a n) where
  toInteger (Mod a) = toInteger a
  quotRem a b = (a * inv b, 0)

inv :: forall n a. (Integral a, KnownNat n) => Mod a n -> Mod a n
inv x = go (unMod x) (modulus @n) 1 0
  where go _ 0 u _ = modulo u
        go a b u v = go b (a - t * b) v (u - t * v)
          where t = a `div` b

instance (Unbox a, Unboxable a) => Unboxable (Mod a m) where
  type Rep (Mod a m) = a

type MInt = Mod Int 1000000007

-- Combination Library
data Combination a (m :: Nat) = Combination
  { facts :: V.Vector a
  , invs  :: V.Vector a
  , finvs :: V.Vector a
  } deriving (Show, Eq, Ord)

combination :: forall m a. (Integral a, KnownNat m, Unboxable a) => Int -> Combination a m
combination n = Combination xs ys zs
  where is = V.enumFromN 1 n
        m = modulus @m :: Int
        xs = V.scanl (\a b -> a * fromIntegral b) 1 is
        ys = V.create $ do
          v <- VM.replicate (n + 1) 1
          V.forM_ (V.tail is) $ \i -> do
            let (p, q) = divMod m i
            y <- VM.read v q
            VM.write v i $ -y * fromIntegral p
          return v
        zs = V.scanl (*) 1 $ V.tail ys

comb :: (Integral a, Unboxable a)=> Combination a m -> Int -> Int -> a
comb c n k
  | n < k || n < 0 || k < 0 = 0
  | otherwise = facts c V.! n * finvs c V.! k * finvs c V.! (n - k)

type MComb = Combination MInt 1000000007


Measured memory_bytes: 21252