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: Accepted)

#include<bits/stdc++.h>
using namespace std;
#define int long long 
typedef long long ll;
typedef pair<int,int>pi;
const int MAXN=2000005;
const int MOD=1000000007;

#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DEC(i,a,b) for(int i=(a);i>=(b);i--)
#define fst first
#define snd second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
#define db(x) cerr<<#x<<" = "<<x<<"\n"
#define LOW(v,x) (lower_bound(all(v),(x))-(v).begin())
#define UP(v,x) (upper_bound(all(v),(x))-(v).begin())

ll qmult(ll X, ll Y, ll M) {
	return X * Y % M;
}

ll qexp(ll A, ll B, ll M) {
	if (B == 0) return 1; 
	ll half = qexp(A, B/2, M); 
	half = qmult(half, half, M);
	half %= M;
	if (B%2==1) half *= A%M;
	return half%M;
}

int f[MAXN], invf[MAXN], r1, r2, c1, c2; 

int g(int N, int M){
	int ans=0;
	FOR(i,0,N){
		int tmp=f[M+i+1];
		tmp*=invf[M];tmp%=MOD;
		tmp*=invf[i+1];tmp%=MOD;
		ans+=tmp;ans%=MOD;
	}
	return ans;
}
main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> r1 >> c1 >> r2 >> c2;
	f[0]=1; invf[0]=1;
	FOR(i,1,r2+c2+1) {
		f[i]=(f[i-1]*i)%MOD;
	}
	invf[r2+c2+1]=qexp(f[r2+c2+1],MOD-2,MOD);
	DEC(i,r2+c2,1){
		invf[i]=(invf[i+1]*(i+1))%MOD;
	}
	int res=g(r2,c2);
	res-=g(r1-1,c2); res%=MOD;
	res-=g(r2,c1-1); res%=MOD;
	res+=g(r1-1,c1-1); res%=MOD;
	cout<<(res+MOD)%MOD;
}