// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// to avoid integer overflow
#define int long long
const int MOD = 1e9 + 7;
// To find GCD of a and b
int gcd(int a, int b);
// To compute x raised to power y under
// modulo M
int power(int x, unsigned int y, unsigned int M);
// Function to find modular inverse of
// under modulo M
// Assumption: M is prime
int modInverse(int A, int M)
{
int g = gcd(A, M);
return power(A, M - 2, M);
}
// To compute x^y under modulo m
int power(int x, unsigned int y, unsigned int M)
{
if (y == 0)
return 1;
int p = power(x, y / 2, M) % M;
p = (p * p) % M;
return (y % 2 == 0) ? p : (x * p) % M;
}
// Function to return gcd of a and b
int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to Count number of ways
// of taking 3 red balls and 3 blue
// balls so that 3 balls are from box1
// and 3 balls are from box 2
int countWays(int A, int B, int C, int D)
{
// Precomputation array storing
// factorials MOD 1e9 + 7
int fact[100001];
// Initialize the base elements
fact[1] = 1, fact[0] = 1;
// Filling factorial table
for (int i = 2; i <= 100000; i++) {
fact[i] = (fact[i - 1] * i) % MOD;
}
// case 1 multiplying A!/(A-2)!
int ans1
= (fact[A] * modInverse(fact[A - 2], MOD)) % MOD;
// case 1 multiplying B!/(B-1)!
ans1 = (ans1 * fact[B] * modInverse(fact[B - 1], MOD))
% MOD;
// case 1 taking into account C!/(C-1)!
ans1 = (ans1 * fact[C] * modInverse(fact[C - 1], MOD))
% MOD;
// case 1 taking into account D!/(D-1)!
ans1 = (ans1 * fact[D] * modInverse(fact[D - 2], MOD))
% MOD;
// case 1 taking into account / 4
ans1 = (ans1 * modInverse(4, MOD)) % MOD;
// case 2 multiplying A!/(A-3)!
int ans2
= (fact[A] * modInverse(fact[A - 3], MOD)) % MOD;
// case 2 multiplying D!/(D-3)!
ans2 = (ans2 * fact[D] * modInverse(fact[D - 3], MOD))
% MOD;
// case 2 taking into account / 36
ans2 = (ans2 * modInverse(36, MOD)) % MOD;
// case 3 multiplying B!/(B-3)!
int ans3
= (fact[B] * modInverse(fact[B - 3], MOD)) % MOD;
// case 3 multiplying C!/(C-3)!
ans3 = (ans3 * fact[C] * modInverse(fact[C - 3], MOD))
% MOD;
// case 3 taking into account / 36
ans3 = (ans3 * modInverse(36, MOD)) % MOD;
// case 4 multiplying A!/(A-1)!
int ans4
= (fact[A] * modInverse(fact[A - 1], MOD)) % MOD;
// case 4 multiplying B!/(B-2)!
ans4 = (ans4 * fact[B] * modInverse(fact[B - 2], MOD))
% MOD;
// case 4 taking into account C!/(C-2)!
ans4 = (ans4 * fact[C] * modInverse(fact[C - 2], MOD))
% MOD;
// case 4 taking into account D!/(D-1)!
ans4 = (ans4 * fact[D] * modInverse(fact[D - 1], MOD))
% MOD;
// case 4 taking into accont / 4
ans4 = (ans4 * modInverse(4, MOD)) % MOD;
// answer
int ans = (ans1 + ans2 + ans3 + ans4) % MOD;
// Returning the answer
return ans;
}
// Driver Code
int32_t main()
{
// Input 1
int A = 4, B = 3, C = 3, D = 4;
// Function Call
cout << countWays(A, B, C, D) << endl;
// Input 2
int A1 = 3, B1 = 3, C1 = 3, D1 = 3;
// Function Call
cout << countWays(A1, B1, C1, D1) << endl;
return 0;
}