#include<bits/stdc++.h>

using namespace std;

const int MAXN = 50005;
const int MOD = 1000000007;

int n, x, y, z, cnt;
int p[10][MAXN], fin[10][MAXN], t[MAXN];
int dp[2][45][MAXN];
map <string, int> mp;
string r[MAXN];

vector <string> f (int x) {
    vector <string> res;
    if (x == 0) {
        res.push_back("");
        return res;
    }
    for (int i=0; i<x; i++) {
        vector <string> tmp = f(i);
        for (auto s : tmp) res.push_back(((char) (x - i + '0')) + s);
    }
    return res;
}

void ubaci (string s) {
    int len = s.size();
    int curr = 0;
    for (int i=0; i<len; i++) {
        int d = s[i] - '0';
        if (p[d][curr] == 0) p[d][curr] = ++cnt;
        curr = p[d][curr];
    }
    t[curr] = 1;
}

void dfs (string s, int br) {
    mp[s] = br;
    r[br] = s;
    for (int i=0; i<10; i++) {
        if (p[i][br]) dfs(s + ((char) (i + '0')), p[i][br]);
    }
}

void gen () {
    vector <string> sx = f(x), sy = f(y), sz = f(z);
    for (auto s1 : sx) {
        for (auto s2 : sy) {
            for (auto s3 : sz) {
                ubaci(s1 + s2 + s3);
            }
        }
    }
    mp[""] = 0;
    dfs("", 0);
    for (int i=0; i<=cnt; i++) {
        int len = r[i].size();
        for (int j=len; j>=0; j--) {
            string suf = r[i].substr(j);
            if (mp.find(suf) != mp.end()) {
                int ind = mp[suf];
                for (int k=0; k<10; k++) {
                    if (p[k][ind] != 0) fin[k][i] = p[k][ind];
                }
            }
        }
    }
}

int f (int flg, int pos, int br) {
    //for (int i=0; i<pos; i++) cout << " ";
    //cout << "bla " << flg << " " << pos << " " << br << endl;
    if (dp[flg][pos][br] != -1) return dp[flg][pos][br];
    if (pos == n) return flg;
    int res = 0;
    for (int i=0; i<10; i++) {
        res = (res + f(flg | t[fin[i][br]], pos + 1, fin[i][br])) % MOD;
    }
    return dp[flg][pos][br] = res;
}

int main () {
    memset(dp, -1, sizeof dp);
    cin >> n >> x >> y >> z;
    gen();
    cout << f(0, 0, 0);
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

long long MOD = 1e9+7;
int main() {
  // U: 3^N fits, which hints towards a fancy subset DP
  // i.e. the one that is magically 3^n when it looks like
  // it should be 2^2n

  cin.tie(0);
  cin.sync_with_stdio(0);
  int n; cin >> n;

  long long a[n][n];
  for(int i = 0; i<n; ++i) {
    for(int j = 0; j<n; ++j) {
      cin >> a[i][j];
    }
  }

  // first, compute the costs of every subset (if grouped)
  long long costs[1<<n];
  for(int i = 0; i<(1<<n); ++i) {
    vector<int> in_group;
    for(int j = 0; j<n; ++j) {
      if((i >> j) & 1) {
        in_group.push_back(j);
      }
    }
    costs[i] = 0;
    for(int j = 0; j<in_group.size(); ++j) {
      for(int k = j+1; k<in_group.size(); ++k) {
        costs[i] += a[in_group[j]][in_group[k]];
      }
    }
  }

  // next, magic
  long long dp[1<<n];
  for(int i = 0; i<(1<<n); ++i) {
    dp[i] = LLONG_MIN;
  }
  dp[0] = 0;
  for(int i = 0; i<(1<<n); ++i) {
    // ugh I can't quite remember it...
    int j = i;
    do {
      j = (j - 1) & i; // go through all masks containing i as a submask...
      dp[i] = max(dp[i], dp[j] + costs[i^j]);
    } while (j != i);
  }

  cout << dp[(1<<n)-1] << endl;
}
