#include <bits/stdc++.h>
using namespace std;
#define iinf 2000000000
#define linf 1000000000000000000LL
#define ulinf 10000000000000000000ull
#define MOD1 1000000007
#define lson(v) ((v)<<1)
#define rson(v) (((v)<<1)^1)
#define mpr make_pair
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned long UL;
typedef unsigned short US;
typedef pair < int , int > pii;
clock_t __stt;
inline void TStart(){__stt=clock();}
inline void TReport(){printf("\nTaken Time : %.3lf sec\n",(double)(clock()-__stt)/CLOCKS_PER_SEC);}
template < typename T > T MIN(T a,T b){return a<b?a:b;}
template < typename T > T MAX(T a,T b){return a>b?a:b;}
template < typename T > T ABS(T a){return a>0?a:(-a);}
template < typename T > void UMIN(T &a,T b){if(b<a) a=b;}
template < typename T > void UMAX(T &a,T b){if(b>a) a=b;}
int n,x,y,z;
vector < vector < int > > hks,p1,p2,p3;
vector < int > cur;
class trie{
	public:
		trie *nxt[10],*fail;
		int dp[41][3],ct,tct;
		trie(){
			ct=tct=0;
			memset(nxt,0,sizeof(nxt));
			fail=0;
			memset(dp,0,sizeof(dp));
		}
}*root=new trie;
vector < trie* > nodes;
void insert(trie *ver,vector < int > &V,int pos){
	if(pos==(int)V.size()){
		ver->ct=1;
		return;
	}
	int val=V[pos];
	if(!(ver->nxt[val])){
		ver->nxt[val]=new trie;
		nodes.push_back(ver->nxt[val]);
	}
	insert(ver->nxt[val],V,pos+1);
}
trie *find(trie *ver,vector < int > &V,int pos){
	if(pos==(int)V.size()){
		return ver;
	}
	int val=V[pos];
	if(!(ver->nxt[val])) return 0;
	return find(ver->nxt[val],V,pos+1);
}
void getfail(trie *ver,vector < int > &V){
	int xb=100,acv=100;
	ver->tct=ver->ct;
	for(xb=1;xb<(int)V.size();++xb){
		trie *ptr=find(root,V,xb);
		if(ptr){
			UMIN(acv,xb);
			ver->tct+=ptr->ct;
		}
	}
	if(acv<(int)V.size()) ver->fail=find(root,V,acv); else ver->fail=root;
	for(xb=0;xb<10;++xb){
		if(!(ver->nxt[xb])) continue;
		V.push_back(xb);
		getfail(ver->nxt[xb],V);
		V.pop_back();
	}
}
void gethaiku(vector < vector < int > > &prt,int lim){
	if(lim==0) prt.push_back(cur);
	if(lim<=0) return;
	int xb;
	for(xb=1;xb<=10;++xb){
		cur.push_back(xb-1);
		gethaiku(prt,lim-xb);
		cur.pop_back();
	}
}
int main(){
    // inputing start
	nodes.push_back(root);
    scanf("%d%d%d%d",&n,&x,&y,&z);
	int xb,x2,x3,x4,cnt=0;
    #ifdef LOCAL
        TStart();
    #endif
    // calculation start
    cur.clear();
	gethaiku(p1,x);
	gethaiku(p2,y);
	gethaiku(p3,z);
	hks.resize(p1.size()*p2.size()*p3.size());
	
	for(xb=0;xb<(int)p1.size();++xb){
		for(x2=0;x2<(int)p2.size();++x2){
			for(x3=0;x3<(int)p3.size();++x3){
				hks[cnt].clear();
				for(x4=0;x4<(int)p1[xb].size();++x4)
					hks[cnt].push_back(p1[xb][x4]);
				for(x4=0;x4<(int)p2[x2].size();++x4)
					hks[cnt].push_back(p2[x2][x4]);
				for(x4=0;x4<(int)p3[x3].size();++x4)
					hks[cnt].push_back(p3[x3][x4]);
				insert(root,hks[cnt],0);
				++cnt;
			}
		}
	}
	cur.clear();
	
	getfail(root,cur);
	
	root->dp[0][0]=1;
	for(xb=0;xb<n;++xb){
		for(x2=0;x2<3;++x2){
			for(x3=0;x3<(int)nodes.size();++x3){
				trie *cr=nodes[x3],*ncr;
				if(cr->dp[xb][x2]) for(x4=0;x4<10;++x4){
					for(ncr=cr;!(ncr->nxt[x4]) && ncr!=root;ncr=ncr->fail);
					if(ncr->nxt[x4]) ncr=ncr->nxt[x4];
					int nv=(x2+ncr->tct)%2;
					if(x2==0 && ncr->tct==0) nv=0; else nv=2-nv;
					ncr->dp[xb+1][nv]=(ncr->dp[xb+1][nv]+cr->dp[xb][x2])%MOD1;
					//printf("%I64d->dp[%d][%d]+=%d->dp[%d][%d]   %d\n",(LL)ncr,xb+1,nv,x3,xb,x2,cr->dp[xb][x2]);
				}
			}
		}
	}
	
	int res=0;
	for(xb=0;xb<(int)nodes.size();++xb){
		trie *cr=nodes[xb];
		for(x2=1;x2<3;++x2){
			res+=cr->dp[n][x2];
			res%=MOD1;
		}
	}
	printf("%d\n",res);
    #ifdef LOCAL
        TReport();
    #endif
    return 0;
}

Measured memory_bytes: 22136