Problem:
Score : 400 points

Problem Statement

There is a knight - the chess piece - at the origin (0, 0) of a two-dimensional grid.

When the knight is at the square (i, j), it can be moved to either (i+1,j+2) or (i+2, j+1).

In how many ways can the knight reach the square (X, Y)?

Find the number of ways modulo 10^9 + 7.

Constraints

1 \leq X \leq 10^6

1 \leq Y \leq 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

X Y

Output

Print the number of ways for the knight to reach (X, Y) from (0, 0), modulo 10^9 + 7.

Sample Input 1

3 3

Sample Output 1

2

There are two ways: (0,0) \to (1,2) \to (3,3) and (0,0) \to (2,1) \to (3,3).

Sample Input 2

2 2

Sample Output 2

0

The knight cannot reach (2,2).

Sample Input 3

999999 999999

Sample Output 3

151840682

Print the number of ways modulo 10^9 + 7.

Solution in Kotlin (1.3.71) (judge verdict: Time Limit Exceeded)

import kotlin.math.max
import kotlin.math.min

fun main() {
    abc145d()
}

fun abc145d() {
    val (x, y) = readLine()!!.split(" ").map { it.toInt() }
    if (x == y && x % 3 != 0) {
        // xとyが同じ値の場合、3の倍数でないと到達不可能
        // 2,2とか8,8とか
        println(0)
        return
    }
    // パスカルの三角形で考えれば答えは出るが、すべての組み合わせを求めていくと時間内におさまらないと思われる
    val small = min(x, y)
    val big = max(x, y)
    if (small * 2 == big) {
        // x,yの座標の小さい方の2倍＝大きい方ならその移動パターンは1しかない（1,2移動を選び続けるor2,1を選び続けるしかないので）
        println(1)
        return
    }
    if (small * 2 <= big) {
        // xとyの関係はお互いの2倍までの範囲内が限度なので、それを超えた盤面ではXYに到達不可能
        println(0)
        return
    }
    // 3の倍数のマスを基準に探していけば早い気がする
    var oneLimit = small
    var twoLimit = oneLimit
    var one = small / 3
    var two = 0
    var found = false
    while (!found && one <= oneLimit) {
        two = 0
        while (!found && two <= twoLimit) {
            if (one + two * 2 == small && one * 2 + two == big) {
                found = true
                break
            }
            two++
        }
        if (!found) one++
    }
    if (found) {
        val depth = one + two
        val memo = mutableMapOf<Pair<Int, Int>, Int>()
        val pattern = triangle(depth, two, memo)
        println(pattern % 1_000_000_007)
    } else {
        // 到達できない
        println(0)
    }
}

private fun triangle(i: Int, j: Int, memo: MutableMap<Pair<Int, Int>, Int>): Int {
    //    if (i == j) return 1
    //    if (i == 0 || j == 0) return 1
    //    if (j == 1 || j + 1 == i) return i
    //    if (i to j in memo) {
    //        return memo.getOrDefault(i to j, 1)
    //    }
    //    val one = triangle(i -1, j -1, memo)
    //    val two = triangle(i - 1, j, memo)
    //    memo[i to j] = one + two
    //    return one + two
    val base_num = 1_000_000_007
    val max_num = i + 1
    val fac = LongArray(max_num) { 1L }
    val inv = LongArray(max_num) { 0L }
    val finv = LongArray(max_num) { 1L }
    inv[1] = 1L
    for (k in 2 until max_num) {
        fac[k] = fac[k - 1] * k % base_num
        inv[k] = base_num - inv[base_num % k] * (base_num / k) % base_num
        finv[k] = finv[k - 1] * inv[k] % base_num
    }
    val ans = fac[i] * (finv[j] * finv[i - j] % base_num) % base_num
    return ans.toInt()
}