// Date: 2020-02-29

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

typedef long long LL;
typedef long double LD;
typedef vector<int> VI;
typedef pair<LL, LL> pll;
typedef pair<int, int> pii;
#define FIO ios::sync_with_stdio(false);cin.tie(0)
#define rep(i, a, b) for(int i = int(a); i <= int(b); ++i)
#define per(i, b, a) for(int i = int(b); i >= int(a); --i)
#define mem(x, y) memset(x, y, sizeof(x))
#define all(x) (x).begin(),(x).end()
#define mk make_pair
#define pb push_back
#define fi first
#define se second
const LL INF = 1e18;
const LL mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int N = 5e5 + 10;
template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }
LL qpow(LL x, LL y, LL MOD) {LL a=1; while(y){ if(y&1) a=a*x%MOD; x=x*x%MOD; y>>=1; } return a;}

LL dp[42][N];
int n, x, y, z;
int a[10], cntx[10], cnty[10], cntz[10];
vector<string> vx, vy, vz;

void dfs(int u, int dep, int sum, int n, int cnt[], vector<string>& v) {
    if(sum > n) return;
    if(u > dep) {
        if(sum == n) {
            cnt[dep]++;
            string s;
            rep(i, 1, dep) s += (char)(a[i]+'a'-1);
            v.pb(s);
        }
        return;
    }
    rep(i, 1, n) a[u] = i, dfs(u+1, dep, sum + a[u], n, cnt, v);
}

void add(LL& x, LL y) {
    x = (x + y) % mod;
}

struct Trie {
    int nxt[N][10], fail[N], ok[N];
    int root, tot;
    int newnode() {
        for(int i = 0; i < 10; ++i)
            nxt[tot][i] = -1;
        ok[tot] = 0;
        return tot++;
    }
    void init() {
        tot = 0;
        root = newnode();
    }
    void insert(string buf) {
        int len = buf.size();
        int now = root;
        for(int i = 0; i < len; ++i) {
            if(nxt[now][buf[i]-'a'] == -1)
                nxt[now][buf[i]-'a'] = newnode();
            now = nxt[now][buf[i]-'a'];
        }
        ok[now] = 1;
    }
    void build() {
        queue<int> Q;
        fail[root] = root;
        for(int i = 0; i < 10; i++) {
            if(nxt[root][i] == -1) nxt[root][i] = root;
            else {
                fail[nxt[root][i]] = root;
                Q.push(nxt[root][i]);
            }
        }
        while(!Q.empty()) {
            int now = Q.front(); Q.pop();
            ok[now] |= ok[fail[now]];
            for(int i = 0; i < 10; ++i) {
                if(nxt[now][i] == -1) {
                    nxt[now][i] = nxt[fail[now]][i];
                }
                else {
                    fail[nxt[now][i]] = nxt[fail[now]][i];
                    Q.push(nxt[now][i]);
                }
            }
        }
    }


    LL solve() {
        dp[0][0] = 1;
        rep(i, 0, n) rep(j, 0, tot-1) if(!ok[j]) rep(k, 0, 9) {
            int to = nxt[j][k];
            if(!ok[to]) add(dp[i+1][to], dp[i][j]);
        }
        LL ans = 0;
        rep(i, 0, tot-1) add(ans, dp[n][i]);
        return ans;
    }
    
} aho;

int main() {
    scanf("%d%d%d%d", &n, &x, &y, &z);
    rep(i, 1, x) dfs(1, i, 0, x, cntx, vx);
    rep(i, 1, y) dfs(1, i, 0, y, cnty, vy);
    rep(i, 1, z) dfs(1, i, 0, z, cntz, vz);

    aho.init();
    for(auto s1 : vx) for(auto s2 : vy) for(auto s3 : vz) {
        string s = s1+s2+s3;
        aho.insert(s);
    }
    aho.build();
    LL ans = 1;
    rep(i, 1, n) ans = ans * 10 % mod;
    ans = (ans - aho.solve() + mod) % mod;
    
    printf("%lld\n", ans);

    return 0;
}

Measured memory_bytes: 104064