#include<iostream>
#include<iomanip>
#include<map>
#include<set>
#include<vector>
#include<string>
#include<stack>
#include<array>
#include<queue>
#include<algorithm>
#include<cassert>
#include<functional>
#include<numeric>
#include<random>
#define int int64_t
#define REP(i, a, b) for (int64_t i = (int64_t)(a); i < (int64_t)(b); i++)
#define rep(i, a) REP(i, 0, a)
#define EACH(i, a) for (auto i: a)
#define ITR(x, a) for (auto x = a.begin(); x != a.end(); x++)
#define ALL(a) (a.begin()), (a.end())
#define HAS(a, x) (a.find(x) != a.end())
using namespace std;

template<int MOD = 1000000007>class modint {
	//MODが素数であることを前提として実装してあるが、その判定はしていない。
	//あまりが出るような除算をしてはいけない。
public:
	modint() {
		//assert(is_prime());
		this->number = 0;
	}
	modint(int src) {
		//assert(is_prime());
		this->number = src;
	}
	modint<MOD> operator + (const modint<MOD> obj) {
		modint re((this->number + obj.number) % MOD);
		return re;
	}
	modint<MOD> operator + (const int n) {
		modint re((this->number + opposit(n)) % MOD);
		return re;
	}
	modint<MOD>& operator += (const modint<MOD>& obj) {
		this->number = (this->number + obj.number) % MOD;
		return *this;
	}
	modint<MOD>& operator += (const int n) {
		this->number = (this->number + opposit(n)) % MOD;
		return *this;
	}
	modint<MOD> operator - (const modint<MOD> obj) {
		modint re((this->number - obj.number + MOD) % MOD);
		return re;
	}
	modint<MOD> operator - (const int n) {
		modint re((this->number - opposit(n) + MOD) % MOD);
		return re;
	}
	modint<MOD>& operator -= (const modint<MOD>& obj) {
		this->number = (this->number - obj.number + MOD) % MOD;
		return *this;
	}
	modint<MOD>& operator -= (const int n) {
		this->number = (this->number - opposit(n) + MOD) % MOD;
		return *this;
	}
	modint<MOD> operator * (const modint<MOD> obj) {
		modint re((this->number * obj.number) % MOD);
		return re;
	}
	modint<MOD> operator * (const int n) {
		modint re((this->number * opposit(n)) % MOD);
		return re;
	}
	modint<MOD>& operator *= (const modint<MOD>& obj) {
		this->number = (this->number * obj.number) % MOD;
		return *this;
	}
	modint<MOD>& operator *= (const int n) {
		this->number = (this->number * opposit(n)) % MOD;
		return *this;
	}
	modint<MOD> operator / (const modint<MOD> obj) {
		modint re((this->number * inverse(obj.number)) % MOD);
		return re;
	}
	modint<MOD> operator / (const int n) {
		modint re((this->number * inverse(n)) % MOD);
		return re;
	}
	modint<MOD>& operator /= (const modint<MOD>& obj) {
		this->number = (this->number * inverse(obj.number)) % MOD;
		return *this;
	}
	modint<MOD>& operator /= (const int n) {
		this->number = (this->number * inverse(n)) % MOD;
		return *this;
	}
	modint operator = (const int n) {
		this->number = opposit(n) % MOD;
		return *this;
	}
	int get() {
		return number;
	}

private:
	int number;

	int opposit(int n) {
		if (n < 0)n = MOD - ((-n) % MOD);
		return n % MOD;
	}
	int inverse(int n) {
		n = opposit(n);
		int result = 1;
		for (int i = MOD - 2; i; i /= 2) {
			if (i % 2)result = (result * n) % MOD;
			n = (n * n) % MOD;
		}
		return result;
	}
	bool is_prime() {

		if (MOD <= 1)return false;
		if (MOD == 2)return true;
		if (MOD % 2 == 0) return false;

		int upperbound = sqrt(MOD);
		for (int i = 3; i <= upperbound; i += 2) {
			if (MOD % i == 0) return false;
		}

		return true;
	}
};




signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N, X, Y, Z;
	cin >> N >> X >> Y >> Z;
	const int m = 1LL << (X + Y + Z);
	const int tas = (1 << (Z - 1)) | (1 << (Y + Z - 1)) | (1 << (X + Y + Z - 1));

	vector<vector<modint<>>>memo;
	memo.resize(N + 1);
	rep(i, N + 1)memo[i].resize(m + 1);
	memo[0][0] = 1;
	//memo[i][j]:=数列のi項目に着目して、かつ
	//j < m: 直前の数列がjである(解説通りのbitDPでエンコードされているとする)ような数列の数。
	//j == m: i項目までにXYZを含むような数列の数。

	rep(i, N)for (int mask = 0; mask <= m; mask++)if (memo[i][mask].get()) {
		for (int j = 1; j <= 10; j++) {
			if (mask == m) {
				//memo[i + 1][m] += memo[i][m] * 10;を意味する。
				//i項目までにXYZを含むような数列は、i+1項目の数がなんでも良いので10倍する。
				memo[i + 1][m] += memo[i][m];
				continue;
			}
			int nmask = ((mask << j) | (1LL << (j - 1))) & (m - 1);
			if ((nmask & tas) == tas)nmask = m;
			memo[i + 1][nmask] += memo[i][mask];
		}
	}

	cout << memo[N][m].get() << endl;

}

Measured memory_bytes: 42368