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.15.1) (judge verdict: Accepted)

use std::io::Write;
use std::ops::{Add, Sub, Mul};
use std::collections::HashMap;

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn main() {
    let (x, y): (isize, isize) = {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        let s = s.trim_right().to_owned();
        let mut ws = s.split_whitespace();
        let a = ws.next().unwrap().parse().unwrap();
        let b = ws.next().unwrap().parse().unwrap();
        (a, b)
    };

    println!("{}", solve(x, y));
}

fn solve(x: isize, y: isize) -> isize {
    let xx3 = 2*x - y;
    let yy3 = -x + 2*y;
    debugln!("{:?}", (xx3, yy3));
    if !(xx3 % 3 == 0 && yy3 % 3 == 0 && xx3 >= 0 && yy3 >= 0) {
        return 0;
    }

    let xx = xx3 / 3;
    let yy = yy3 / 3;

    Modulo::binom(xx + yy, xx).0
}

#[derive(Debug, Copy, Clone)]
struct Modulo(isize);

const MODULO: isize = 1000000000 + 7;

fn positive_rem(a: isize, b: usize) -> isize {
    let b = b as isize;
    let mut value = a % b;
    if value < 0 {
        value += b;
    }
    value
}

impl Modulo {
    fn new(n: isize) -> Modulo {
        Modulo(n % MODULO)
    }

    fn pow(self, p: usize) -> Modulo {
        if self == Modulo(0) {
            return Modulo(0);
        }
        if p == 0 {
            return Modulo(1);
        }

        if p % 2 == 0 {
            let half = self.pow(p / 2);
            half * half
        } else {
            self.pow(p - 1) * self
        }
    }

    fn inv(self) -> Modulo {
        self.pow((MODULO - 2) as usize)
    }

    fn binom(n: isize, k: isize) -> Modulo {
        let mut ret = Modulo::new(1);
        for i in 1..(k + 1) {
            ret = ret * Modulo::new(n - i + 1) * Modulo::new(i).inv();
            // debugln!("{:?}", ret);
        }
        ret
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn inv() {
        assert_eq!(Modulo(1), Modulo(2).inv() * Modulo(2));
        assert_eq!(Modulo(1), Modulo(3).inv() * Modulo(3));
    }
}

impl Add for Modulo {
    type Output = Modulo;

    fn add(self, other: Modulo) -> Modulo {
        Modulo((self.0 + other.0) % MODULO)
    }
}

impl Sub for Modulo {
    type Output = Modulo;

    fn sub(self, other: Modulo) -> Modulo {
        Modulo(positive_rem(self.0 - other.0, MODULO as usize))
    }
}

impl Mul for Modulo {
    type Output = Modulo;

    fn mul(self, other: Modulo) -> Modulo {
        Modulo((self.0 * other.0) % MODULO)
    }
}

impl PartialEq for Modulo {
    fn eq(&self, &other: &Self) -> bool {
        self.0 == other.0
    }
}

impl Eq for Modulo {}