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)

/*
これを入れて実行
g++ code.cpp
./a.out
 */
 
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <unordered_map>
#include <cmath>
#include <math.h>
#include <tuple>
#include <iomanip>
#include <bitset>
 
using namespace std;
typedef long long ll;
typedef long double ld;
 
int dy4[4] = {-1, 0, +1, 0};
int dx4[4] = {0, +1, 0, -1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};
 
const long long INF = 1LL << 60;
const ll MOD = 1e9 + 7;
 
bool greaterSecond(const pair<int, int>& f, const pair<int, int>& s){
    return f.second > s.second;
}
 
ll gcd(ll a, ll b){
	if (b == 0)return a;
	return gcd(b, a % b);
}
 
ll lcm(ll a, ll b){
    return a / gcd(a, b) * b;
}
 
ll nCr(ll n, ll r){
    if(r == 0 || r == n){
        return 1;
    } else if(r == 1){
        return n;
    }
    return (nCr(n - 1, r) + nCr(n - 1, r - 1));
}
 
ll nPr(ll n, ll r){
    r = n - r;
    ll ret = 1;
    for (ll i = n; i >= r + 1; i--) ret *= i;
    return ret;
}
 
//-----------------------ここから-----------
ll factorial[2000100];
ll invfactorial[2000100];

ll extGCD(ll a, ll b, ll &x, ll &y){
	if (b == 0){
		x = 1;
		y = 0;
		return a;
	}
 
	ll d = extGCD(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

ll nCrM(ll n, ll r){
	ll ret = factorial[n];
	ret *= invfactorial[n - r];
	ret %= MOD;
	ret *= invfactorial[r];
	ret %= MOD; 
	return ret;
}
int main(void){
    factorial[0] = 1;

    for (int i = 1; i < 2000100; i++){
        factorial[i] = (factorial[i - 1] * i) % MOD;
    }
    for (int i = 0; i < 2000100; i++){
        ll x, y;
        ll g = extGCD(factorial[i], MOD, x, y);
        while (x < 0) x += MOD;
        x %= MOD;
        invfactorial[i] = x;
    }

    ll r1, c1, r2, c2;
    cin >> r1 >> c1 >> r2 >> c2;

    ll total = 0;

    for(ll i = 0; i <= r2; i++){
        total += nCrM(c2 + i, i);
        total %= MOD;
    }
    
    for(ll i = 0; i <= c2; i++){
        total += nCrM(r2 + i, i);
        total %= MOD;
    }

    ll minus = 0;
    for(ll i = 0; i < r1; i++){
        minus += nCrM(c1 + i, i);
        minus %= MOD;
    }
    for(ll i = 0; i < c1; i++){
        minus += nCrM(r1 + i, i);
        minus %= MOD;
    }

    cout << total - minus << endl;
}