Problem:
野球観戦
先日，あなたの競技プログラミング仲間であるOさんは野球観戦に出かけた．
観戦した試合は，チームXとチームYの合計 4 試合の対戦だったが，一方的な展開となり，全試合でチームXが勝利した．
しかも，4 試合を通じたXの合計得点は 33 点だったのに対し，Yの合計得点はたったの 4 点だった．
あまりに一方的な内容のため，試合内容への興味が薄れてしまったOさんは，試合を観戦している間も競技プログラミングの作問ネタをついつい考えてしまっていた．
その甲斐もあって，Oさんは以下のような問題を思いついた．
野球チームXとYが対戦し，Xが勝った試合数，Yが勝った試合数，引き分けの試合数がそれぞれ
A, B, C
試合だったとする．
また，全
A+B+C
試合を通じたX，Yの総得点は，それぞれ
S
X
点，
S
Y
点だったとする．得点は全て 0 以上の整数である．
XとYが合計
A+B+C
試合対戦したとき，全試合の結果としてこのような条件を満たす各試合のスコアの並びは何通り有り得るだろうか？
ここで，ある試合で勝利する条件は，その試合における得点が，相手チームの得点よりも多いことであり，等しい場合は引き分けとなる．
また，各試合のスコアの並びを求める際，対戦した全試合の結果を比べた時，XとYの得点の組み合わせが同じでも，その順序が異なれば区別する必要がある．
例えば，XとYが 2 試合対戦した結果，共に 1 勝ずつし，引き分けが無く，XとYの総得点が共に 1 点ずつだったとする．
この場合，各試合におけるX，Yの得点を (Xの得点) - (Yの得点) という表記で表し，合計 2 試合の結果を並べると，以下の 2 通りが与えられた条件を満たす．
1 - 0, 0 - 1
0 - 1, 1 - 0
試合の順序を区別して数えるので，これらは区別される．
あなたにはこの答えを求めるプログラムを作って欲しい．
ただし，求める数はとても大きい数になり得るため，求める数を 1,000,000,007 で割った余りを答えるようにして欲しい．
Input
入力は複数のデータセットからなる． 
各データセットは 1 行からなり，次の形式で表される．
A
B
C
S
X
S
Y
ここで，
A
はチームXの勝利数，
B
はチームYの勝利数，
C
は引き分けの試合数，
S
X
はチームXの総得点，
S
Y
はチームYの総得点を表す．
A, B, C, S
X
, S
Y
は全て 0 以上 1,000,000 以下の整数であり，かつ
0 < A+B+C
を満たす．
入力の終わりは，5 つのゼロからなる行で示される．
Output
各データセットについて，与えられた条件を満たす場合の数を 1,000,000,007 で割った余りのみからなる行を 1 行で出力せよ．
Sample Input
1 1 0 1 1
0 0 2 3 2
4 0 0 33 4
5 4 2 20 25
4726 87361 2742 23497 162843
328324 420923 12782 834286 538297
0 0 0 0 0
Output for Sample Input
2
0
114660
512095631
673703234
166259450

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;

ll mod = 1000000007;

ll kai[3000010];
ll inv_kai[3000010];

ll beki(ll x, ll a)
{
	if(x==0) return 0;
	if(a==0) return 1;
	if(a==1) return x;
	ll tmp=beki(x, a/2);
	tmp=tmp*tmp%mod;
	if(a%2==0) return tmp;
	else return tmp*x%mod;
}

ll inv(ll x)
{
	return beki(x, mod-2);
}

ll cb(ll s, ll t)
{
	if(s==t) return 1;
	if(t==-1) return 0;
	ll tmp=kai[(int)s];
	tmp=(tmp*inv_kai[(int)t])%mod;
	return tmp*inv_kai[(int)s-(int)t]%mod;
}

int main() {
	kai[0]=1;
	inv_kai[0]=1;
	for(int i=1; i<=3000005; i++)
	{
		kai[i]=kai[i-1]*(ll)i%mod;
		inv_kai[i]=inv(kai[i]);
	}
	//cout << "aaaaaaa" << cb(0, 0) << endl;
	while (true) {
		ll a, b, c, sx, sy;
		cin >> a >> b >> c >> sx >> sy;
		if(a+b+c==0) break;

		ll ans=0;
		for(ll x=a; x<=sx; x++)
		{
			ll y=sy-(sx-x);
			if(y>=b)
			{
				ll tmp=1;
				tmp=(tmp*cb(x-1, a-1))%mod;
				tmp=(tmp*cb(y-1, b-1))%mod;
				tmp=(tmp*cb(sx-x+a+b+c-1, a+b+c-1))%mod;
				ans=(ans+tmp)%mod;
			}
		}
		ans=(ans*cb(a+b+c, a))%mod;
		cout << ans*cb(b+c, b)%mod << endl;
	}
}
accuracy: 1
time_ms: 1680
memory_kb: 50216
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define each(i,a) for (auto&& i : a)
#define FOR(i,a,b) for (ll i=(a),__last_##i=(b);i<__last_##i;i++)
#define RFOR(i,a,b) for (ll i=(b)-1,__last_##i=(a);i>=__last_##i;i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,0,n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define chmin(x,v) x = min(x, v)
#define chmax(x,v) x = max(x, v)

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template<typename T>
istream& operator>>(istream& is, vector<T>& vec) {
    each(x,vec) is >> x;
    return is;
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
    rep(i,vec.size()) {
        if (i) os << " ";
        os << vec[i];
    }
    return os;
}
template<typename T>
ostream& operator<<(ostream& os, const vector< vector<T> >& vec) {
    rep(i,vec.size()) {
        if (i) os << endl;
        os << vec[i];
    }
    return os;
}
const ll mod = 1000000007;
ll mul(ll a, ll b) {
    return a * b % mod;
}
ll add(ll a, ll b) {
    return (a + b) % mod;
}
ll sub(ll a, ll b) {
    return (a - b + mod) % mod;
}
ll power(ll x, ll n) {
    ll res = 1;
    for (ll i = 1; i <= n; i <<= 1) {
        if (i & n) res = mul(res, x);
        x = mul(x, x);
    }
    return res;
}
ll inv(ll n) {
    return power(n, mod-2);
}
ll divi(ll a, ll b) {
    return mul(a, inv(b));
}
vector<ll> fact;
void init_fact(ll n) {
    fact.assign(n+1, 1);
    FOR(i, 1, fact.size()) {
        fact[i] = mul(fact[i-1], i);
    }
}

ll comb(ll n, ll r) {
    if (r < 0) return 0;
    assert(r >= 0);
    if (r > n) return 0;
    return divi(fact[n], mul(fact[r], fact[n-r]));
}

ll H(ll n, ll r) {
    if (n + r == 0) return 1;
    return comb(n+r-1, n);
}

// f(n, m) := 正整数をm個使ってnを構成する場合の数
ll f(ll n, ll m) {
    if (m < n) return 0;
    return H(m-n, n);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll A, B, C, Sx, Sy;
    init_fact(4000000);
    while (cin >> A >> B >> C >> Sx >> Sy, A || B || C || Sx || Sy) {
        ll ans = 0;
        // Sx - Sy
        rep(a, 0, Sx+1) {
            ll da = 1;
            ll b = a - (Sx - Sy);
            if (b < 0) continue;
            // cout << f(A, a) << " " << f(B, -b) << " " <<
            ans = add(ans, mul(mul(f(A, a), f(B, b)), H(Sx-a, A+B+C)));
        }
        ans = mul(ans, mul(comb(A+B+C, A), comb(B+C, B)));
        cout << ans << endl;
    }
    // cout << f(0, 0) << endl;
    // cout << f(4, 29) << endl;
}
accuracy: 1
time_ms: 2570
memory_kb: 34024
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
#define rep(i,t,n) for(long long i=t;i<n;i++)
#define rep2(i,A) for(auto &i:A)
#define Sort(a) sort(a.begin(),a.end())
#define rSort(a,n,m) sort(a.begin()+n,a.begin()+m+1)
#define Reverse(a) reverse(a.begin(),a.end())
#define rReverse(a,n,m) reverse(a.begin()+n,a.begin()+m+1)
#define MOD1 998244353LL
#define MOD2 1000000007LL
#define sign(i) -1*pow(-1,i)
#define vi(A,N,i)  vector<long long> A(N,i)
#define vd(A,N,i)  vector<double> A(N,i)
#define vc(A,N,i)  vector<char> A(N,i)
#define vs(A,N,i)  vector<string> A(N,i)
#define vb(A,N,i)  vector<bool> A(N,i)
#define vp(A,N,i)  vector<Pair> A(N,{i,i})
#define vvi(A,N,M,i) vector<vector<long long>> A(N,vector<long long>(M,i))
#define vvp(A,N,M,i) vector<vector<Pair>> A(N,vector<Pair>(M,{i,i}))
#define vvd(A,N,M,i) vector<vector<double>> A(N,vector<double>(M,i))
#define vvc(A,N,M,i) vector<vector<char>> A(N,vector<char>(M,i))
#define vvb(A,N,M,i) vector<vector<bool>> A(N,vector<bool>(M,i))
#define vvs(A,N,M,i) vector<vector<string>> A(N,vector<string>(M,i))
#define vvvi(A,N,M,L,i) vector<vector<vector<ll>>> A(N,vector<vector<ll>>(M,vector<ll>(L,i)))
#define vvvs(A,N,M,L,i) vector<vector<vector<string>>> A(N,vector<vector<string>>(M,vector<string>(L,i)))
#define ll long long
#define INF ((1LL<<62)-(1LL<<31))
#define ALL(a) (a).begin(),(a).end()

using VVi=vector<vector<ll>>;
using Pair=pair<ll,ll>;
using graphi=vector<vector<ll>>;
using graphp=vector<vector<Pair>>;
struct Plane{
  ll x;
  ll y;
};
struct Path{
  ll cost;
  ll to;
};
template<typename T>
void CIN(vector<T> &A){
  rep(i,0,(ll)A.size()){
    cin>>A[i];
  }
  return;
}
struct ThreePlane{
  ll x,y,z;
  ThreePlane(ll X=0,ll Y=0,ll Z=0):x(X),y(Y),z(Z){}
  bool operator<(const ThreePlane& other) const {
    return x<other.x;
  }
  bool operator<=(const ThreePlane& other) const {
    return x<=other.x;
  }
  bool operator>(const ThreePlane& other) const {
    return x>other.x;
  }
  bool operator>=(const ThreePlane& other) const {
    return x>=other.x;
  }
};
struct FourPlane{
  ll dist;
  ll x;
  ll y;
  ll stat;
};
struct Fraction{
    ll p,q,r;
    Fraction(ll P = 0, ll Q = 1,ll R = 1): p(P), q(Q),r(R){}
    bool operator<(const Fraction &other)const{
      if(p*other.q != other.p*q){
        return p*other.q < other.p*q;
      }else{
        return r>other.r;
      }
        
    }
};

ll GCD(ll a,ll b){
  if(b==0)return a;
  return GCD(b,a%b);
}
pair<long long, long long> extGCD(long long a, long long b) {// ax+by=1 solver
  if (b == 0) return make_pair(1, 0);
  long long x,y;
  tie(y,x)=extGCD(b,a%b);
  y-=a/b*x;
  return make_pair(x,y);
}
ll SQRT(ll a){
  ll low,high,mid;
  low=0;
  high=1LL<<31;
  while(high-low!=1){
    mid=(low+high)/2;
    if(mid*mid<=a){
      low=mid;
    }else{
      high=mid;
    }
  }
  return low;
}
string strmin(string x,string y){
  ll minlength=min((int)x.size(),(int)y.size());
  rep(i,0,minlength){
    if(x[i]>y[i])return y;
    if(x[i]<y[i])return x;
  }
  if((int)x.size()>(int)y.size())return y;
  return x;
}
ll LCS(string x,string y){
  ll xsize=(ll)x.size();
  ll ysize=(ll)y.size();
  vvi(dp,xsize+1,ysize+1,0);
  rep(i,1,xsize+1){
    rep(j,1,ysize+1){
      if(x[i-1]==y[j-1])dp[i][j]=max(max(dp[i-1][j-1]+1,dp[i][j-1]),dp[i-1][j]);
      else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
    }
  }
  return dp[xsize][ysize];
}
ll Factorial(ll n,ll mod){
  ll a=1;
  if(n>=mod)return 0;
  rep(i,1,n+1){
    a*=i;
    a%=mod;
  }
  return a;
}
ll Combination(ll n,ll k,ll mod){
  if(n<k)return 0;
  ll a=Factorial(n,mod);
  ll b=inv_mod(Factorial(k,mod),mod);
  ll c=inv_mod(Factorial(n-k,mod),mod);
  a*=b;
  a%=mod;
  a*=c;
  a%=mod;
  return a;
}
vector<pair<char,long long>> RLE(string x,char s=' ',long long a=0,vector<pair<char,long long>> res={}){
  for(auto i:x){
    if(s==i){
      a++;
    }else{
      if(s!=' ')res.push_back({s,a});
      s=i,a=1;
    }
  }
  res.push_back({s,a});
  return res;
}
vector<pair<ll,long long>> RLEll(vector<ll> x,ll s=-INF,long long a=0,vector<pair<ll,long long>> res={}){
  for(auto i:x){
    if(s==i){
      a++;
    }else{
      if(s!=-INF)res.push_back({s,a});
      s=i,a=1;
    }
  }
  res.push_back({s,a});
  return res;
}
vector<ll> cu1d(vector<ll> A){
  ll cu1=A.size();
  vector<ll> res(cu1+1,0);
  rep(i,0,cu1)res[i+1]=A[i];
  rep(i,1,cu1+1)res[i]+=res[i-1];
  return res;
}
vector<vector<ll>> cu2d(vector<vector<ll>> A){
  ll cu1=A.size(),cu2=A[0].size();
  vector<vector<ll>> res(cu1+1,vector<ll>(cu2+1,0));
  rep(i,0,cu1)rep(j,0,cu2)res[i+1][j+1]=A[i][j];
  rep(i,1,cu1+1)rep(j,0,cu2+1)res[i][j]+=res[i-1][j];
  rep(j,0,cu1+1)rep(i,1,cu2+1)res[j][i]+=res[j][i-1];
  return res;
}
ll LIS(vector<ll> A){
  ll a=(ll)A.size();
  vector<ll> result(a,INF);
  ll answer=0;
  rep(i,0,a){
    ll ok=-1;
    ll ng=a;
    while(ng-ok!=1){
      ll mid=(ok+ng)/2;
      if(A[i]<=result[mid])ng=mid;
      else ok=mid;
    }
    result[ok+1]=A[i];
    answer=max(answer,ok+2);
  }
  return answer;
}
vector<ll> zaatu(vector<ll> A){
  vector<ll> B=A;
  Sort(B);
  B.erase(unique(ALL(B)),end(B));
  vector<ll> res;
  transform(ALL(A),back_inserter(res),[&](const ll &x){
    return lower_bound(ALL(B),x)-begin(B);
  });
  return res;
}
vector<string> trim(vector<string> A){
  bool frag=0;
  char s='#';
  ll h=(ll)A.size();
  ll w=(ll)A[0].size();
  ll a=-1,b=h,c=-1,d=w;
  for(ll i=0;i<h;i++){
    for(ll j=0;j<w;j++)if(A[i][j]==s)frag=1;
    if(frag)break;
    a=i;
  }
  frag=0;
  for(ll i=h-1;i>=0;i--){
    for(ll j=0;j<w;j++)if(A[i][j]==s)frag=1;
    if(frag)break;
    b=i;
  }
  frag=0;
  for(ll i=0;i<w;i++){
    for(ll j=0;j<h;j++)if(A[j][i]==s)frag=1;
    if(frag)break;
    c=i;
  }
  frag=0;
  for(ll i=w-1;i>=0;i--){
    for(ll j=0;j<h;j++)if(A[j][i]==s)frag=1;
    if(frag)break;
    d=i;
  }
  vector<string> B(b-a-1,"");
  for(ll i=a+1;i<b;i++)for(ll j=c+1;j<d;j++)B[i-a-1]+=A[i][j];
  return B;
}
char to_upper(char &s){
  if('a'<=s){
    s-=32;
  }
  return s;
}
char to_lower(char &s){
  if(s<='Z'){
    s+=32;
  }
  return s;
}
vector<vector<ll>> Warshall(vector<vector<ll>> A){
  ll a=A.size();
  rep(k,0,a)rep(i,0,a)rep(j,0,a)A[i][j]=min(A[i][j],A[i][k]+A[k][j]);
  return A;
}

ll bit_ceil(ll n) {
    ll x = 1;
    while (x < (ll)(n)) x *= 2;
    return x;
}
int countr_zero(ll n){
    ll res=0;
    while(n%2==0){
        res++;
        n>>=1;
    }
    return res;
}
vector<string> make_grid(ll H,ll W,char filler='#'){
  vector<string> res(H+2);
  string st="";
  rep(i,0,W+2)st+=filler;
  res[0]=res[H+1]=st;
  string st2;
  rep(i,1,H+1){
    cin>>st2;
    res[i]=filler+st2+filler;
  }
  return res;
}
struct binC{
    long long mod;
    vector<long long>fact;
    vector<long long>inv;
    vector<long long>fact_inv;
    binC(long long mod):mod(mod){
        fact.resize(5050505);
        inv.resize(5050505);
        fact_inv.resize(5050505);
        fact[0]=fact[1]=1;
        fact_inv[0]=fact_inv[1]=1;
        inv[1]=1;
        rep(i,2,5050505){
            fact[i]=fact[i-1]*i%mod;
            inv[i]=mod-inv[mod%i]*(mod/i)%mod;
            fact_inv[i]=fact_inv[i-1]*inv[i]%mod;
        }
    }
    ll C(ll n,ll k){
        if(k<0||n<k)return 0;
        return fact[n]*(fact_inv[k]*fact_inv[n-k]%mod)%mod;
    }
};
struct rolling_hash {
    vector<ll> data;
    ll size;
    static const ll mod=385870579LL;
    static const ll base=258324359LL;
    ll base_inv=inv_mod(base,mod);
    static ll ie(){return 0LL;}
    static ll operat(ll a,ll b){return (a+b)%mod;}
    segtree<ll,operat,ie>seg;
    vector<ll>ofset;
    vector<ll>power;
    void init(){
        ofset[0]=1LL;
        rep(idx,1,size){
            ofset[idx]=ofset[idx-1]*base_inv;
            ofset[idx]=ofset[idx]%mod;
        }
        power[0]=1LL;
        rep(idx,1,size){
            power[idx]=power[idx-1]*base;
            power[idx]=power[idx]%mod;
        }
    }
    rolling_hash(ll n) : data(n), size(n), seg(n), ofset(n), power(n) {
        init();
        rep(idx,0,size){
            data[idx]=0;
        }
        
    }
    rolling_hash(const string& str) : data(str.size()), size(str.size()), seg(str.size()), ofset(str.size()), power(str.size()) {
        init();
        rep(idx,0,size){
            data[idx]=str[idx];
            seg.set(idx,str[idx]*power[idx]%mod);
        }
        
    }
    rolling_hash(const vector<ll>& vec) : data(vec), size(vec.size()), seg(vec), ofset(vec.size()), power(vec.size()) {
        init();
        rep(idx,0,size){
            data[idx]=vec[idx];
            seg.set(idx,vec[idx]*power[idx]%mod);
        }
    }
    void set(ll i,ll a){
        data[i]=a;
        seg.set(i,a*power[i]%mod);
    }
    ll get(ll idx){
        return data[idx];
    }
    ll value(ll l,ll r){
        return seg.prod(l,r)*ofset[l]%mod;
    }
};
ll inversion(vector<ll>A){
    ll res=0;
    ll siz=0;
    rep(i,0,(ll)A.size())siz=max(siz,A[i]);
    fenwick_tree<ll>FT(siz);
    rep(i,0,A.size()){
        res+=FT.sum(A[i],siz);
        FT.add(A[i],1);
    }
    return res;
}
vector<ll>argsort(vector<ll>&A){
    vector<Pair>B((ll)A.size());
    rep(i,0,(ll)A.size())B[i]={A[i],i};
    stable_sort(B.begin(),B.end());
    vector<ll>res((ll)A.size());
    rep(i,0,(ll)A.size())res[i]=B[i].second;
    return res;
}

//Warshall rep(k,0,a)rep(i,0,a)rep(j,0,a)A[i][j]=min(A[i][j],A[i][k]+A[k][j]);
// long long a,b,c,d,e,f,g,h,ans=0;
// string w,x="",y="",z="";
// char s,t,u;
// bool frag=false,frag1=false,frag2=false;
// vector<ll> X={1,0,-1,0},Y={0,1,0,-1};

int main(){
    binC BINC(MOD2);
    
    vector<long long>fact;
    vector<long long>inv;
    vector<long long>fact_inv;
    fact.resize(5050505);
    inv.resize(5050505);
    fact_inv.resize(5050505);
    fact[0]=fact[1]=1;
    fact_inv[0]=fact_inv[1]=1;
    inv[1]=1;
    rep(i,2,5050505){
        fact[i]=fact[i-1]*i%MOD2;
        inv[i]=MOD2-inv[MOD2%i]*(MOD2/i)%MOD2;
        fact_inv[i]=fact_inv[i-1]*inv[i]%MOD2;
    }
    
    while(1){
        ll ans=0;
        ll A,B,C,X,Y;
        cin>>A>>B>>C>>X>>Y;
        if(A+B+C+X+Y==0)break;
        
        if(A==0){
            swap(A,B);
            swap(X,Y);
        }
        if(A==0){
            if(X!=Y){
                cout<<0<<endl;
            }else{
                ll e=1;
                e*=BINC.C(X+C-1,C-1);
                e%=MOD2;
                ans+=e;
                ans*=fact[A+B+C];
                ans%=MOD2;
                ans*=fact_inv[A];
                ans%=MOD2;
                ans*=fact_inv[B];
                ans%=MOD2;
                ans*=fact_inv[C];
                ans%=MOD2;
                cout<<ans<<endl;
            }
        }
        else if(B==0){
            ll e=1;
            X-=A;
            ll f=X-Y;
            if(f<0)cout<<0<<endl;
            else{
                e*=BINC.C(f+A-1,A-1);
                e%=MOD2;
                e*=BINC.C(Y+A+B+C-1,A+B+C-1);
                e%=MOD2;
                ans+=e;
                ans*=fact[A+B+C];
                ans%=MOD2;
                ans*=fact_inv[A];
                ans%=MOD2;
                ans*=fact_inv[B];
                ans%=MOD2;
                ans*=fact_inv[C];
                ans%=MOD2;
                cout<<ans<<endl;
            }
        }else{
            // cerr<<"A"<<endl;
            rep(i,0,X+1){
                ll e=1;
                if(A>i)continue;
                // cerr<<i<<endl;
                e*=BINC.C(i-1,A-1);
                // cerr<<i-1<<" "<<A-1<<endl;
                e%=MOD2;
                ll f=Y-(X-i);
                e*=BINC.C(f-1,B-1);
                // cerr<<f-1<<" "<<B-1<<endl;
                e%=MOD2;
                
                e*=BINC.C((X-i)+(A+B+C-1),A+B+C-1);
                // cerr<<(X-i)+(A+B+C-1)<<" "<<A+B+C-1<<endl;
                e%=MOD2;
                ans+=e;
                ans%=MOD2;
            }
            ans*=fact[A+B+C];
            ans%=MOD2;
            ans*=fact_inv[A];
            ans%=MOD2;
            ans*=fact_inv[B];
            ans%=MOD2;
            ans*=fact_inv[C];
            ans%=MOD2;
            cout<<ans<<endl;
        }
    }
}
accuracy: 1
time_ms: 230
memory_kb: 240208
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
constexpr ll MOD = 1000000007;
// constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}


ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

ll maxnum=5000005;
vector<ll> fac(maxnum), inv(maxnum), finv(maxnum);
void init_fac(){
    fac[0] = fac[1] = 1;
    inv[1] = 1;
    finv[0] = finv[1] = 1;
    rep(i, 2, maxnum){
        fac[i] = fac[i-1]*i%MOD;
        inv[i] = MOD-MOD/i*inv[MOD%i]%MOD;
        finv[i] = finv[i-1]*inv[i]%MOD;
    }
}
ll nCr(ll n, ll r){
    if(n < 0 or n-r < 0 or r < 0) return 0;
    return fac[n]*(finv[n-r]*finv[r]%MOD)%MOD;
}
ll nHr(ll n, ll r){
    return nCr(n+r-1, r);
}

template<int MOD> struct ModInt {
	static const int Mod = MOD; unsigned x; ModInt() : x(0) { }
	ModInt(signed sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
	ModInt(signed long long sig) { x = sig < 0 ? sig % MOD + MOD : sig % MOD; }
	int get() const { return (int)x; }
	ModInt &operator+=(ModInt that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
	ModInt &operator-=(ModInt that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
	ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; }
	ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
	ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
	ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
	ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
	ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
	ModInt inverse() const { long long a = x, b = MOD, u = 1, v = 0;
		while (b) { long long t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); }
		return ModInt(u); }
	bool operator==(ModInt that) const { return x == that.x; }
	bool operator!=(ModInt that) const { return x != that.x; }
	ModInt operator-() const { ModInt t; t.x = x == 0 ? 0 : Mod - x; return t; }
};
template<int MOD> ostream& operator<<(ostream& st, const ModInt<MOD> a) { st << a.get(); return st; };
template<int MOD> ModInt<MOD> operator^(ModInt<MOD> a, unsigned long long k) {
	ModInt<MOD> r = 1; while (k) { if (k & 1) r *= a; a *= a; k >>= 1; } return r; }
typedef ModInt<MOD> mint;

int main() {
    init_fac();
    while(true){
        ll a, b, c, sx, sy; cin >> a >> b >> c >> sx >> sy;
        ll n = a+b+c;
        if(n == 0) break;
        {
            if(sx > sy){
                swap(sx,sy);
                swap(a,b);
            }
        }
        mint ans = 0;
        rep(i,0,sx+1){
            if(sx-i < a || sy-i < b) continue;
            if(a == 0 && sx-i > 0) continue;
            if(b == 0 && sy-i > 0) continue;
            mint cnt = nCr(i+n-1,n-1);
            if(a > 0)cnt *= nCr(sx-i-a+a-1,a-1);
            if(b > 0)cnt *= nCr(sy-i-b+b-1,b-1);
            ans += cnt;
        }
        ans *= nCr(n,a);
        ans *= nCr(n-a,b);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 120512
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    if (n == 0 && r == 0) return 1;
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

using Fp = fp<1000000007>;

int main() {
while(1) {
    ll A, B, C, SX, SY;
    cin >> A >> B >> C >> SX >> SY;
    if (A == 0 && B == 0 && C == 0) return 0;
    SX -= A, SY -= B;
    if (SX < 0 || SY < 0) {
        cout << 0 << endl;
        continue;
    }
    Fp M = Fact<Fp>(A+B+C)*Fact<Fp>(A,true)*Fact<Fp>(B,true)*Fact<Fp>(C,true);
    Fp ANS = 0;
    for (ll k = 0; k <= SX && k <= SY; k++) {
        ANS += nHr<Fp>(A+B+C,k)*nHr<Fp>(A,SX-k)*nHr<Fp>(B,SY-k);
    }
    cout << M * ANS << endl;
}
}
accuracy: 1
time_ms: 240
memory_kb: 43744
final_rank: 2

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/number/modint.hpp"
struct modinfo { uint mod, root, isprime; };
template < modinfo const &ref >
struct modint {
    static constexpr uint const &mod = ref.mod;
    static constexpr uint const &root = ref.root;
    static constexpr uint const &isprime = ref.isprime;
    uint v = 0;
    constexpr modint& s(uint v) { this->v = v < mod ? v : v - mod; return *this; }
    constexpr modint(ll v = 0) { s(v % mod + mod); }
    modint operator-() const { return modint() - *this; }
    modint& operator+=(const modint& rhs) { return s(v + rhs.v); }
    modint& operator-=(const modint& rhs) { return s(v + mod - rhs.v); }
    modint& operator*=(const modint& rhs) { v = ull(v) * rhs.v % mod; return *this; }
    modint& operator/=(const modint& rhs) { return *this *= inv(rhs); }
    modint operator+(const modint& rhs) const { return modint(*this) += rhs; }
    modint operator-(const modint& rhs) const { return modint(*this) -= rhs; }
    modint operator*(const modint& rhs) const { return modint(*this) *= rhs; }
    modint operator/(const modint& rhs) const { return modint(*this) /= rhs; }
    friend modint pow(modint x, ll n) { modint res(1); while(n > 0) { if(n & 1) res *= x; x *= x; n >>= 1; } return res; }
    friend modint inv(modint v) {
        if(isprime) {
            return pow(v, mod - 2);
        } else {
            ll a = v.v, b = modint::mod, x = 1, y = 0, t;
            while(b > 0) { t = a / b; swap(a -= t * b, b); swap(x -= t * y, y); }
            return modint(x);
        }
    }
    friend modint operator+(int x, const modint& y) { return modint(x) + y; }
    friend modint operator-(int x, const modint& y) { return modint(x) - y; }
    friend modint operator*(int x, const modint& y) { return modint(x) * y; }
    friend modint operator/(int x, const modint& y) { return modint(x) / y; }
    friend istream& operator>>(istream& is, modint& m) { ll x; is >> x; m = modint(x); return is; }
    friend ostream& operator<<(ostream& os, const modint& m) { return os << m.v; }
    bool operator==(const modint& r) const { return v == r.v; }
    bool operator!=(const modint& r) const { return v != r.v; }
    static uint get_mod() { return mod; }
    static int is_prime() { return isprime; }
};
constexpr modinfo base998244353 { 998244353, 3, 1 };
constexpr modinfo base1000000007 { 1000000007, 0, 1 };
using mint998244353 = modint< base998244353 >;
using mint1000000007 = modint< base1000000007 >;
#line 3 "cp-library/src/number/binom_mod.hpp"

template < class mint >
mint fact(int n) {
    assert(0 <= n);
    assert(mint::is_prime());
    static const uint mod = mint::get_mod();
    static std::vector<mint> data = {1, 1};
    while(int(data.size()) <= n) {
        int i = data.size();
        data.push_back(data.back() * i);
    }
    return data[n];
}

template < class mint >
mint inv(int n) {
    assert(0 <= n);
    assert(mint::is_prime());
    static const uint mod = mint::get_mod();
    static std::vector<mint> data = {1, 1};
    while(int(data.size()) <= n) {
        int i = data.size();
        data.push_back(- data[mod % i] * (mod / i));
    }
    return data[n];
}

template < class mint >
mint fact_inv(int n) {
    assert(0 <= n);
    assert(mint::is_prime());
    static const uint mod = mint::get_mod();
    static std::vector<mint> data = {1, 1};
    while(int(data.size()) <= n) {
        int i = data.size();
        data.push_back(data.back() * inv<mint>(i));
    }
    return data[n];
}

template < class mint >
mint comb(int n, int k) {
    if(k < 0 or n < k) return 0;
    return fact<mint>(n) * fact_inv<mint>(k) * fact_inv<mint>(n - k);
}

template < class mint >
mint perm(int n, int k) {
    return fact<mint>(n) * fact_inv<mint>(n - k);
}

template < class mint >
mint homo(int n, int k) {
    return comb<mint>(n + k - 1, k);
}

template < class mint > struct power {
    mint a;
    std::vector<mint> data = {1};
    power() {}
    power(const mint a) : a(a) {}
    // a^n
    mint get(const int n) {
        assert(0 <= n);
        while(int(data.size()) <= n)
            data.push_back(data.back() * a);
        return data[n];
    }
};
#line 5 "B.cpp"

using mint = mint1000000007;
mint solve(int A, int B, int C, int Sx, int Sy) {
    mint ans = 0;
    auto f = [&](int e, int i) {
        if(e == 0) return mint(i == 0);
        return comb<mint>(i + e - 1, i);
    };
    for(int n = 0; n + A <= Sx and n + B <= Sy; n++) {
        mint now = 1;
        now *= f(A + B + C, n);
        now *= f(A, Sx - (n + A));
        now *= f(B, Sy - (n + B));
        ans += now;
    }
    return ans * fact<mint>(A + B + C) * fact_inv<mint>(A) * fact_inv<mint>(B) * fact_inv<mint>(C);
}

int main() {
    while(true) {
        int A = in(), B = in(), C = in(), Sx = in(), Sy = in();
        if(make_tuple(A, B, C, Sx, Sy) == make_tuple(0, 0, 0, 0, 0)) return 0;
        print(solve(A, B, C, Sx, Sy));
    }
}
accuracy: 1
time_ms: 190
memory_kb: 49468
final_rank: 3

code_snippet: #include<bits/stdc++.h>

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned long long y = x * _m;
        return (unsigned int)(z - y + (z < y ? _m : 0));
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

using namespace std;
using mint=atcoder::modint1000000007;
template<typename mint>
struct combination
{
    combination(int n=0):inner_fac(1,1),inner_finv(1,1){init(n);}
    mint fac(int n)
    {
        init(n);
        return inner_fac[n];
    }
    mint finv(int n)
    {
        init(n);
        return inner_finv[n];
    }
    mint inv(int n)
    {
        if(n==0)return 0;
        init(n);
        return inner_fac[n-1]*inner_finv[n];
    }
    mint C(int n, int r)
    {
        if(r<0)return 0;
        if(n<0)
        {
            n=-n;
            mint res=C(n-1+r,r);
            if(r&1)res=-res;
            return res;
        }
        if(n<r)return 0;
        if(n<bound)
        {
            init(n);
            return inner_fac[n]*inner_finv[n-r]*inner_finv[r];
        }
        init(r);
        mint res=1;
        for(int i=0;i<r;i++)res*=(n-i);
        return res*inner_finv[r];
    }
    mint P(int n, int r)
    {
        if(n<0||r<0||n<r)return 0;
        if(n<bound)
        {
            init(n);
            return inner_fac[n]*inner_finv[n-r];
        }
        mint res=1;
        for(int i=0;i<r;i++)res*=(n-i);
        return res;
    }
    mint H(int n, int r)
    {
        return C(n-1+r,r);
    }
private:
    const int bound=1<<25;
    vector<mint>inner_fac,inner_finv;
    void init(int n)
    {
        int sz=inner_fac.size();
        if(sz>n)return;
        n=min(max(n,2*sz),bound);
        inner_fac.resize(n+1);
        inner_finv.resize(n+1);
        for(int i=sz;i<=n;i++)inner_fac[i]=inner_fac[i-1]*i;
        inner_finv[n]=inner_fac[n].inv();
        for(int i=n;i>sz;i--)inner_finv[i-1]=inner_finv[i]*i;
    }
};
combination<mint>C;
bool solve()
{
    int A,B,D,X,Y;
    cin>>A>>B>>D>>X>>Y;
    if(A==0&&B==0&&D==0&&X==0&&Y==0)return 0;
    mint ans=0;
    for(int a=A;a<=X;a++)
    {
        int b=Y-X+a;
        ans+=C.H(A,a-A)*C.H(B,b-B)*C.H(A+B+D,X-a);
    }
    ans*=C.C(A+B+D,A)*C.C(B+D,B);
    cout<<ans.val()<<endl;
    return 1;
}
int main(){while(solve()){}}
accuracy: 1
time_ms: 150
memory_kb: 52784
final_rank: 4

code_snippet: #include<bits/stdc++.h>


#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

using namespace atcoder;
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };



using mint = modint1000000007;
using vm = vector<mint>;
using vvm = vector<vm>;
using vvvm = vector<vvm>;


vector<mint> fact, factinv, inv, factK;
ll mod = 1000000007;
void prenCkModp(ll n) {
    fact.resize(n + 5);
    factinv.resize(n + 5);
    inv.resize(n + 5);
    fact[0] = fact[1] = 1;
    factinv[0] = factinv[1] = 1;
    inv[1] = 1;
    for (ll i = 2; i < n + 5; i++) {
        fact[i] = (fact[i - 1] * i);
        inv[i] = (mod - ((inv[mod % i] * (mod / i))));
        factinv[i] = (factinv[i - 1] * inv[i]);
    }
}
mint nCk(ll n, ll k) {
    if (n < k || k < 0) return 0;
    return (fact[n] * ((factinv[k] * factinv[n - k])));
}

void solve(ll A, ll B, ll C, ll SX, ll SY) {
    mint an = 0;
    //Xが勝った試合の勝ち越し総和がx点
    for (ll x = A; x <= SX; x++) {
        ll y = SY - SX + x;
        if (y<B || y>SY)continue;
        mint res = 1;
        if(x>0)res *= nCk(x - 1, A - 1);
        if(y>0)res *= nCk(y - 1, B - 1);
        if(SX!=x)res *= nCk(SX - x + A + B + C - 1, A + B + C - 1);
        an += res;
    }
    an *= fact[A + B + C];
    an *= factinv[A];
    an *= factinv[B];
    an *= factinv[C];
    cout << an.val() << endl;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    prenCkModp(5e6);
    ll A, B, C, X, Y;
    while (cin >> A >> B >> C >> X >> Y) {
        if (A + B + C + X + Y == 0)return 0;
        solve(A, B, C, X, Y);
    }

}
accuracy: 1
time_ms: 130
memory_kb: 61600
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

ll mod_pow(ll x, ll n, ll mod)
{
    ll xx = x % mod;
    ll ret = 1;
    while (n)
    {
        if (n & 1)
        {
            ret *= xx;
            ret %= mod;
        }
        xx = xx * xx % mod;
        n >>= 1;
    }
    
    return ret;
}

const ll nmax = 5e6;
const ll MOD = 1e9 + 7;

ll fact[nmax], inv_fact[nmax];

ll mod_comb(ll n, ll r, ll mod)
{
    // check 0 <= r <= n
    if (r < 0 || n < r) return 0;
    
    ll ret = inv_fact[n-r] * inv_fact[r] % mod;
    ret *= fact[n];
    ret %= mod;
    
    return ret;
}

void init()
{
    for (int i = 0; i < nmax; ++i)
    {
        if (i == 0) fact[i] = 1;
        else fact[i] = fact[i-1] * i % MOD;
    }
    inv_fact[nmax - 1] = mod_pow(fact[nmax - 1], MOD - 2, MOD);
    for (int i = nmax - 2; i >= 0; --i)
    {
        inv_fact[i] = inv_fact[i+1] * (i + 1) % MOD;
    }
    
    return;
}


bool is_end = false;

void solve()
{
    ll A, B, C, X, Y; cin >> A >> B >> C >> X >> Y;
    ll N = A + B + C;
    
    if (N == 0 && X == 0 && Y == 0)
    {
        is_end = true;
        return;
    }
    
    ll res = 0;
    ll kmax = min(X - A, Y - B);
    // cout << kmax << endl;
    
    for (int k = 0; k <= kmax; ++k)
    {
        ll draw = mod_comb(N - 1 + k, N - 1, MOD);
        ll x = mod_comb(X - k - 1, A - 1, MOD);
        if (A == 0 && X - k == 0) x = 1;
        
        ll y = mod_comb(Y - k - 1, B - 1, MOD);
        if (B == 0 && Y - k == 0) y = 1;
        
        ll tmp = draw * x % MOD;
        tmp *= y;
        tmp %= MOD;
        
        res += tmp;
        res %= MOD;
        
        // cout << k << " " << tmp << endl;
    }
    
    {
        ll mult = fact[A + B + C];
        mult *= inv_fact[A];
        mult %= MOD;
        mult *= inv_fact[B];
        mult %= MOD;
        mult *= inv_fact[C];
        mult %= MOD;
        
        res *= mult;
        res %= MOD;
    }
    
    cout << res << endl;
    
    return;
}

int main()
{
    init();
    while (!is_end)
    {
        solve();
    }
    
    return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 81568
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
constexpr ll mod = 1000000007;
ll pow_mod(ll x, ll n) {
    x %= mod;
    if(x < 0) x += mod;
    ll res = 1;
    while(n > 0) {
        if(n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}
ll inv_mod(ll x) {
    return pow_mod(x, mod - 2);
}

int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(0);
    constexpr int MAX = 6000000;
    vector<ll> fact(MAX), ifact(MAX);
    fact[0] = 1;
    rep(i, 1, MAX) fact[i] = (fact[i - 1] * i) % mod;
    ifact[MAX - 1] = inv_mod(fact[MAX - 1]);
    rrep(i, MAX - 1, 1) ifact[i - 1] = (ifact[i] * i) % mod;
    auto comb = [&](int n, int r) -> ll {
        if(n < 0 or n < r or r < 0) return 0;
        return ((fact[n] * ifact[n - r]) % mod * ifact[r]) % mod;
    };
    auto solve = [&](auto& solve, ll a, ll b, ll c, ll sx, ll sy) -> ll {
        if(a == 0 && b == 0) {
            if(sx != sy) return 0;
            return comb(sx + c - 1, c - 1);
        }
        if(a == 0) {
            return solve(solve, b, a, c, sy, sx);
        }
        if(b == 0) {
            ll term1 = comb(a + c, c);
            ll term2 = comb(sy + a + c - 1, a + c - 1);
            ll term3 = comb(sx - sy - 1, a - 1);
            return (((term1 * term2) % mod) * term3) % mod;
        }

        return 0;
    };
    while(1) {
        ll a, b, c, sx, sy;
        cin >> a >> b >> c >> sx >> sy;
        if(a == 0 and b == 0 and c == 0 and sx == 0 and sy == 0) break;
        if(a == 0 or b == 0) {
            cout << solve(solve, a, b, c, sx, sy) << '\n';
            continue;
        }
        ll ans = 0;
        rep(z, 0, min(sx - a, sy - b) + 1) {
            ans = (ans + comb(a + b + c, a) % mod * comb(b + c, b) % mod * comb(sx - z - 1, a - 1) % mod * comb(sy - z - 1, b - 1) % mod * comb(z + a + b + c - 1, a + b + c - 1) % mod) % mod;
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 130
memory_kb: 96812
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<n;i++)
#define all(A) A.begin(),A.end()

const ll mod = 1e9 + 7;
vector<ll> fact, factinv, inv;
void prenCkmodp(ll n) {
    fact.resize(n + 5);
    factinv.resize(n + 5);
    inv.resize(n + 5);
    fact[0] = fact[1] = factinv[0] = factinv[1] = inv[1] = 1;
    for (ll i = 2; i < n + 5; i++) {
        fact[i] = (fact[i - 1] * i) % mod;
        inv[i] = ((mod - (inv[mod % i] * (mod / i)) % mod) + mod) % mod;
        factinv[i] = (factinv[i - 1] * inv[i]) % mod;
    }
}
ll nCk(ll n, ll k) {
    if (n < k || k < 0)return 0;
    return (fact[n] * ((factinv[k] * factinv[n - k]) % mod)) % mod;
}

int main() {

    prenCkmodp(6e6);

    while (1) {
        ll A, B, C, X, Y;
        cin >> A >> B >> C >> X >> Y;
        ll S = A + B + C;
        if (S == 0)return 0;
        ll an = 0;
        for (ll D = 0; D <= S+X+Y; D++) {
            ll E = X - Y - D;
            if(E>0)continue;
            ll res = nCk(S - 1 + Y + E, S - 1);
            res%=mod;
            ll fes = nCk(abs(E) - 1, B - 1);
            if(abs(E)==B&&B==0)fes=1;
            fes%=mod;
            ll ges = nCk(D - 1, A - 1);
            if(D==A&&D==0)ges=1;
            ges%=mod;
            an += ((res * fes) % mod) * ges;
            an %= mod;
        }
        an *= fact[A + B + C];
        an %= mod;
        an *= factinv[A];
        an %= mod;
        an *= factinv[B];
        an %= mod;
        an *= factinv[C];
        an %= mod;
        cout << an << endl;
    }
}
accuracy: 1
time_ms: 1030
memory_kb: 143560
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define REP(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[ ";
    for (auto& vi : v) os << vi << ", ";
    return os << "]";
}

template <class T, class U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "{ " << p.first << ", " << p.second << " }";
}

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << x << endl;
#else
#define show(x) true
#endif

using i64 = long long;
template <i64 MD> struct modint {
    using M = modint<MD>;
    i64 a;
    modint(const i64 x = 0) : a((x % MD + MD) % MD) {}
    M& s(i64 v) {
        a = v < MD ? v : v - MD;
        return *this;
    }
    i64 value() const { return a; }
    M inv() const { return this->pow(MD - 2); }
    M pow(i64 r) const {
        M ans(1);
        M x = *this;
        while (r) {
            if (r & 1) ans *= x;
            x *= x;
            r >>= 1;
        }
        return ans;
    }
    M& operator+=(M r) { return s(a + r.a); }
    M& operator-=(M r) { return s(a + MD - r.a); }
    M& operator*=(M r) { return s(a * r.a % MD); }
    M& operator/=(M r) { return *this *= r.inv(); }
    M operator+(M r) const { return M(*this) += r; }
    M operator-(M r) const { return M(*this) -= r; }
    M operator*(M r) const { return M(*this) *= r; }
    M operator/(M r) const { return M(*this) /= r; }
    M operator-() const { return M(0) - M(*this); }
};

using fp = modint<1000000007>;

template <class T> struct Binomial {
    V<T> f, g;

    Binomial(const int n = 0) {
        f.resize(n);
        g.resize(n);
        f[0] = g[0] = 1;
        for (int i = 1; i < n; i++) f[i] = f[i - 1] * T(i);
        g[n - 1] = T(1) / f[n - 1];
        for (int i = n - 2; i >= 1; i--) g[i] = g[i + 1] * T(i + 1);
    }

    T C(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K] * g[K];
    }

    T P(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K];
    }

    T C_naive(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        T res(1);
        K = min(K, N - K);
        for (int i = 1; i <= K; i++) {
            res *= N--;
            res /= i;
        }
        return res;
    }
};

ostream& operator<<(ostream& os, const fp p) {
    return os << p.value();
}

void solve(long long A, long long B, long long C, long long Sx, long long Sy, Binomial<fp>& binom) {
    fp ans = 0;
    long long d = Sx - Sy;
    long long n = A + B + C;
    for (long long x = max(0LL, d); x <= Sx; x++) {
        long long y = x - d;
        long long s = Sx - x;
        if (x < A or y < B or s < 0) continue;
        if (A == 0 and x > 0) continue;
        if (B == 0 and y > 0) continue;
        fp cur = binom.C(s + n - 1, n - 1);
        if (A != 0) cur *= binom.C(x - 1, A - 1);
        if (B != 0) cur *= binom.C(y - 1, B - 1);
        ans += cur;
    }
    ans *= binom.C(n, A) * binom.C(n - A, B);
    cout << ans << '\n';
}

int main() {
    Binomial<fp> binom(4000000);
    long long A, B, C, Sx, Sy;
    while (cin >> A >> B >> C >> Sx >> Sy, !(A == 0 and B == 0 and C == 0 and Sx == 0 and Sy == 0)) {
        solve(A, B, C, Sx, Sy, binom);
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 65376
final_rank: 6

code_snippet: #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2751"

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define REP(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;
template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[ ";
    for (auto& vi : v) os << vi << ", ";
    return os << "]";
}

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << x << endl;
#else
#define show(x) true
#endif

using uint = unsigned int;
using ull = unsigned long long;

// g++ -g -fsanitize=undefined,address -DLOCAL -std=gnu++17

// https://onlinejudge.u-aizu.ac.jp/problems/3331

using uint = unsigned int;
using ull = unsigned long long;
template <uint MD> struct Modint {
    using M = Modint;
    const static M G;
    uint v;
    Modint(ll val = 0) { set_v(val % MD + MD); }
    M& set_v(uint val) {
        v = (val < MD) ? val : val - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(ull(v) * r.v % MD); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    M pow(ll n) const {
        M x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    M inv() const { return pow(MD - 2); }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};
// using mint = Modint<998244353>;
// template<> const mint mint::G = mint(3);

template <class T> struct Binomial {
    V<T> f, g;

    Binomial(const int n = 0) {
        f.resize(n);
        g.resize(n);
        f[0] = g[0] = 1;
        for (int i = 1; i < n; i++) f[i] = f[i - 1] * T(i);
        g[n - 1] = T(1) / f[n - 1];
        for (int i = n - 2; i >= 1; i--) g[i] = g[i + 1] * T(i + 1);
    }

    T C(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K] * g[K];
    }

    T P(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K];
    }

    T C_naive(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        T res(1);
        K = min(K, N - K);
        for (int i = 1; i <= K; i++) {
            res *= N--;
            res /= i;
        }
        return res;
    }
};

using fp = Modint<1000000007>;

void solve(long long A, long long B, long long C, long long Sx, long long Sy, Binomial<fp>& binom) {
    fp ans = 0;
    long long d = Sx - Sy;
    long long n = A + B + C;
    for (long long x = max(0LL, d); x <= Sx; x++) {
        long long y = x - d;
        long long s = Sx - x;
        if (x < A or y < B or s < 0) continue;
        if (A == 0 and x > 0) continue;
        if (B == 0 and y > 0) continue;
        fp cur = binom.C(s + n - 1, n - 1);
        if (A != 0) cur *= binom.C(x - 1, A - 1);
        if (B != 0) cur *= binom.C(y - 1, B - 1);
        ans += cur;
    }
    ans *= binom.C(n, A) * binom.C(n - A, B);
    cout << ans << '\n';
}

int main() {
    Binomial<fp> binom(4000000);
    long long A, B, C, Sx, Sy;
    while (cin >> A >> B >> C >> Sx >> Sy, !(A == 0 and B == 0 and C == 0 and Sx == 0 and Sy == 0)) {
        solve(A, B, C, Sx, Sy, binom);
    }
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 34248
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define REP(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[ ";
    for (auto& vi : v) os << vi << ", ";
    return os << "]";
}

template <class T, class U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "{ " << p.first << ", " << p.second << " }";
}

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << x << endl;
#else
#define show(x) true
#endif

using i64 = long long;
template <i64 MD> struct modint {
    using M = modint<MD>;
    i64 a;
    modint(const i64 x = 0) : a((x % MD + MD) % MD) {}
    M& s(i64 v) {
        a = v < MD ? v : v - MD;
        return *this;
    }
    i64 value() const { return a; }
    M inv() const { return this->pow(MD - 2); }
    M pow(i64 r) const {
        M ans(1);
        M x = *this;
        while (r) {
            if (r & 1) ans *= x;
            x *= x;
            r >>= 1;
        }
        return ans;
    }
    M& operator+=(M r) { return s(a + r.a); }
    M& operator-=(M r) { return s(a + MD - r.a); }
    M& operator*=(M r) { return s(a * r.a % MD); }
    M& operator/=(M r) { return *this *= r.inv(); }
    M operator+(M r) const { return M(*this) += r; }
    M operator-(M r) const { return M(*this) -= r; }
    M operator*(M r) const { return M(*this) *= r; }
    M operator/(M r) const { return M(*this) /= r; }
    M operator-() const { return M(0) - M(*this); }
};

using fp = modint<1000000007>;

template <class T> struct Binomial {
    V<T> f, g;

    Binomial(const int n = 0) {
        f.resize(n);
        g.resize(n);
        f[0] = g[0] = 1;
        for (int i = 1; i < n; i++) f[i] = f[i - 1] * T(i);
        g[n - 1] = T(1) / f[n - 1];
        for (int i = n - 2; i >= 1; i--) g[i] = g[i + 1] * T(i + 1);
    }

    T C(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K] * g[K];
    }

    T P(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        return f[N] * g[N - K];
    }

    T C_naive(int N, int K) {
        if (N < 0 or K < 0 or N < K) return 0;
        T res(1);
        K = min(K, N - K);
        for (int i = 1; i <= K; i++) {
            res *= N--;
            res /= i;
        }
        return res;
    }
};

ostream& operator<<(ostream& os, const fp p) {
    return os << p.value();
}

void solve(long long A, long long B, long long C, long long Sx, long long Sy, Binomial<fp>& binom) {
    fp ans = 0;
    long long d = Sx - Sy;
    long long n = A + B + C;
    for (long long x = max(0LL, d); x <= Sx; x++) {
        long long y = x - d;
        long long s = Sx - x;
        if (x < A or y < B or s < 0) continue;
        if (A == 0 and x > 0) continue;
        if (B == 0 and y > 0) continue;
        fp cur = binom.C(s + n - 1, n - 1);
        if (A != 0) cur *= binom.C(x - 1, A - 1);
        if (B != 0) cur *= binom.C(y - 1, B - 1);
        ans += cur;
    }
    ans *= binom.C(n, A) * binom.C(n - A, B);
    cout << ans << '\n';
}

int main() {
    Binomial<fp> binom(4000000);
    long long A, B, C, Sx, Sy;
    while (cin >> A >> B >> C >> Sx >> Sy, !(A == 0 and B == 0 and C == 0 and Sx == 0 and Sy == 0)) {
        solve(A, B, C, Sx, Sy, binom);
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 65392
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;
using i64 = long long;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;

void out(vi &a) {
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << " \n"[i + 1 == a.size()];
    }
}

constexpr i64 mod = 1e9 + 7;

i64 inv(i64 x){
    i64 k = mod - 2;
    i64 res = 1, tmp = x;
    while(k){
        if(k&1){
            res = res * tmp % mod;
        }
        tmp = tmp * tmp % mod;
        k >>= 1;
    }
    return res;
}

struct Enumeration{
    using M = long long;
    vector<M> fact, finv, invs;
    Enumeration(){}
    void init(int n){
        int m = fact.size();
        if(n < m){
            return;
        }
        fact.resize(n+1, 1);
        finv.resize(n+1,1);
        invs.resize(n+1,1);
        if(m==0){
            m=1;
        }
        for(int i=m; i <= n; ++i){
            fact[i] = (fact[i - 1] * i) % mod;
        }
        finv[n] = inv(fact[n]);
        for(int i = n; i >= m; i--){
            finv[i-1]=finv[i]*i%mod;
        }
        for(int i = m; i <= n; ++i){
            invs[i] = finv[i] * fact[i-1] % mod;
        }
    }
    M C(int n, int k){
        if(n<k||k<0)return 0;
        init(n);
        // cout << "ncr: " << n << " "<< k << "  " << fact[n] * finv[n-k]%mod << endl;
        return fact[n]*finv[n-k]%mod*finv[k]%mod;
    }
    M H(int n, int k){
        if(n<0||k<0)return 0;
        if(!n&&!k){
            return 1;
        }
        init(n+k);
        return C(n+k-1, k);
    }
};

bool solve() {
    int a, b, c, sx, sy;
    cin >> a >> b >> c >> sx >> sy;
    if(a + b + c == 0){
        return false;
    }

    // must be (sx < sy)
    if(sx > sy){
        swap(sx, sy);
        swap(a, b);
    }
    i64 ans = 0;
    Enumeration enu;
    for(int e = 0;; ++e){
        int x = sx - e;
        int y = sy - e;
        if(x < a || y < b){
            break;
        }
        // cout << e << " " << x << " " << y << endl;
        i64 val = 1;
        val *= enu.H(a + b + c, e);

        // cout << a + b + c << " " << e << ": " << enu.H(a + b + c, e) << endl;

        val %= mod;
        val *= enu.C(a + b + c, a);
        val %= mod;
        val *= enu.C(b + c, b);
        val %= mod;

        val *= enu.H(a, x - a);
        val %= mod;
        val *= enu.H(b, y - b);
        val %= mod;

        ans += val;
        ans %= mod;
    }
    cout << ans << endl;

    return true;
}

signed main(){
    while(solve());
}
accuracy: 1
time_ms: 1040
memory_kb: 91388
final_rank: 16

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define rep(i,s,n) for(int i = int(s); i < int(n); i++)
#define rrep(i,s,n) for(int i = int(n) - 1; i >= s; i--)
#define all(a) a.begin(), a.end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

using namespace std;

template<class T>
bool chmin(T &a, T &b) {
    if(a <= b) return false;
    a = b;
    return true;
}

template<class T>
bool chmax(T &a, T &b) {
    if(a >= b) return false;
    a = b;
    return true;
}

const ll mod = 1'000'000'007;
const int mx = 4'000'100;
ll fact[mx], ifact[mx];

ll modpow(ll x, ll n){
    if (n == 0) return 1;
    x %= mod;
    ll res = modpow(x,n/2);
    res = res * res % mod;
    if (n % 2 == 1) res = res * x % mod;\
    return res;
}

ll nhr(int n, int r){
    if (r == 0){
        if (n == 0) return 1;
        return 0;
    }
    if (n < 0 || r < 0) return 0;
    return (fact[n+r-1] * ifact[n] % mod) * ifact[r-1] % mod;
}

int main() {
    fact[0] = 1;
    for (ll n = 1; n < mx; n++){
        fact[n] = fact[n-1] * n % mod;
    }
    ifact[mx-1] = modpow(fact[mx-1],mod-2);
    for (ll n = mx-1; n >= 1; n--){
        ifact[n-1] = ifact[n] * n % mod;
    }
    while(true){
        int a, b, c, sx, sy; cin >> a >> b >> c >> sx >> sy;
        if (a == 0 && b == 0 && c == 0) break;
        ll ans = 0;
        for (int p = 0; p <= min(sx,sy); p++){
            int x = sx-p-a, y = sy-p-b; //cout << x << " " << a << " " << y << " " << b << endl;
            ll cur = nhr(x,a) * nhr(y,b) % mod;
            cur = cur * nhr(p,a+b+c) % mod;
            ans += cur;
        }
        ans %= mod; //cout << ans << endl;
        ll tmp1 = fact[a+b+c] * ifact[a] % mod;
        ll tmp2 = ifact[b] * ifact[c] % mod;
        ans *= tmp1 * tmp2 % mod;
        ans %= mod;
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 170
memory_kb: 65828
final_rank: 10

code_snippet: #include<bits/stdc++.h>
#define int ll
#define rep(i, N) for(int i = 0; i < (int)(N); ++i)
#define rep1(i, N) for(int i = 1; i <= (int)(N); ++i)
#define per(i, N) for(int i = (N)-1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) ((n) >> (k))
#define pcnt(n) (__builtin_popcount(n))
#define TakAo(ans) ans ? cout << "Takahashi\n" : cout << "Aoki\n"
#define YesNo(ans) ans ? cout << "Yes\n" : cout << "No\n"
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back

using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using point = struct{ ll x, y; };
using pointld = struct{ ld x, y; };
using State = string::const_iterator;
template<class T> using max_heap = priority_queue<T>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vec<vec<T>>;
template<class T> using vvvec = vec<vvec<T>>;
template<class T> using vvvvec = vvec<vvec<T>>;

constexpr ld EPS = 1e-10;
constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr ll MOD = (0) ? 998244353 : 1e9+7;
constexpr int NIL = -1;
constexpr int pm[2] = {1, -1};
constexpr int dy[4] = {0, 1, 0, -1};
constexpr int dx[4] = {1, 0, -1, 0};

ll cel(ll a, ll b){ return (a + b - 1) / b;}
ll Gcd(ll a, ll b){ return b ? Gcd(b, a % b) : abs(a);}
template<class T> T powi(T x, ll exp){
    return exp > 0 ? (exp & 1 ? x : 1) * powi(x * x, exp >> 1) : x / x;
}
ll modpow(ll x, ll exp, ll mod){
    x %= mod;
    return exp > 0 ? (exp & 1 ? x : 1) * modpow(x * x, exp >> 1, mod) % mod : 1;
}
template<class T> bool chmin(T &a, T b){ return a > b ? (a = b, true) : 0;}
template<class T> bool chmax(T &a, T b){ return a < b ? (a = b, true) : 0;}

using Pair = pair<ll, ll>;
using Tpl = tuple<int, int, int>;

class Combination{
    int max_val; // (2^n)-2
    vector<ll> fact_, invf_;

    void build(int n){
        int prev_val = max_val;
        while(max_val < n) max_val = (max_val << 1) | 2;
        fact_.resize(max_val + 1);
        invf_.resize(max_val + 1);
        for(int i = prev_val + 1; i <= max_val; i++){
            fact_[i] = fact_[i-1] * i % MOD;
        }
        invf_[max_val] = 1;
        for(ll x = fact_[max_val], k = MOD-2; k > 0; k >>= 1){
            if(k & 1) invf_[max_val] = invf_[max_val] * x % MOD;
            x = x * x % MOD;
        }
        for(int i = max_val; i > prev_val + 1; i--){
            invf_[i-1] = invf_[i] * i % MOD;
        }
    }
    bool check(int n){
        if(n < 0) return false;
        if(n > max_val) build(n);
        return true;
    }
    bool check(int n, int r){
        if(n < r || r < 0) return false;
        if(n > max_val) build(n);
        return true;
    }

    public:
    Combination() : max_val(0), fact_(1, 1), invf_(1, 1) {}
    Combination(int N) : max_val(0), fact_(1, 1), invf_(1, 1) {build(N);}
    int fact(int n){
        check(n);
        return fact_[n];
    }
    int invf(int n){
        check(n);
        return invf_[n];
    }
    int nPr(int n, int r){
        check(n, r);
        return fact_[n] * invf_[n-r] % MOD;
    }
    int nCr(int n, int r){
        check(n, r);
        return fact_[n] * invf_[n-r] % MOD * invf_[r] % MOD;
    }
};

void Main(){
    Combination comb(4e6+10);
    while(1){
        ll A, B, C, SX, SY;
        cin >> A >> B >> C >> SX >> SY;
        if(A + B + C == 0) break;

        ll ans = comb.nCr(A + B + C, A) * comb.nCr(B + C, B) % MOD;
        ll val = 0;

        for(ll scr = 0; scr <= max(SX, SY); scr++){
            // 2
            ll val2 = comb.nCr(scr + A + B + C - 1, scr);

            // 3
            if(A == 0 && SX - scr) continue;
            if(B == 0 && SY - scr) continue;

            if(SX - scr < A || SY - scr < B) continue;

            ll val3 = A ? comb.nCr(SX - scr - 1, A - 1) : 1;
            val3 = B ? val3 * comb.nCr(SY - scr - 1, B - 1) % MOD : val3;

            val2 = val2 * val3 % MOD;

            val = (val + val2) % MOD;
        }

        cout << ans * val % MOD << endl;
    }
}
 
signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    Main();
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 68512
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define int ll
#define rep(i, N) for(int i = 0; i < (int)(N); ++i)
#define rep1(i, N) for(int i = 1; i <= (int)(N); ++i)
#define per(i, N) for(int i = (N)-1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) ((n) >> (k))
#define pcnt(n) (__builtin_popcount(n))
#define TakAo(ans) ans ? cout << "Takahashi\n" : cout << "Aoki\n"
#define YesNo(ans) ans ? cout << "Yes\n" : cout << "No\n"
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back

using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using point = struct{ ll x, y; };
using pointld = struct{ ld x, y; };
using State = string::const_iterator;
template<class T> using max_heap = priority_queue<T>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vec<vec<T>>;
template<class T> using vvvec = vec<vvec<T>>;
template<class T> using vvvvec = vvec<vvec<T>>;

constexpr ld EPS = 1e-10;
constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr ll MOD = (0) ? 998244353 : 1e9+7;
constexpr int NIL = -1;
constexpr int pm[2] = {1, -1};
constexpr int dy[4] = {0, 1, 0, -1};
constexpr int dx[4] = {1, 0, -1, 0};

ll cel(ll a, ll b){ return (a + b - 1) / b;}
ll Gcd(ll a, ll b){ return b ? Gcd(b, a % b) : abs(a);}
template<class T> T powi(T x, ll exp){
    return exp > 0 ? (exp & 1 ? x : 1) * powi(x * x, exp >> 1) : x / x;
}
ll modpow(ll x, ll exp, ll mod){
    x %= mod;
    return exp > 0 ? (exp & 1 ? x : 1) * modpow(x * x, exp >> 1, mod) % mod : 1;
}
template<class T> bool chmin(T &a, T b){ return a > b ? (a = b, true) : 0;}
template<class T> bool chmax(T &a, T b){ return a < b ? (a = b, true) : 0;}

using Pair = pair<ll, ll>;
using Tpl = tuple<int, int, int>;

class Combination{
    int max_val; // (2^n)-2
    vector<ll> fact_, invf_;

    void build(int n){
        int prev_val = max_val;
        while(max_val < n) max_val = (max_val << 1) | 2;
        fact_.resize(max_val + 1);
        invf_.resize(max_val + 1);
        for(int i = prev_val + 1; i <= max_val; i++){
            fact_[i] = fact_[i-1] * i % MOD;
        }
        invf_[max_val] = 1;
        for(ll x = fact_[max_val], k = MOD-2; k > 0; k >>= 1){
            if(k & 1) invf_[max_val] = invf_[max_val] * x % MOD;
            x = x * x % MOD;
        }
        for(int i = max_val; i > prev_val + 1; i--){
            invf_[i-1] = invf_[i] * i % MOD;
        }
    }
    bool check(int n){
        if(n < 0) return false;
        if(n > max_val) build(n);
        return true;
    }
    bool check(int n, int r){
        if(n < r || r < 0) return false;
        if(n > max_val) build(n);
        return true;
    }

    public:
    Combination() : max_val(0), fact_(1, 1), invf_(1, 1) {}
    Combination(int N) : max_val(0), fact_(1, 1), invf_(1, 1) {build(N);}
    int fact(int n){
        check(n);
        return fact_[n];
    }
    int invf(int n){
        check(n);
        return invf_[n];
    }
    int nPr(int n, int r){
        check(n, r);
        return fact_[n] * invf_[n-r] % MOD;
    }
    int nCr(int n, int r){
        check(n, r);
        return fact_[n] * invf_[n-r] % MOD * invf_[r] % MOD;
    }
};

void Main(){
    Combination comb(4e6+10);
    while(1){
        ll A, B, C, SX, SY;
        cin >> A >> B >> C >> SX >> SY;
        if(A + B + C == 0) break;

        ll ans = comb.nCr(A + B + C, A) * comb.nCr(B + C, B) % MOD;
        ll val = 0;

        for(ll scr = 0; scr <= max(SX, SY); scr++){
            // 2
            ll val2 = comb.nCr(scr + A + B + C - 1, scr);

            // 3
            if(A == 0 && SX - scr) continue;
            if(B == 0 && SY - scr) continue;

            if(SX - scr < A || SY - scr < B) continue;

            ll val3 = A ? comb.nCr(SX - scr - 1, A - 1) : 1;
            val3 = B ? val3 * comb.nCr(SY - scr - 1, B - 1) % MOD : val3;

            val2 = val2 * val3 % MOD;

            val = (val + val2) % MOD;
        }

        cout << ans * val % MOD << endl;
    }
}
 
signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    Main();
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 68600
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
const ll MOD = (ll)1e9+7;
//const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;


template<long long mod>
class modint{
	public:
		long long x;
		modint(long long a){x=a%mod;if(x<0)x+=mod;}
		modint(){x=0;}

		modint pow(long long a){
			modint res(1), b(x);
			while(a){
				if(a&1)res*=b;
				b*=b;
				a>>=1;
			}
			return res;
		}

		modint inv(){return pow(mod-2);}

		modint& operator+=(modint a){x=(x+a.x)%mod;return *this;}
		modint& operator-=(modint a){x=x-a.x;if(x<0)x+=mod;return *this;}
		modint& operator*=(modint a){x=x*a.x%mod;return *this;}
		modint& operator/=(modint a){x=x*a.inv().x%mod;return *this;}

		modint operator+(modint a){return modint(x)+=a;}
		modint operator-(modint a){return modint(x)-=a;}
		modint operator*(modint a){return modint(x)*=a;}
		modint operator/(modint a){return modint(x)/=a;}

		modint operator-(){return modint(x);}

		bool operator==(const modint a){return x == a.x;}
		bool operator<(const modint a){return x < a.x;}
		bool operator>(const modint a){return x > a.x;}
};

template<long long mod>
ostream& operator<<(ostream& os, const modint<mod>& a){
	os << a.x;
	return os;
}

using mint = modint<MOD>;

mint factorial(int n){
    if(n < 0)return 0;
    if(n <= 1)return 1;
    static vector<mint> memo(2,1);
    while(memo.size() <= n){
        mint add = memo.back() * memo.size();
        memo.emplace_back(add);
    }
    return memo[n];
}

mint combination(int a,int b){
    return factorial(a) / (factorial(a-b) * factorial(b));
}

mint func(int a,int b,int c,int x,int y){
    mint mul = 1;
    mul *= factorial(a+b+c);
    mul /= factorial(a);
    mul /= factorial(b);
    mul /= factorial(c);
    mint res = 0;
    rep(remind,max(x,y)+10){
        int overx = x - remind;
        int overy = y - remind;
        if(overx < a)continue;
        if(overy < b)continue;
        if(a==0 and overx)continue;
        if(b==0 and overy)continue;
        mint add = 1;
        if(a){
            add *= combination(overx-1,a-1);
        }
        if(b){
            add *= combination(overy-1,b-1);
        }
        add *= combination(remind+a+b+c-1,a+b+c-1);
        res += add;
    }
    res *= mul;
    return res;
}

int main(){
    while(true){
        int a = in();
        int b = in();
        int c = in();
        int x = in();
        int y = in();
        if(a==0 and b==0 and c==0 and x==0 and y==0)break;
        println(func(a,b,c,x,y));
    }
    return 0;
}
accuracy: 1
time_ms: 1280
memory_kb: 37664
final_rank: 15

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/modint>
using namespace std;
// using namespace atcoder;
const long long MOD = 1000000007;
const long long N = 4000400;
long long fact[N];
long long invfact[N];

long long modpow(long long a, long long b){
	long long ret = 1;
	while(b > 0){
		if(b & 1){
			ret *= a;
			ret %= MOD;
		}
		a *= a;
		a %= MOD;
		b >>= 1;
	}
	return ret;
}

void init(){
	fact[0] = 1;
	for(int i = 1; i < N; i++){
		fact[i] = fact[i - 1] * i % MOD;
	}
	invfact[N - 1] = modpow(fact[N - 1], MOD - 2);
	for(int i = N - 2; i >= 0; i--){
		invfact[i]  =invfact[i + 1] * (i + 1) % MOD;
	}
}

long long nCk(int n, int k){
	if(k < 0 || k > n) return 0;
	return (fact[n] * invfact[k] % MOD) * invfact[n - k] % MOD;
}

long long nHk(int n, int k){
	if(n == 0 && k == 0) return 1;
	return nCk(n + k - 1, k);
}

void solve(){
	init();
	while(1){
		int a, b, c, sx, sy;
		cin >> a >> b >> c >> sx >> sy;
		if(a + b + c == 0) return;
		int abc = a + b + c;
		long long ans = 0;
		for(int cc = 0; cc <= min(sx, sy); cc++){
			long long tmp = nHk(abc, cc);
			tmp *= nHk(a, sx - cc - a) * nHk(b, sy - cc - b) % MOD;
			ans += tmp % MOD;
			ans %= MOD;
		}
		ans *= nCk(abc, a) * nCk(b + c, b) % MOD;
		ans %= MOD;
		cout << ans << "\n";
	}
}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    int t;
    t = 1;
    // cin >> t;
    while(t--) solve();
}
accuracy: 1
time_ms: 200
memory_kb: 65944
final_rank: 11