#define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long double ld; typedef long long ll; typedef vector vint; typedef pair pii; typedef pair pll; typedef pair pdd; typedef complex compd; #define rep(i,n) for(int i=0;i=0;i--) #define RREP(i,n) for(int i=n;i>=0;i--) #define all(a) (a).begin(),(a).end() #define mp(a,b) make_pair(a,b) #define mt make_tuple #define pb push_back #define fst first #define scn second #define bicnt(x) __buildin__popcount(x) #define debug(x) cout<<"debug: "<, ll> dp; //赤青、青緑、緑赤で塗れるだけ塗る(2^個数通り) //余ったところに単色を塗っていく //ここで塗り切れるか判定が出来る bool check(int n, int r, int g, int b) { int use = 0; int rg = min(r, g); use += max(0, 3 * rg - 1); r -= rg; g -= rg; int gb = min(g, b); use += max(0, 3 * gb - (use == 0 ? 1 : 0)); g -= gb; b -= gb; int br = min(b, r); use += max(0, 3 * br - (use == 0 ? 1 : 0)); b -= br; r -= br; use += max(0, 2 * (r + g + b) - (use == 0 ? 1 : 0)); if (use <= n) return true; else return false; } ll solve(int n, int a, int b, int c,bool f) { if (dp.find(mt(n, a, b, c, f)) != dp.end()) return dp[mt(n, a, b, c, f)]; if (n < 0) return 0; if (n >= 0 && a + b + c == 0) return 1; if (!check(n, a, b, c)) return 0; if (!f) return dp[mt(n, a, b, c, f)] = solve(n - 1, a, b, c, true); ll ret = 0; vint dat = { a, b, c }; rep(i, 2){ if (a - i < 0) continue; rep(j, 2) { if (b - j < 0) continue; rep(k, 2) { if (c - k < 0) continue; if (i == j&&j == k) continue; ret += (i + j + k)*solve(n - (i + j + k), a - i, b - j, c - k, false); } } } ret += solve(n - 1, a, b, c, true); return dp[mt(n, a, b, c, f)] = ret%mod; } int main() { int n, r, g, b; cin >> n >> r >> g >> b; cout << solve(n, r, g, b, true) << endl; return 0; }