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
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1000000007;

//NUMERIC SECTOR
long long power(long long b, int e){
	if(e==0)
		return 1;
	long long x = power(b, e/2);
	x = (x*x)%MOD;
	return (e%2)?(x*b%MOD):x;
}
long long inverse(long long x){
	return power(x, MOD-2);
}
vector<long long>FactTab,InvFactTab;
void prepareFactorialTab(int mx){
	if(FactTab.empty()){
		FactTab.push_back(1);
		FactTab.push_back(1);
		InvFactTab.push_back(1);
		InvFactTab.push_back(1);
	}
	while((int)FactTab.size()<=mx){
		FactTab.push_back(FactTab.back()*FactTab.size()%MOD);
		InvFactTab.push_back(inverse(FactTab.back()));
	}
}
long long binom(int n, int k){
	//return FactTab[n]*inverse(FactTab[k])%MOD*inverse(FactTab[n-k])%MOD;
	return FactTab[n]*InvFactTab[k]%MOD*InvFactTab[n-k]%MOD;
}

//N-DIMENSIONAL SECTOR
struct Kula{
	int r;
	string O;
};
long long Mono(const Kula &K){
	long long wnk=0;
	for(int diff=0;diff<=K.r;diff++)
		wnk = (wnk + binom(K.O.length(), diff))%MOD;
	//cerr << "Mono returns " << wnk << endl;
	return wnk;
}
long long Di(const Kula &K1, const Kula &K2){
	int alpha=0, beta=0;
	for(int i=0;i<(int)K1.O.length();i++)
		if(K1.O[i]==K2.O[i])
			alpha++;
		else
			beta++;
	
	long long wnk=0;
	for(int diff=0;diff<=K1.r;diff++)
		for(int gamma=0;gamma<=min(alpha,diff);gamma++)
			if(diff-gamma<=beta && 2*gamma+beta-diff<=K2.r)
				wnk = (wnk+binom(alpha, gamma)*binom(beta, diff-gamma))%MOD;
	//cerr << "Di returns " << wnk << endl;
	return wnk;
}
long long Tri(const Kula &K1, const Kula &K2, const Kula &K3){
	int alpha=0, beta=0, gamma=0, fi=0;
	for(int i=0;i<(int)K1.O.length();i++)
		if(K1.O[i]==K2.O[i]){
			if(K2.O[i]==K3.O[i])
				alpha++;
			else
				beta++;
		}
		else{
			if(K2.O[i]==K3.O[i])
				gamma++;
			else
				fi++;
		}
	
	long long wnk=0;
	for(int diff=0;diff<=K1.r;diff++)
		for(int lambda=0;lambda<=min(diff, alpha);lambda++)
			for(int omega=0;omega<=min(diff-lambda, beta);omega++)
				for(int psi=0;psi<=min(diff-lambda-omega,gamma);psi++){
					int epsilon=diff-lambda-omega-psi;
					if(epsilon<=fi && lambda+omega+gamma-psi+fi-epsilon<=K2.r && lambda+beta-omega+gamma-psi+epsilon<=K3.r)
						wnk = (wnk+binom(alpha,lambda)*binom(beta,omega)%MOD*binom(gamma,psi)%MOD*binom(fi,diff-lambda-omega-psi))%MOD;
				}
	//cerr << "Tri returns " << wnk << endl;
	return wnk;
}

//THE BORING REST
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int n;
	cin >> n;
	prepareFactorialTab(n);
	
	Kula A,B,C;
	cin >> A.r >> A.O >> B.r >> B.O >> C.r >> C.O;
	
	long long wnk = Mono(A) + Mono(B) + Mono(C) - Di(A,B) - Di(B,C) - Di(C,A) + Tri(A,B,C);
	wnk = (wnk + 42ll*MOD)%MOD;
	cout << wnk << "\n";
	
	return 0;
}