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, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;

#[derive(Debug, Clone)]
struct Combination {
    fact_inv: Vec<usize>,
    inv: Vec<usize>,
    com: Option<Vec<usize>>,
    MOD: usize,
}
impl Combination {
    fn new(n: usize, MOD: usize) -> Combination {
        let mut fact_inv = vec![0; n + 1];
        let mut inv = vec![0; n + 1];
        fact_inv[0] = 1;
        fact_inv[1] = 1;
        inv[1] = 1;
        for i in 2..=n {
            inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
            fact_inv[i] = fact_inv[i - 1] * inv[i] % MOD;
        }
        Combination {
            fact_inv: fact_inv,
            inv: inv,
            com: None,
            MOD: MOD,
        }
    }
    fn fix_n(&mut self, n: usize) {
        let mut com = vec![0; n + 1];
        com[0] = 1;
        for i in 1..=n {
            com[i] = com[i - 1] * ((n - i + 1) * self.inv[i] % self.MOD) % self.MOD;
        }
        self.com = Some(com)
    }
    fn _calc_nck(&self, n: usize, k: usize) -> usize {
        if n < k {
            return 0;
        }
        let mut ans: usize = 1;
        let mut i = n;
        while n - k < i {
            ans *= i;
            ans %= self.MOD;
            i -= 1;
        }
        ans * self.fact_inv[k] % self.MOD
    }
    fn nck(&self, n: usize, k: usize) -> usize {
        match self.com.clone() {
            None => self._calc_nck(n, k),
            Some(x) => x[k],
        }
    }
    fn nhk(&self, n: usize, k: usize) -> usize {
        if self.fact_inv.len() < n + k - 1 {
            panic!("length must be n+k-1 or larger!")
        }
        self.nck(n + k - 1, k)
    }
}

#[fastout]
fn main() {
    input!{
        x: isize, y: isize,
    }
    if (x + y) % 3 == 0 { 
        let move_cnt = (x + y) / 3;
        let new_x = x - move_cnt;
        let new_y = y - move_cnt;
        if new_x < 0 || new_y < 0 {
            println!("0")
        } else {
            let comb = Combination::new((new_x+new_y) as usize, 1e9 as usize + 7);
            println!("{}", comb.nck((new_x+new_y) as usize, new_x as usize))
        }

    } else {
        println!("0")
    }
}