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: Time Limit Exceeded)

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

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

ll mod_inverse(ll a,ll m){
	ll x,y;
	extgcd(a,m,x,y);
	return (m+x%m)%m;
}

ll fact[2000005];

ll mod_fact(ll n,ll p,ll& e){
	e=0;
	if(n==0)return 1;
	ll res=mod_fact(n/p,p,e);
	e+=n/p;
	if(n/p%2!=0){
		return res*(p-fact[n%p])%p;
	}
	return res*fact[n%p]%p;
}

ll mod_comb(ll n,ll k,ll p){
	if(n<0 || k<0 || n<k)return 0;
	ll e1,e2,e3;
	ll a1=mod_fact(n,p,e1),a2=mod_fact(k,p,e2),a3=mod_fact(n-k,p,e3);
	if(e1>e2+e3)return 0;
	return a1*mod_inverse(a2*a3%p,p)%p;
}



ll solve(ll x,ll y){
	if(x==0 || y==0)return 0;
	ll r1=2,r2=1;
	ll u1=2,u2=1;
	ll sum=2;
	ll ans=2;
	for(int i=2;i+1<x+y;i++){
		sum=sum*2LL%MOD;
		if(i<=x){
			sum+=1LL;
			sum%=MOD;
			r1++;
		}else{
			sum+=MOD-mod_comb(r1,r2,MOD);
			sum%=MOD;
			r1++;
			r2++;
		}
		if(i<=y){
			sum+=1LL;
			sum%=MOD;
			u1++;
		}else{
			sum+=MOD-mod_comb(u1,u2,MOD);
			sum%=MOD;
			u1++;
			u2++;
		}
		ans+=sum;
		ans%=MOD;
		//printf("%lld\n",sum);
	}
	ans+=mod_comb(x+y,x,MOD);
	ans%=MOD;
	//printf("%d %d %lld\n",x,y,ans);
	return ans;
}

int main(void){
	fact[0]=1;
	for(ll i=1;i<=2000003;i++){
		fact[i]=fact[i-1]*i%MOD;
	}
	int r1,r2;
	int c1,c2;
	scanf("%d%d",&r1,&c1);
	scanf("%d%d",&r2,&c2);
	printf("%lld\n",(solve(r2,c2)-solve(r1-1,c2)-solve(r2,c1-1)+solve(r1-1,c1-1)+MOD+MOD)%MOD);
	return 0;
}