fun main(args: Array<String>) {

    val MOD = 1000000007

    class MInt(var value: Long) {

        constructor(value: Int) : this(value.toLong())

        operator fun plus(a: MInt): MInt = MInt((this.value + a.value) % MOD)
        operator fun plus(a: Long): MInt = this + MInt(a)
        operator fun plus(a: Int): MInt = this + MInt(a)

        operator fun plusAssign(a: MInt) {
            this.value = (this + a).value
        }

        operator fun plusAssign(a: Long) {
            plusAssign(MInt(a))
        }

        operator fun plusAssign(a: Int) {
            plusAssign(MInt(a))
        }

        operator fun minus(a: MInt) = MInt((this.value - a.value) % MOD)
        operator fun minus(a: Long) = this - MInt(a)
        operator fun minus(a: Int) = this - MInt(a)

        operator fun minusAssign(a: MInt) {
            this.value = (this - a).value
        }

        operator fun minusAssign(a: Long) {
            minusAssign(MInt(a))
        }

        operator fun minusAssign(a: Int) {
            minusAssign(MInt(a))
        }

        operator fun times(a: MInt) = MInt((this.value * a.value) % MOD)
        operator fun times(a: Long) = this * MInt(a)
        operator fun times(a: Int) = this * MInt(a)

        operator fun timesAssign(a: MInt) {
            this.value = (this * a).value
        }

        operator fun timesAssign(a: Long) {
            timesAssign(MInt(a))
        }

        operator fun timesAssign(a: Int) {
            timesAssign(MInt(a))
        }

        operator fun div(a: MInt) = this * a.inv()
        operator fun div(a: Long) = div(MInt(a))
        operator fun div(a: Int) = div(MInt(a))

        operator fun divAssign(a: MInt) {
            this.value = (this / a).value
        }

        operator fun divAssign(a: Long) {
            divAssign(MInt(a))
        }

        operator fun divAssign(a: Int) {
            divAssign(MInt(a))
        }

        /**
         * 非再帰拡張 Euclid の互除法
         * 逆元を求める
         */
        fun inv(): MInt {

            var at = this.value.toInt()
            var bt = MOD

            var u = 1
            var v = 0

            var tmp = 0

            while (bt != 0) {
                val t = at / bt
                at -= t * bt
                tmp = at
                at = bt
                bt = tmp

                u -= t * v
                tmp = u
                u = v
                v = tmp
            }

            u %= MOD
            if (u < 0) u += MOD
            return MInt(u.toLong())
        }
    }


    class MCombination(val n: Long) {
        private val fact = Array(n.toInt() + 1) { MInt(1) }
        private val invfact = Array(n.toInt() + 1) { MInt(1) }

        init {
            for (i in 2..n.toInt()) {
                fact[i] = fact[i - 1] * i
                invfact[i] = fact[i].inv()
            }
        }

        operator fun get(n: Int, k: Int): MInt {
            return this[n.toLong(), k.toLong()]
        }

        operator fun get(n: Long, m: Long): MInt {
            if (m > n) {
                return MInt(0)
            }

            return fact[n.toInt()] * invfact[m.toInt()] * invfact[(n - m).toInt()]
        }
    }

    val (x, y) = readLine()!!.split(" ").map(String::toInt)

    val totalMove = (x + y) / 3
    val xCount = x - totalMove
    val yCount = y - totalMove

    if ((x + y) % 3 != 0 || xCount < 0 || yCount < 0) {
        println(0)
        return
    }

    println(MCombination(totalMove.toLong())[totalMove.toLong(), xCount.toLong()].value)

}




Measured memory_bytes: 125260