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 Rust (1.42.0) (judge verdict: Accepted)

#![allow(non_snake_case)]
#![allow(unused_imports)]
use proconio::input;
use std::cmp::max;
// use std::cmp::min;
// use std::collections::HashMap;
// use std::collections::VecDeque;

// a^n % m
fn mod_pow(a: i64, n: u32, m: i64) -> i64 {
    if n == 0 {
        return 1;
    }

    if n == 1 {
        return a % m;
    }

    if n % 2 == 1 {
        let k = mod_pow(a, (n - 1) / 2, m);
        let mut ans = (a * k) % m;
        ans = (ans * k) % m;
        return ans;
    } else {
        let k = mod_pow(a, n / 2, m);
        let ans = (k * k) % m;
        return ans;
    }
}

// O(N^2)の解法しか思い浮かばなかったので答えを見た
fn main() {
    input! {
        X: usize,
        Y: usize,
    }

    const MOD: i64 = 1000_000_000 + 7;
    if (X + Y) % 3 != 0 {
        println!("0");
        return;
    }

    // n + 2m = X, 2n + m = Yより、
    // 3n + 3m = X + Y
    // n + m = (X + Y) / 3

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

    // O(N^2)だと間に合わない
    // カウントをテーブルで持っておきつつ幅優先みたいな感じで広げていけば間に合うか?
    // ダメー。

    if 2 * X < Y || 2 * Y < X {
        println!("0");
        return;
    }

    let M = 2 * X - Y;
    let N = 2 * Y - X;
    if M % 3 != 0 || N % 3 != 0 {
        println!("0");
        return;
    }

    let n: usize = N / 3;
    let m: usize = M / 3;

    let mut fact_memo: Vec<i64> = vec![0; n + m + 1];
    fact_memo[0] = 1;
    fact_memo[1] = 1;
    for i in 2..n + m + 1 {
        fact_memo[i] = (fact_memo[i - 1] * i as i64) % MOD;
    }

    let fact_n = fact_memo[n];

    // a * a^(p-2) = 1 (mod p)
    // (MOD - 2) 乗を愚直に計算するとだめ
    let fact_inv_n = mod_pow(fact_n, (MOD - 2) as u32, MOD);

    let fact_m = fact_memo[m];
    // a * a^(p-2) = 1 (mod p)
    let fact_inv_m = mod_pow(fact_m, (MOD - 2) as u32, MOD);

    let mut ans = (fact_memo[n + m] * fact_inv_n) % MOD;
    ans = (ans * fact_inv_m) % MOD;

    println!("{}", ans);
}