1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <bits/stdc++.h>
#ifdef LOC
#include "debuglib.h"
#else
#define deb(...)
#define DBP(...)
#endif
using namespace std;
using   ll         = long long;
using   Vi         = vector<int>;
using   Pii        = pair<int, int>;
#define pb           push_back
#define mp           make_pair
#define x            first
#define y            second
#define rep(i, b, e) for (int i = (b); i < (e); i++)
#define each(a, x)   for (auto& a : (x))
#define all(x)       (x).begin(), (x).end()
#define sz(x)        int((x).size())

//#define MAX_TEST

constexpr int MOD = 1e9+7;
constexpr ll MOD_SQR = ll(MOD)*MOD;

vector<ll> fact, factInv;
int prefs[10005][10005];

ll modInv(ll a, ll m = MOD) {
	if (a == 1) return 1;
	return ((a - modInv(m%a, a))*m + 1) / a;
}

ll choose(ll n, ll k) {
	return fact[n] * factInv[k] % MOD * factInv[n-k] % MOD;
}

int main() {
	cin.sync_with_stdio(0); cin.tie(0);
	cout << fixed << setprecision(18);

#ifdef MAX_TEST
	int n = 10000;
	int nSaved = 4800;
	int cnt[4] = {nSaved, n/2-nSaved, n/2-nSaved, nSaved};
	int rad[3] = {1234, 234, 1987};
#else
	int n; cin >> n;
	string str[3];
	int rad[3];

	rep(i, 0, 3) {
		cin >> rad[i] >> str[i];
	}

	int cnt[4] = {};

	rep(i, 0, n) {
		int type = (str[1][i] == '1');
		type |= (str[2][i] == '1') << 1;
		if (str[0][i] == '1') type ^= 3;
		cnt[type]++;
	}
#endif

	fact.resize(n+5, 1);
	factInv.resize(n+5, 1);

	rep(i, 1, n+5) {
		fact[i] = fact[i-1] * i % MOD;
		factInv[i] = modInv(fact[i]);
	}

	rep(ones1, 0, cnt[0]+1) {
		rep(ones2, 0, cnt[3]+1) {
			int a = ones1+ones2;
			int b = ones1-ones2+cnt[3];
			prefs[a][b] = int(choose(cnt[0], ones1) * choose(cnt[3], ones2) % MOD);
		}
	}

	int dim = cnt[0]+cnt[3];

	for (int i = dim; i >= 0; i--) {
		for (int j = dim; j >= 0; j--) {
			int tmp = prefs[i][j] + prefs[i][j+1];
			prefs[i][j] = (tmp >= MOD ? tmp-MOD : tmp);
		}
	}

	for (int i = dim; i >= 0; i--) {
		for (int j = dim; j >= 0; j--) {
			int tmp = prefs[i][j] + prefs[i+1][j];
			prefs[i][j] = (tmp >= MOD ? tmp-MOD : tmp);
		}
	}

	ll ans = 1;
	rep(i, 0, n) ans = ans*2 % MOD;

	rep(ones1, 0, cnt[1]+1) {
		rep(ones2, 0, cnt[2]+1) {
			int a = ones1+ones2;
			int b = cnt[1]-ones1+ones2;
			int c = ones1+cnt[2]-ones2;

			int ra = rad[0]-a+1;
			int rb = max(rad[1]-b+1, rad[2]-c+1);

			ra = min(max(ra, 0), 10001);
			rb = min(max(rb, 0), 10001);

			ll opt1 = choose(cnt[1], ones1) * choose(cnt[2], ones2) % MOD;
			ll opt2 = prefs[ra][rb];
			ans -= opt1*opt2;
			if (ans < 0) ans += MOD_SQR;
		}
	}

	ans %= MOD;
	if (ans < 0) ans += MOD;
	cout << ans << '\n';
	return 0;
}