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;

typedef long long ll;

const int mx=1e6+7;
const int mod=1e9+7;

int phi(int n) {
	int result=n;
	for (int i=2; i*i<=n; i++) {
		if(n%i==0) result-=result/i;
		while(n%i==0) n/=i;
	}
	if(n>1) result-=result/n;
	return result;
}

// (a^b)%m
ll exp(ll a, ll b, ll m) {
	ll r=1;
	while(b) {
		if(b%2) r=(r*a)%m;
		a=(a*a)%m;
		b/=2;
	}
	return r;
}

// a^-1 %m, any m
ll inv(ll a, ll m) {
	return exp(a, phi(m)-1, m);
}

// a^-1 %m, prime m
ll invp(ll a, ll m) {
	return exp(a, m-2, m);
}

// (a*b)%m
ll mul(ll a, ll b, ll m) {
	ll x=0, y=a%m;
	while(b>0) {
		if(b%2) x=(x+y)%m;
		y=(y*2)%m;
		b/=2;
	}
  return x%m;
}

// (a+b)%m
ll add(ll a, ll b, ll m) {
	return (a+b)%m;
}

ll fact[mx], binv[mx];

ll combi(int n, int x, ll m) {
	ll p=fact[n], q=fact[x], r=fact[n-x];
	ll ret=p;
	ret=(ret*invp(q,m))%m;
	ret=(ret*invp(r,m))%m;
	return ret;
}

bool isprime(int n) {
	if(n==1) return false;
	for (int i=2; i*i<=n; i++)
		if(n%i==0) return false;
	return true;
}

int gcd(int a, int b) {
	if(!b) return a;
	else return gcd(b,a%b);
}

ll eval(int R, int C) {
	//  C(R+1,1) + ... + C(R+C,C)
	ll ret=0, cur=1;
	for (int t=1; t<=C+1; t++) {
		cur=(cur*(R+t))%mod;
		cur=(cur*binv[t])%mod;
		ret=(ret+cur)%mod;
	}
	return ret;
}

int main() {
	fact[0]=1;
	for (int i=1; i<mx; i++)
		fact[i]=(fact[i-1]*i)%mod;
	for (int i=1; i<mx; i++)
		binv[i]=invp(i,mod);
	
	int r1,c1,r2,c2;
	cin>>r1>>c1>>r2>>c2;
	cout<<(eval(r2,c2)+mod-eval(r2,c1-1)+mod-eval(r1-1,c2)+eval(r1-1,c1-1))%mod<<"\n";
	return 0;
}