#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <map> 
#include <string>
#include <vector>  
#include <iostream> 
#include <sstream> 
#include <queue>
#include <algorithm>
#include <assert.h>


using namespace std;

#define ll long long
#define PB 		push_back
#define FOR(a,start,end) 	for(int a=int(start); a<int(end); a++)
#define INF 		INT_MAX
#define SORT(a) 	sort(a.begin(),a.end()) 
#define CL(a,x) 		memset(a,x,sizeof(a))
#define REP(a,x)	for(int a=0;a<x;a++)
#define REP1(a,x)	for(int a=1;a<=x;a++)
#define MP 		make_pair



typedef vector<ll>     vi;
typedef pair<ll, ll>     pii;
typedef vector<string> vs;
typedef vector<pii> vii;
typedef vector<vector<ll> > vvi;
typedef vector<vector<string> > vvs;
typedef vector<pair<string, string> > vss;
typedef pair<string, string> pss;
typedef pair<ll, pii> ppii;
typedef vector<ppii> vppii;
typedef vector<vector<pii> > vvii;
typedef vector<vvi> vvvi;


ll n, k, a, b, c, d, i, j, q, t, z, m, s;
ll b1, c0, c1,z12,z13,z23,z123,z1,z2,z3;
vi vk, va, vb;
vvi vvk, vva;
vii vkx, vbx, vax2;
pii pa1, pa2, pb1, pb2;
vector<pair<ll, string> > vx;
pair<ll, string> p1, p2;
string w;

ll gt[10001], igt[10001];		//gt = n!, igt - n! inverse


long long npok(long long n, long long k, long long d) {
	long long z;

	z = (((gt[n] * igt[k]) % d)*igt[n - k]) % d;

	return z;
}
long long powmod(long long a, long long m, long long d) {
	if (m == 0) return 1;
	long long r = powmod(a, m / 2, d);
	if (m % 2) return r * (long long)r % d * a % d;
	else return r * (long long)r % d;
}
int main() {
	//freopen("c:\\wojtek\\uva\\pa\\debug\\t1.in", "rt", stdin);
	//freopen("c:\\cygwin64\\home\\PLWOKOW\\.check_sol\\kul\\tests\\B304.in", "rt", stdin);
	//pi=2*acos(0.0);
	cin >> n;
	d = 1000000007;
	vx.clear();
	
	gt[0] = 1;
	for (i = 1; i <= 5000; ++i) gt[i] = i * (ll)gt[i - 1] % d;
	for (i = 0; i <= 5000; ++i) igt[i] = powmod(gt[i], d - 2, d);

	for (int i = 0; i < 3; i++) {
		cin >> a >> w;
		vx.push_back(MP(a, w));
	}
	if (vx[1].first > vx[0].first)
		vx[1].swap(vx[0]);
	if (vx[2].first > vx[1].first)
		vx[1].swap(vx[2]);
	if (vx[1].first > vx[0].first)
		vx[1].swap(vx[0]);
	for (int i = 0; i < n; i++) {
		a = vx[0].second[i] - '0';
		for (int j = 0; j < 3; j++)
			vx[j].second[i] = ((vx[j].second[i] - '0') ^ a) + '0';
	}
	a = 0;
	b1 = 0;
	c0 = 0;
	c1 = 0;
	for (int i = 0; i < n; i++) {
		if (vx[1].second[i] == '1') {
			b1++;
			if (vx[2].second[i] == '1')
				c1++;
		}
		else {
			if (vx[2].second[i] == '1')
				c0++;
		}
	}

	z = 0;
	for (int i = 0; i <= vx[0].first; i++) {
		z += npok(n, i, d);
		z %= d;
		if (i == vx[1].first)
			z2 = z;
		if (i == vx[2].first)
			z3 = z;
	}
	z1 = z;
	//
	if (vx[0].first + vx[1].first < b1)//rozłączne
		z12 = 0;
	else if (b1 + vx[1].first <= vx[0].first)//pełne pokrycie
		z12 = z2;

	else {
		z12 = 0;
		for (int i = max(0ll, -vx[0].first + b1); i <= vx[1].first; i++) {
		//	for (int j = max(0ll,(b1+i-vx[0].first)/2); j <= min((ll)i, b1); j++) {//j z b1 ,i-j z b0
			for (int j = 0; j <= min((ll)i,b1); j++) {//j z b1 ,i-j z b0
				if (b1 - j + i - j <= vx[0].first) {
					z12 += (npok(b1, j, d)*npok(n - b1, i-j, d))%d;
					z12 %= d;
				}
			}
		}
	}
	if (vx[0].first + vx[2].first < c1+c0)//rozłączne
		z13 = 0;
	else if (c1+c0 + vx[2].first <= vx[0].first)//pełne pokrycie
		z13 = z3;

	else {
		z13 = 0;
		for (int i = max(0ll, -vx[0].first  + (c1+c0)); i <= vx[2].first; i++) {
		//	for (int j = max(0ll,(c0+c1+i-vx[0].first)/2); j <= min((ll)i, c1 + c0); j++) {//j z b1 ,i-j z b0
			for (int j = 0; j <= min((ll)i,c1+c0); j++) {//j z b1 ,i-j z b0
				if (c0+c1 - j + i - j <= vx[0].first) {
					z13 += (npok(c1+c0, j, d)*npok(n - (c1+c0), i-j, d))%d;
					z13 %= d;
				}
			}
		}
	}
	c = b1 - c1 + c0;
	if (vx[1].first + vx[2].first < c)//rozłączne
		z23 = 0;
	else if (c + vx[2].first <= vx[1].first)//pełne pokrycie
		z23 = z3;
	
	else {
		z23 = 0;
		for (int i = max(0ll, -vx[1].first  + c); i <= vx[2].first; i++) {
		//	for (int j = max(0ll,(c+i-vx[1].first)/2); j <= min((ll)i, c); j++) {//j z b1 ,i-j z b0
			for (int j = 0; j <=min((ll) i,c); j++) {//j z b1 ,i-j z b0
				if (c - j + i - j <= vx[1].first) {
					z23 += (npok(c, j, d)*npok(n - c, i-j, d))%d;
					z23 %= d;
				}
			}
		}
	}
	//
	/*
	if (vx[0].first + vx[1].first < b1)//rozłączne
		z123 = 0;
	else if (b1 + vx[1].first <= vx[0].first)//pełne pokrycie
		z123 = z2;
	else {
	*/
	z123 = 0;
	if ((z12 == z1) && (z12 == z2))
		z123 = z13;
	else if ((z13 == z1) && (z13 == z3))
		z123 = z12;
	else if ((z23 == z2) && (z23 == z3))
		z123 = z12;
	else if (z12 > 0 && z13 > 0 && z23 > 0) {

		for (int i = max(0ll, -vx[0].first  + b1); i <= vx[1].first; i++) {
		//	for (int j = max(0ll,(b1+i-vx[0].first)/2); j <= min((ll)i, b1); j++) {//j z b1 ,i-j z b0
			for (int j = 0; j <= min((ll)i, b1); j++) {//j z b1 ,i-j z b0
				if (b1 - j + i - j <= vx[0].first) {

					for (int i2 = 0; i2 <= min(c1, vx[2].first); i2++) {
						if ((c1 - i2 <= b1 - j) && (i2 + (b1 - j) - (c1 - i2) <= vx[2].first)) {

							ll g = (npok(c1, i2, d)*npok(b1 - c1, b1 - j - (c1 - i2), d)) % d;
							for (int i0 = 0; i0 <= min(c0, vx[2].first - (i2 + (b1 - j) - (c1 - i2))); i0++) {
								if (((c0 - i0) <= i - j) && (i2 + (b1 - j) - (c1 - i2) + i0 + (i - j) - (c0 - i0)) <= vx[2].first) {

									z123 += ((g * npok(c0, i0, d)) % d)*npok(n - b1 - c0, i - j - (c0 - i0), d);
									z123 %= d;
								}
							}

						}
					}


				}
			}
		}
	}
		z = z1 + z2 + z3 - z12 - z13 - z23 + z123;
		z += 3 * d;
		z %= d;
		cout << z << endl;

	return 0;

}
