## Alien Flowers

### 実装

#include <iostream>
#include <vector>
#include <cassert>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
typedef long long ll;
using namespace std;
const int mod = 1e9+7;
ll inv(ll x) { // O(logn)
assert (0 < x and x < mod);
ll y = 1;
for (int i = 0; (1 << i) <= mod - 2; ++ i) {
if ((mod - 2) & (1 << i)) {
y = y * x % mod;
}
x = x * x % mod;
}
return y;
}
ll combination(ll n, ll r) { // O(nlogn), O(1)
assert (0 <= n and 0 <= r or r <= n);
static vector<ll> fact(1,1);
static vector<ll> ifact(1,1);
if (not (n < fact.size())) {
int l = fact.size();
fact.resize(n + 1);
ifact.resize(n + 1);
repeat_from (i,l,n+1) {
fact[i] = fact[i-1] * i % mod;
ifact[i] = inv(fact[i]);
}
}
r = min(r, n - r);
return fact[n] * ifact[n-r] % mod * ifact[r] % mod;
}

ll distribute_strict(int n, int r) { // distribute n same things into r distinguishable groups, each group has positive number of things
assert (n >= r);
return combination((n-r)+r-1,r-1);
}
ll starts_with_r(int rr, int rb, int bb, int br) {
if (not (rb == br or rb == br+1)) return 0;
if (rb == 0 and br == 0) return bb == 0 ? 1 : 0;
ll r = distribute_strict(1 + rr + br, 1 + br);
ll b = distribute_strict(    bb + rb,     rb);
return r * b % mod;
}
int main() {
int a, b, c, d; cin >> a >> b >> c >> d;
cout << (starts_with_r(a,b,c,d) + starts_with_r(c,d,a,b)) % mod << endl;
}