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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <complex>

long long int MOD = 1e9+7;
long long int NMAX = 2e6 + 10000;


// calculate x%m for x "properly" for all x
long long int mod(long long int x, long long int m);

long long int mod_inverse(long long int x, long long int m);

// calculate inverse of x in mod m for PRIME m
long long int mod_inverse_Fermat(long long int x, long long int m);

// calculate x^n mod m
long long int fast_power(long long int x, long long int n, long long int m);

// extended euclid gojjohou
long long int euclid_extended(long long int a, long long int b, long long int &x, long long int &y);

int main(){

  // read problem
  long long int r1, c1, r2, c2;
  scanf("%lld%lld%lld%lld", &r1, &c1, &r2, &c2);

  // make factorial table
  std::vector<long long int> fact_table(NMAX), fact_inverse(NMAX);
  fact_table[0] = 1;
  fact_inverse[0] = 1;
  for(long long int i = 1; i < NMAX; i++){
    fact_table[i] = (fact_table[i-1]*i + MOD)%MOD;
    fact_inverse[i] = mod_inverse_Fermat(fact_table[i], MOD);
  }

  // solve problem
  long long int tmp1, tmp2, tmp;
  long long int ans = 0;

  tmp2 = 0;
  for(long long int i = r2; i > r1; i--){
    // tmp1 = r+c1 C r
    tmp1 = (fact_table[i+c1] * fact_inverse[i] + MOD)%MOD;
    tmp1 = (tmp1*fact_inverse[c1] + MOD)%MOD;
    // add tmp1
    ans += tmp1;
    ans = (ans+MOD)%MOD;
    // tmp2 += c2-c1 +r2-i C r2-i+1
    tmp = (fact_table[c2-c1+r2-i]*fact_inverse[r2-i+1] + MOD)%MOD;
    tmp = (tmp*fact_inverse[c2-c1-1] + MOD)%MOD;
    tmp2 = (tmp2+tmp+MOD)%MOD;
    // add tmp1*tmp2
    tmp = (tmp1*tmp2 + MOD)%MOD;
    ans += tmp;
    ans = (ans+MOD)%MOD;
  }

  // add f(r1, c1)
  tmp1 = (fact_table[r1+c1] * fact_inverse[r1] + MOD)%MOD;
  tmp1 = (tmp1*fact_inverse[c1] + MOD)%MOD;
  ans += tmp1;
  ans = (ans+MOD)%MOD;

  tmp2 = 0;
  for(long long int i = c2; i > c1; i--){
    // tmp1 = r1+i C r1
    tmp1 = (fact_table[i+r1]*fact_inverse[r1] + MOD)%MOD;
    tmp1 = (tmp1*fact_inverse[i] + MOD)%MOD;
    // add tmp1
    ans += tmp1;
    ans = (ans+MOD)%MOD;
    // tmp2 += r2-r1 + c2-i C c2-i+1
    tmp = (fact_table[r2-r1 + c2-i]*fact_inverse[c2-i+1] + MOD)%MOD;
    tmp = (tmp*fact_inverse[r2-r1-1] + MOD)%MOD;
    tmp2 = (tmp2+tmp+MOD)%MOD;
    // add tmp1*tmp2
    tmp = (tmp1*tmp2 + MOD)%MOD;
    ans += tmp;
    ans = (ans+MOD)%MOD;
  }

  std::cerr << "Answer: " << std::endl;
  std::cout << ans << std::endl;

  return 0;
}


long long int mod(long long int x, long long int m){
  if(x>0){
    return x%m;
  }
  else if(x==0){
    return 0;
  }
  else if((-x)%m == 0){
    return 0;
  }
  else{
    return m - (-x)%m;
  }
}


long long int euclid_extended(long long int a, long long int b, long long int &x, long long int &y){
  long long int d = a;
  if(b != 0){
    d = euclid_extended(b, a%b, y, x);
    y -= (a/b)*x;
  }
  else{
    x = 1;
    y = 0;
  }
  
  return d;
}

long long int mod_inverse(long long int x, long long int m){
  long long int tmp, x_inv, gcd_xm;
  gcd_xm = euclid_extended(x, m, x_inv, tmp);
  // if the inverse is calculate properly
  if(gcd_xm == 1){
    return mod(x_inv, m);
  }
  else{
    //std::cerr << "Error in mod_inverse: there is no inverse of x in mod m" << std::endl;
    return 0;
  }
}

long long int mod_inverse_Fermat(long long int x, long long int m){
  return fast_power(x, m-2, m);
}

long long int fast_power(long long int x, long long int n, long long int m){
  long long int ans = 1;
  
  while(n > 0){
    if(n&1){
      ans = ans * x;
      ans = mod(ans, m);
    }
    x = x*x;
    x = mod(x, m);
    n = n>>1;
  }
  
  return ans;
}