Problem:
Score : 600 points

Problem Statement

Snuke is standing on a two-dimensional plane. In one operation, he can move by 1 in the positive x-direction, or move by 1 in the positive y-direction.

Let us define a function f(r, c) as follows:

f(r,c) := (The number of paths from the point (0, 0) to the point (r, c) that Snuke can trace by repeating the operation above)

Given are integers r_1, r_2, c_1, and c_2.
Find the sum of f(i, j) over all pair of integers (i, j) such that r_1 ≤ i ≤ r_2 and c_1 ≤ j ≤ c_2, and compute this value modulo (10^9+7).

Constraints

1 ≤ r_1 ≤ r_2 ≤ 10^6

1 ≤ c_1 ≤ c_2 ≤ 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

r_1 c_1 r_2 c_2

Output

Print the sum of f(i, j) modulo (10^9+7).

Sample Input 1

1 1 2 2

Sample Output 1

14

For example, there are two paths from the point (0, 0) to the point (1, 1): (0,0) → (0,1) → (1,1) and (0,0) → (1,0) → (1,1), so f(1,1)=2.

Similarly, f(1,2)=3, f(2,1)=3, and f(2,2)=6. Thus, the sum is 14.

Sample Input 2

314 159 2653 589

Sample Output 2

602215194

Solution in Rust (1.15.1) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use proconio::input;
use modulo::{ModInt, ModuloUtils};

fn main() {
    input! {
        r1: usize,
        c1: usize,
        r2: usize,
        c2: usize,
    }

    let mut ans = g(r2, c2);
    if c1 > 0 {
        ans = ans - g(r1 - 1, c2);
    }
    if r1 > 0 {
        ans = ans - g(r2, c1 - 1);
    }
    if r1 > 0 && c1 > 0 {
        ans = ans + g(r1 - 1, c1 - 1);
    }

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

fn g(r: usize, c: usize) -> ModInt {
    let mut mod_util = ModuloUtils::new();
    mod_util.binom_coef(r + c + 2, r + 1) - ModInt::from(1)
}

mod modulo {
    use std::ops::{Add, Mul, Neg, Sub, AddAssign, MulAssign, SubAssign};

    pub const MODULO: usize = 1_000_000_007;
    // const MODULO: usize = 11;

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

    /// Return (x, y) s.t. ax + by = d where d = gcd(a, b)
    #[allow(unused)]
    pub fn ext_gcd(a: usize, b: usize) -> (isize, isize) {
        if b == 0 {
            return (1, 0);
        }

        let q = (a / b) as isize;
        let r = a % b;
        let (x1, y1) = ext_gcd(b, r);
        (y1, x1 - q * y1)
    }

    #[derive(Debug, Copy, Clone)]
    pub struct ModInt(pub usize);

    impl From<usize> for ModInt {
        fn from(n: usize) -> ModInt {
            ModInt(n % MODULO)
        }
    }

    impl From<isize> for ModInt {
        fn from(n: isize) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n, MODULO as usize))
        }
    }

    impl From<i32> for ModInt {
        fn from(n: i32) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n as isize, MODULO as usize))
        }
    }

    impl ModInt {
        pub fn pow(self, p: usize) -> ModInt {
            if self == ModInt::from(0) {
                return ModInt::from(0);
            }
            if p == 0 {
                return ModInt::from(1);
            }

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

        // when MODULO is prime
        #[allow(unused)]
        pub fn inv(self) -> ModInt {
            let (x, _) = ext_gcd(self.0 as usize, MODULO as usize);
            ModInt::from(x)
        }
    }

    impl Add for ModInt {
        type Output = ModInt;

        fn add(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 + other.0)
        }
    }

    impl Sub for ModInt {
        type Output = ModInt;

        fn sub(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 as isize - other.0 as isize)
        }
    }

    impl Mul for ModInt {
        type Output = ModInt;

        fn mul(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 * other.0)
        }
    }

    impl Neg for ModInt {
        type Output = ModInt;

        fn neg(self) -> Self::Output {
            ModInt::from(0) - self
        }
    }

    impl AddAssign for ModInt {
        fn add_assign(&mut self, other: Self) {
            *self = *self + other;
        }
    }

    impl MulAssign for ModInt {
        fn mul_assign(&mut self, other: Self) {
            *self = *self * other;
        }
    }

    impl SubAssign for ModInt {
        fn sub_assign(&mut self, other: Self) {
            *self = *self - other;
        }
    }

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

    impl Eq for ModInt {}

    #[derive(Debug)]
    pub struct ModuloUtils {
        factorial: Vec<ModInt>,
        factorial_inv: Vec<ModInt>,
        inv: Vec<ModInt>,
    }

    impl ModuloUtils {
        pub fn new() -> ModuloUtils {
            ModuloUtils {
                factorial: vec![ModInt::from(1), ModInt::from(1)],
                factorial_inv: vec![ModInt::from(1), ModInt::from(1)],
                inv: vec![ModInt::from(0), ModInt::from(1)],
            }
        }

        // when MODULO is prime
        pub fn binom_coef(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }

            let len = self.factorial.len();
            if len < n + 1 {
                for i in len..(n + 1) {
                    let prev = *self.factorial.last().unwrap();
                    self.factorial.push(prev * ModInt::from(i));

                    let inv_i = -self.inv[MODULO % i] * ModInt::from(MODULO / i);
                    self.inv.push(inv_i);

                    let prev = *self.factorial_inv.last().unwrap();
                    self.factorial_inv.push(prev * self.inv[i]);
                }
            }
            self.factorial[n] * self.factorial_inv[k] * self.factorial_inv[n - k]
        }
    }
}
*/

fn main() {
    let exe = "/tmp/bin16E48AD6";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";