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 PHP7 (7.0.15) (judge verdict: Wrong Answer)

<?php
// $n = (int)trim(fgets(STDIN));
$input = explode(' ', trim(fgets(STDIN)));

// $start = microtime(true);
$x = (int)$input[0];
$y = (int)$input[1];

$mod = 1000000007;
$sum = 0;
// $i+1, $j+2を何回やるか？
$y_max = (int)floor($y / 2);
for ($i=0; $i <= $y_max; $i++) { 
	$x_1 = $i;
	$y_1 = $i * 2;
	// $i+2, $j+1の繰り返しでたどり着けるか？
	if ($x - $x_1 >= 0 && $y - $y_1 >= 0 && $x - $x_1 === ($y - $y_1) * 2) {
		$reach_turn = $i + ($y - $y_1);
		$sum += ModComb::singleComb($reach_turn, $i, $mod);
		$sum %= $mod;
		// 回数の組み合わせとしては1通りしかないはずなのでbreak
		break;
	}
}
// $end = microtime(true);
// echo $end - $start . PHP_EOL;
echo $sum;




/**
 * フェルマーの小定理を利用した組み合わせ計算クラス
 * https://qiita.com/ofutonfuton/items/92b1a6f4a7775f00b6ae
 * $modで組み合わせ爆発を抑制している
 */
class ModComb
{
	// 事前計算テーブル
	private $f_table  = [1]; // $n! % $mod
	private $if_table = [1]; // $k!の($mod-2)乗 % $mod
	// 十分大きな素数にする
	private $mod = 0;

	public function __construct($max = 10000, $mod = 1000000007){
		$this->mod = $mod;
		// 事前計算
		$this->calcFactorial($max);
	}

	// 組み合わせ計算（nCm）
	public function comb($n, $m){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < $m || $n < 0) {
			return 0;
		}
		if (!isset($this->f_table[$n])) {
			$this->calcFactorial($n);
		}
		return ($this->if_table[$n - $m] * $this->if_table[$m] % $this->mod) * $this->f_table[$n] % $this->mod;
	}

	// logNで組み合わせを算出する
	public static function singleComb($n, $m, $mod){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < $m || $n < 0) {
			return 0;
		}
		$f_n    = self::singleFact($n, $mod);
		$if_n_m = self::sigleBinPow(self::singleFact($n-$m, $mod), $mod-2, $mod) % $mod;
		$if_m   = self::sigleBinPow(self::singleFact($m, $mod), $mod-2, $mod) % $mod;
		return ($if_n_m * $if_m % $mod) * $f_n % $mod;
	}

	private static function singleFact($n, $mod){
		$table = [];
		for ($i=0; $i < $n; $i++) { 
			$table[$i] = $i+1;
		}
		$idx = 1;
		while ($idx <= $n) {
			$span = $idx<<1;
			for ($i=0; $i < $n; $i+=$span) { 
				if ($idx + $i < $n) {
					$table[$i] = ($table[$i] * $table[$i+$idx]) % $mod;
				}
			}
			$idx = $idx<<1;
		}
		return $table[0];
	}

	private static function sigleBinPow($x, $n, $mod){
		$ans = 1;
		$bin = decbin($n);
		$cur_pos = strlen($bin) -1;
		while ($cur_pos >= 0) {
			if ($bin[$cur_pos] == '1') {
				$ans = ($ans * $x) % $mod;
			}
			$x = ($x * $x) % $mod;
			--$cur_pos;
		}
		return $ans;
	}

	// 順列計算（nPm）
	public function perm($n, $m){
		if ($n < $m) {
			return 0;
		}
		if (!isset($this->f_table[$n])) {
			$this->calcFactorial($n);
		}
		return ($this->if_table[$n - $m] % $this->mod) * $this->f_table[$n] % $this->mod;
	}

	// 重複組合せ計算（nHm）
	public function dupc($n, $m){
		if ($n === 0 && $m === 0) {
			return 1;
		}
		if ($n < 0 || $m === 0) {
			return 0;
		}
		if (!isset($this->f_table[$n + $m - 1])) {
			$this->calcFactorial($n + $m - 1);
		}
		return ($this->if_table[$n - 1] * $this->if_table[$m] % $this->mod) * $this->f_table[$n + $m - 1] % $this->mod;
	}

	// 既存の事前計算結果テーブルの末尾から$maxまでの階乗までtableを拡張する。
	private function calcFactorial($max){
		$already = count($this->f_table);
		for($i = $already; $i <= $max; $i++){
			$this->f_table[$i] = $this->f_table[$i-1] * $i % $this->mod;
			$this->if_table[$i] = $this->if_table[$i-1] * $this->binPow($i, $this->mod-2) % $this->mod;
		}
	}

	// $xの$n乗を2進数で高速に計算する
	// これを単体で利用する場合、コンストラクタの$maxは低めで良い
	public static function binPow($x, $n){
		$ans = 1;
		$bin = decbin($n);
		$cur_pos = strlen($bin) -1;
		while ($cur_pos >= 0) {
			if ($bin[$cur_pos] == '1') {
				$ans = ($ans * $x) % $this->mod;
			}
			$x = ($x * $x) % $this->mod;
			--$cur_pos;
		}
		return $ans;
	}
}