//const int K = 17;
//int x,y,z;
//vi decode(int s){
//    int last = -1;
//    vi ans;
//    rep(i,0,K-1)
//        if(s&(1<<i)){
//            ans.pb(i-last);
//            last = i;
//        }
//    return ans;
//}
//int encode(vi arr){
//    int ans = 0, s = 0;
//    for(int x : arr){
//        ans |= 1 << (x+s-1);
//        s += x;
//    }
//    assert(s <= K);
//    return ans;
//}
//bool sat[1<<K];
//vi adj[1<<K];
//bool does_sat(vi arr){
//    for(int i = 1; i < sz(arr); ++i)
//        arr[i] += arr[i-1];
//    vi to_search = {z,y+z,x+y+z};
//    int l = 0;
//    for(int x : arr)
//        if(x == to_search[l]){
//            ++l;
//            if(l == 3)
//                return true;
//        }
//    return false;
//}
//const int N = 41;
//ll dp[1<<K][N][2];
//void _(){
//    int n;
//    cin >> n >> x >> y >> z;
//    for(int i = 0; i < (1<<K); ++i){
//        vi tmp = decode(i);
//        sat[i] = does_sat(tmp);
//        rep(x,1,10){
//            vi nxt = tmp;
//            nxt.insert(nxt.begin(),x);
//            while(sum(nxt) > K)
//                nxt.pop_back();
//            adj[i].pb(encode(nxt));
//        }
//    }
//    dp[encode({})][0][0] = 1;
//    rep(i,0,n-1){
//        rep(bm,0,(1<<K)-1){
//            rep(is_sat,0,1){
//                for(int v : adj[bm]){
//                    dp[v][i+1][is_sat|sat[v]] += dp[bm][i][is_sat];
//                    dp[v][i+1][is_sat|sat[v]] %= MOD;
//                }
//            }
//        }
//    }
//    ll ans = 0;
//    rep(bm,0,(1<<K)-1)
//        ans += dp[bm][n][1];
//    print(ans%MOD);
//}
#include <iomanip>
#include <cassert>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#define pb push_back
#define REP_INT(i,l,r) for(int i = l; i <= r; ++i)
#define GET_REP_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define rep(...) GET_REP_MACRO(__VA_ARGS__,REP_ANY,REP_INT)(__VA_ARGS__)
#define all(v) (v).begin(), (v).end()
#define sz(v) ll(v.size())
#define T1 template<typename T> static
using namespace std;
typedef long long ll;
typedef vector<int> vi;
const ll MOD = 1e9 + 7;
T1 ostream& operator<<(ostream& stream, const vector<T>& t);
T1 istream& read(T, T, istream& = cin);
T1 void print(T x, string end = "\n"){
    cout << x << end;
}
T1 T sum(vector<T>& arr){
    T ans = 0;
    for(auto x : arr)
        ans += x;
    return ans;
}
const int K = 17;
int x,y,z;
vi decode(int s){
    int last = -1;
    vi ans;
    rep(i,0,K-1)
        if(s&(1<<i)){
            ans.pb(i-last);
            last = i;
        }
    return ans;
}
int encode(vi arr){
    int ans = 0, s = 0;
    for(int x : arr){
        ans |= 1 << (x+s-1);
        s += x;
    }
    assert(s <= K);
    return ans;
}
bool sat[1<<K];
vi adj[1<<K];
bool does_sat(vi arr){
    for(int i = 1; i < sz(arr); ++i)
        arr[i] += arr[i-1];
    vi to_search = {z,y+z,x+y+z};
    int l = 0;
    for(int x : arr)
        if(x == to_search[l]){
            ++l;
            if(l == 3)
                return true;
        }
    return false;
}
const int N = 41;
ll dp[1<<K][N][2];
void _(){
    int n;
    cin >> n >> x >> y >> z;
    for(int i = 0; i < (1<<K); ++i){
        vi tmp = decode(i);
        sat[i] = does_sat(tmp);
        rep(x,1,10){
            vi nxt = tmp;
            nxt.insert(nxt.begin(),x);
            while(sum(nxt) > K)
                nxt.pop_back();
            adj[i].pb(encode(nxt));
        }
    }
    dp[encode({})][0][0] = 1;
    rep(i,0,n-1){
        rep(bm,0,(1<<K)-1){
            rep(is_sat,0,1){
                for(int v : adj[bm]){
                    dp[v][i+1][is_sat|sat[v]] += dp[bm][i][is_sat];
                    dp[v][i+1][is_sat|sat[v]] %= MOD;
                }
            }
        }
    }
    ll ans = 0;
    rep(bm,0,(1<<K)-1)
        ans += dp[bm][n][1];
    print(ans%MOD);
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
        _();
}


Measured memory_bytes: 97664