Problem:
Score : 700 points

Problem Statement

Haiku is a short form of Japanese poetry. A Haiku consists of three phrases with 5, 7 and 5 syllables, in this order.

Iroha is looking for X,Y,Z-Haiku (defined below) in integer sequences.

Consider all integer sequences of length N whose elements are between 1 and 10, inclusive. Out of those 10^N sequences, how many contain an X,Y,Z-Haiku?

Here, an integer sequence a_0, a_1, ..., a_{N-1} is said to contain an X,Y,Z-Haiku if and only if there exist four indices x, y, z, w (0 ≦ x < y < z < w ≦ N) such that all of the following are satisfied:

a_x + a_{x+1} + ... + a_{y-1} = X

a_y + a_{y+1} + ... + a_{z-1} = Y

a_z + a_{z+1} + ... + a_{w-1} = Z

Since the answer can be extremely large, print the number modulo 10^9+7.

Constraints

3 ≦ N ≦ 40

1 ≦ X ≦ 5

1 ≦ Y ≦ 7

1 ≦ Z ≦ 5

Input

The input is given from Standard Input in the following format:

N X Y Z

Output

Print the number of the sequences that contain an X,Y,Z-Haiku, modulo 10^9+7.

Sample Input 1

3 5 7 5

Sample Output 1

1

Here, the only sequence that contains a 5,7,5-Haiku is [5, 7, 5].

Sample Input 2

4 5 7 5

Sample Output 2

34

Sample Input 3

37 4 2 3

Sample Output 3

863912418

Sample Input 4

40 5 7 5

Sample Output 4

562805100

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

// In the name of God

#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <deque>
#include <assert.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <stdio.h>
#include <string.h>
#include <utility>
#include <math.h>
#include <bitset>
#include <iomanip>

using namespace std;

#define rep(i, n) for (int i = 0, _n = (int)(n); i < _n; ++i)

const int N = 45, K = 17, mod = (int) 1e9 + 7;
int dp[N][K + 1][1 << K][2], haiku[K + 1][1 << K], tlen[1 << K][K + 1][K + 1], tmask[1 << K][K + 1][K + 1];
void sadd(int &x, int y) {
    x += y;
    if (x >= mod)
        x -= mod;
    if (x < 0)
        x += mod;
}
int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n, x, y, z;
    cin >> n >> x >> y >> z;
    for (int mask = 0; mask < (1 << (x + y + z)); ++mask) {
        haiku[x + y + z][mask] = (mask >> (x - 1) & 1) & (mask >> (x + y - 1) & 1) & (mask >> (x + y + z - 1) & 1);
    }
    for (int len = 0; len <= x + y + z; ++len)
        for (int dig = 1; dig <= 10; ++dig)
            for (int lmask = 0; lmask < (1 << len); ++lmask) if (!len || lmask >> (len - 1) & 1) {
                if (dig > x + y + z) {
                    tlen[lmask][dig][len] = 0;
                    tmask[lmask][dig][len] = 0;
                    continue;
                }
                int nwlen = dig + len, mask = (lmask << dig) | (1 << (dig - 1));
                while (nwlen > x + y + z) {
                    mask -= 1 << (nwlen - 1);
                    for (int j = nwlen - 1; j >= 0; --j)
                        if (mask >> j & 1) {
                            nwlen = j + 1;
                            break;
                        }
                }
                tlen[lmask][dig][len] = nwlen;
                tmask[lmask][dig][len] = mask;
                
            }
    int l = x + y + z;
    dp[0][0][0][0] = 1;
    for (int dig = 1; dig <= n; ++dig) {
//        cout << dig << endl;
        for (int cur_dig = 1; cur_dig <= 10; ++cur_dig) {
            for (int len = 0; len <= l; ++len) {
                for (int lmask = len? (1 << len - 1): 0; lmask < (1 << len); ++lmask) if (!len || lmask >> (len - 1) & 1) {
                    int to_mask = tmask[lmask][cur_dig][len], to_len = tlen[lmask][cur_dig][len];
                    for (int has = 0; has < 2; ++has) {
                        sadd(dp[dig][to_len][to_mask][haiku[to_len][to_mask] | has], dp[dig - 1][len][lmask][has]);
                    }
                }
            }
        }
    }
    int res = 0;
    for (int len = 0; len <= l; ++len)
        for (int mask = 0; mask < (1 << len); ++mask) {
            if (0 && dp[n][len][mask][1]) {
                cout << n << ' ' << len << ' ' << mask << ' ' << haiku[len][mask] << endl;
                for (int i = 0; i < len; ++i)
                    cout << (mask >> i & 1);
                cout << endl << endl;
            }
            sadd(res, dp[n][len][mask][1]);
        }
    cout << res << endl;


}