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)

use std::vec::Vec;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}

fn read_touple<T: std::str::FromStr + Copy>() -> (T, T, T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 4);
  (v[0], v[1], v[2], v[3])
}

const MOD: usize = 1_000_000_000 + 7;
fn main() {
    let (r1, c1, r2, c2) = read_touple::<usize>();
    let mdc: ModConb = ModConb::new(r2+c2+2);
    println!("{}", (g(&mdc, r2, c2) - g(&mdc, r2, c1-1) - g(&mdc, r1-1, c2) + g(&mdc, r1-1, c1-1)).unwrap());
}

fn g(mdc: &ModConb, r: usize, c: usize) -> Mod {
  mdc.get(r+c+2, c+1) - Mod::new_one()
}

use std::cmp::Ord;
use std::cmp::*;
use std::ops::Add;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Neg;
use std::ops::Sub;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
struct Mod {
  val: usize,
}

// 和を定義
impl Add for Mod {
  type Output = Mod;
  // O(1)
  fn add(self, other: Mod) -> Mod {
    Mod {
      val: (self.val + other.val) % MOD,
    }
  }
}

// 差を定義
impl Sub for Mod {
  type Output = Mod;

  // O(1)
  fn sub(self, other: Mod) -> Mod {
    Mod {
      val: (self.val  + MOD - other.val) % MOD,
    }
  }
}

// 積を定義
impl Mul for Mod {
  type Output = Mod;

  // O(1)
  fn mul(self, other: Mod) -> Mod {
    Mod {
      val: (self.val * other.val) % MOD,
    }
  }
}

// 加法単位元
impl Neg for Mod {
  type Output = Mod;

  // O(1)
  fn neg(self) -> Mod {
    Mod {
      val: MOD - self.val,
    }
  }
}

// 逆元を定義
// フェルマーの小定理により実装
impl Div for Mod {
  type Output = Mod;

  //O(logN)
  fn div(self, other: Mod) -> Mod {
    self * other.inv()
  }
}

impl Mod {
  // コンストラクター
  fn new(n: usize) -> Mod {
    Mod { val: n % MOD }
  }

  // 加法単位元
  fn new_zero() -> Mod {
    Mod { val: 0 }
  }

  // 乗法単位元
  fn new_one() -> Mod {
    Mod { val: 1 }
  }

  // 加法逆元
  // 上記にて定義

  // 乗法逆元
  fn inv(self) -> Mod {
    if self.val == 0 {
      panic!("zero divide");
    }
    self.pow(MOD - 2)
  }

  // 累乗を定義
  // O(logN)
  fn pow(self, n: usize) -> Mod {
    let mut res = 1;
    let mut a = self.unwrap();
    let mut n = n;

    while n > 0 {
      if n % 2 == 0 {
        a = a * a;
        n /= 2;
      } else {
        res = res * a;
        a = a * a;
        n /= 2;
      }
      res %= MOD;
      a %= MOD;
    }
    Mod::new(res)
  }

  // 最大公約数
  // O(logN)
  fn gcd(self, other: Mod) -> usize {
    let mut x = self.val;
    let mut y = other.val;
    while y != 0 {
      let t = y;
      y = x % y;
      x = t;
    }
    x
  }

  // 階乗
  // O(N)
  fn fact(self) -> Mod {
    let mut res = 1;
    for i in 1..self.val + 1 {
      res *= i;
      res %= MOD;
    }

    Mod::new(res)
  }

  // 順列
  fn perm(self, other: Mod) -> Mod {
    let mut res = Mod::new_one();
    for x in (self.val - other.val + 1)..self.val + 1 {
      res = res * Mod::new(x);
    }

    res
  }

  // 組み合わせ O(N)
  fn conb(self, other: Mod) -> Mod {
    if self < other {
      return Mod::new_zero();
    }
    self.fact() / (other.fact() * (self - other).fact())
  }
  fn unwrap(self) -> usize {
    self.val % MOD
  }
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
struct ModConb {
  fact: Vec<Mod>,
  inv_fact: Vec<Mod>,
  n: usize,
}

impl ModConb {
  // O(N)
  fn new(n: usize) -> ModConb {
    let mut fact = vec![Mod::new_one(); n + 1];
    let mut inv_fact = vec![Mod::new_one(); n + 1];
    for i in 1..(n + 1) {
      fact[i] = fact[i - 1] * Mod::new(i);
      inv_fact[i] = inv_fact[i - 1] / Mod::new(i);
    }

    ModConb {
      fact: fact,
      inv_fact: inv_fact,
      n: n + 1,
    }
  }
  // O(1)
  fn get(&self, n: usize, r: usize) -> Mod {
    if r <= n {
      self.fact[n] * self.inv_fact[r] * self.inv_fact[n - r]
    } else {
      Mod::new_zero()
    }
  }
}