//#pragma GCC optimize ("-O3","unroll-loops")
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include <random>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end());
#define ll long long
#define pb(a) push_back(a)
#define print(x) cout<<x<<'\n';
#define pe(x) cout<<x<<" ";
#define lb(v,n) lower_bound(v.begin(), v.end(), n);
#define ub(v,n) upper_bound(v.begin(), v.end(), n);
#define int long long
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ");
//#define double long double



template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }

const int MOD = 1e9 + 7;
int n, x, y, z, l, ng;
ll dp[41][1 << 16], ans;
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	cin >> n >> x >> y >> z;
	l = x + y + z - 1;
	int m = (1 << l) - 1;
	ng = (1 << l) | (1 << (l - x)) | (1 << (l - x - y));
	dp[0][0] = 1;
	REP(i, n) {
		FOR(a, 1, 11) {
			REP(s, 1 << l) {
				int t = (s << a) | (1 << (a - 1));
				if ((ng & t) != ng)dp[i + 1][t & m] = (dp[i + 1][t & m] + dp[i][s]) % MOD;

			}
		}
	}
	ans = 1;
	REP(i, n)ans = ans * 10 % MOD;
	REP(s, 1 << l) {
		ans += MOD - dp[n][s]; ans %= MOD;
	}
	print(ans);
}

#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iterator>
#include <assert.h>
#pragma warning(disable:4996) 
 
typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF  9223300000000000000
#define LINF2 1223300000000000000
#define INF 2140000000
//const long long MOD = 1000000007;
//const long long MOD = 998244353;
long long MOD;

using namespace std;

ll dp[6010][8005];

void solve()
{
    int n;
    scanf("%d%lld", &n, &MOD);

    dp[0][n] = 1;   // dp[i][j]: 後ろからi文字目まで選択済で、ただし残る2マス数が残る1マス数よりj-n個多い場合の数
    int i, j;
    for (i = 0; i < n * 3; i++) {
        for (j = 0; j <= n*4; j++) {
            if (dp[i][j]) {
                if(j+1<=n*4) dp[i + 1][j + 1] = (dp[i + 1][j + 1] + dp[i][j]) % MOD;
                if(i+2<=n*3 && j-1>=0)   dp[i + 2][j - 1] = (dp[i + 2][j - 1] + dp[i][j] * (n*3-i-1) % MOD) % MOD;
                if(i+3<=n*3) dp[i + 3][j] = (dp[i + 3][j] + dp[i][j] * (n * 3 - i - 1) % MOD * (n * 3 - i - 2) % MOD) % MOD;            
            }
        }
    }
    ll ans = 0;
    for (j = n; j <= n * 4; j++) {
        ans = (ans + dp[n * 3][j]) %MOD;
    }
    printf("%lld\n", ans);

    return;
}

int main(int argc, char* argv[])
{
#if 1
    solve();
#else
    int T; scanf("%d", &T);
    while(T--) {
        solve();
    }
#endif
    return 0;
}
