import sys

read = sys.stdin.read

mod = 10 ** 9 + 7

r1, c1, r2, c2 = map(int, read().split())



def prepare(n, MOD):



    # 1! - n! の計算

    f = 1

    factorials = [1]  # 0!の分

    for m in range(1, n + 1):

        f *= m

        f %= MOD

        factorials.append(f)

    # n!^-1 の計算

    inv = pow(f, MOD - 2, MOD)

    # n!^-1 - 1!^-1 の計算

    invs = [1] * (n + 1)

    invs[n] = inv

    for m in range(n, 1, -1):

        inv *= m

        inv %= MOD

        invs[m - 1] = inv



    return factorials, invs





fac, finv = prepare(2 * 10**6 + 10, mod)





def comb(n, k, mod=mod, fac=fac, finv=finv):

    '''

    二項係数の計算



    Parameters

    n : int

        元集合

    k : int

        元集合から選択する数

    mod : int

        あまり

    fac : list

        階乗のリスト

    finv : list

        逆元のリスト



    Returns

    c : int

        nCkの組み合わせの数

    '''

    if n < k:

        return 0

    if n < 0 or k < 0:

        return 0

    return fac[n] * (finv[k] * finv[n - k] % mod) % mod





answer = comb(r2 + c2 + 2, r2 + 1) - comb(r1 + c2 + 1, r1) - \

    comb(c1 + r2 + 1, c1) + comb(r1 + c1, r1)

answer %= mod

print(answer)

import numpy as np

import sys

read = sys.stdin.read

r1, c1, r2, c2 = map(int, read().split())

MOD = 10 ** 9 + 7





def cumprod(A, MOD=MOD):

    L = len(A)

    Lsq = int(L**.5 + 1)

    A = np.resize(A, Lsq**2).reshape(Lsq, Lsq)

    for n in range(1, Lsq):

        A[:, n] *= A[:, n - 1]

        A[:, n] %= MOD

    for n in range(1, Lsq):

        A[n] *= A[n - 1, -1]

        A[n] %= MOD

    return A.ravel()[:L]





def make_fact(U, MOD=MOD):

    x = np.arange(U, dtype=np.int64)

    x[0] = 1

    fact = cumprod(x, MOD)

    x = np.arange(U, 0, -1, dtype=np.int64)

    x[0] = pow(int(fact[-1]), MOD - 2, MOD)

    fact_inv = cumprod(x, MOD)[::-1]

    fact.flags.writeable = False

    fact_inv.flags.writeable = False

    return fact, fact_inv





fac, finv = make_fact(2 * 10**6 + 10, MOD)





def comb(n, k, mod=MOD, fac=fac, finv=finv):

    if n < k:

        return 0

    if n < 0 or k < 0:

        return 0

    return fac[n] * (finv[k] * finv[n - k] % mod) % mod





answer = comb(r2 + c2 + 2, r2 + 1) - comb(r1 + c2 + 1, r1) - \

    comb(c1 + r2 + 1, c1) + comb(r1 + c1, r1)

answer %= MOD

print(answer)

import sys

read = sys.stdin.read
mod = 10**9 + 7
r1, c1, r2, c2 = map(int, read().split())


def prepare(n, MOD):
    # 1! - n! の計算
    f = 1
    factorials = [1]  # 0!の分
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials.append(f)
    # n!^-1 の計算
    inv = pow(f, MOD - 2, MOD)
    # n!^-1 - 1!^-1 の計算
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv
    return factorials, invs


fac, finv = prepare(2 * 10**6 + 10, mod)


def comb(n, k, mod=mod, fac=fac, finv=finv):
    """
    二項係数の計算
    Parameters
    n : int
        元集合
    k : int
        元集合から選択する数
    mod : int
        あまり
    fac : list
        階乗のリスト
    finv : list
        逆元のリスト
    Returns
    c : int
        nCkの組み合わせの数
    """
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod


answer = (
    comb(r2 + c2 + 2, r2 + 1)
    - comb(r1 + c2 + 1, r1)
    - comb(c1 + r2 + 1, c1)
    + comb(r1 + c1, r1)
)
answer %= mod
print(answer)

import numpy as np
import sys

read = sys.stdin.read
r1, c1, r2, c2 = map(int, read().split())
MOD = 10**9 + 7


def cumprod(A, MOD=MOD):
    L = len(A)
    Lsq = int(L**0.5 + 1)
    A = np.resize(A, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        A[:, n] *= A[:, n - 1]
        A[:, n] %= MOD
    for n in range(1, Lsq):
        A[n] *= A[n - 1, -1]
        A[n] %= MOD
    return A.ravel()[:L]


def make_fact(U, MOD=MOD):
    x = np.arange(U, dtype=np.int64)
    x[0] = 1
    fact = cumprod(x, MOD)
    x = np.arange(U, 0, -1, dtype=np.int64)
    x[0] = pow(int(fact[-1]), MOD - 2, MOD)
    fact_inv = cumprod(x, MOD)[::-1]
    fact.flags.writeable = False
    fact_inv.flags.writeable = False
    return fact, fact_inv


fac, finv = make_fact(2 * 10**6 + 10, MOD)


def comb(n, k, mod=MOD, fac=fac, finv=finv):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod


answer = (
    comb(r2 + c2 + 2, r2 + 1)
    - comb(r1 + c2 + 1, r1)
    - comb(c1 + r2 + 1, c1)
    + comb(r1 + c1, r1)
)
answer %= MOD
print(answer)

+import numpy as np -mod = 10**9 + 7 +MOD = 10**9 + 7 -def prepare(n, MOD): -    # 1! - n! の計算 -    f = 1 -    factorials = [1]  # 0!の分 -    for m in range(1, n + 1): -        f *= m -        f %= MOD -        factorials.append(f) -    # n!^-1 の計算 -    inv = pow(f, MOD - 2, MOD) -    # n!^-1 - 1!^-1 の計算 -    invs = [1] * (n + 1) -    invs[n] = inv -    for m in range(n, 1, -1): -        inv *= m -        inv %= MOD -        invs[m - 1] = inv -    return factorials, invs +def cumprod(A, MOD=MOD): +    L = len(A) +    Lsq = int(L**0.5 + 1) +    A = np.resize(A, Lsq**2).reshape(Lsq, Lsq) +    for n in range(1, Lsq): +        A[:, n] *= A[:, n - 1] +        A[:, n] %= MOD +    for n in range(1, Lsq): +        A[n] *= A[n - 1, -1] +        A[n] %= MOD +    return A.ravel()[:L] -fac, finv = prepare(2 * 10**6 + 10, mod) +def make_fact(U, MOD=MOD): +    x = np.arange(U, dtype=np.int64) +    x[0] = 1 +    fact = cumprod(x, MOD) +    x = np.arange(U, 0, -1, dtype=np.int64) +    x[0] = pow(int(fact[-1]), MOD - 2, MOD) +    fact_inv = cumprod(x, MOD)[::-1] +    fact.flags.writeable = False +    fact_inv.flags.writeable = False +    return fact, fact_inv -def comb(n, k, mod=mod, fac=fac, finv=finv): -    """ -    二項係数の計算 -    Parameters -    n : int -        元集合 -    k : int -        元集合から選択する数 -    mod : int -        あまり -    fac : list -        階乗のリスト -    finv : list -        逆元のリスト -    Returns -    c : int -        nCkの組み合わせの数 -    """ +fac, finv = make_fact(2 * 10**6 + 10, MOD) + + +def comb(n, k, mod=MOD, fac=fac, finv=finv): -answer %= mod +answer %= MOD