#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <map>

using namespace std;
typedef long long ll;
const ll MOD = 1000000007;

struct Rule {
	int type, value;
};
typedef vector<Rule> Rules;

int Na, Nt, Ng, Nc;
vector<Rules> rule_set;

vector<int> decoded;

ll dp[201][51][51][51] = { { { { 0 } } } };
ll dp2[51][51][51][51] = { { { { 0 } } } };

int recur(const Rules &r, int p){
	int Ntot = Na + Nt + Ng + Nc, i;
	for(i = 0; i < r.size() && p <= Ntot; ++i){
		if(r[i].type == 0){
			decoded.push_back(r[i].value);
			++p;
		}else{
			p = recur(rule_set[r[i].value], p);
		}
	}
	return p;
}

int main(){
	cin >> Na >> Nt >> Ng >> Nc;
	int m;
	cin >> m;
	map<string, int> name_table;
	string s;
	getline(cin, s);
	vector<string> raw_rules;
	for(int i = 0; i < m; ++i){
		getline(cin, s);
		name_table[s.substr(0, s.find(':'))] = i;
		raw_rules.push_back(s);
	}
	rule_set.resize(m);
	for(int i = 0; i < m; ++i){
		stringstream ss(raw_rules[i]);
		ss >> s;
		while(ss >> s){
			Rule r;
			if(s[0] == '['){
				int st = 0;
				for(int i = 1; i + 1 < s.size(); ++i){
					switch(s[i]){
						case 'A': st |= 1; break;
						case 'T': st |= 2; break;
						case 'G': st |= 4; break;
						case 'C': st |= 8; break;
					}
				}
				r.type = 0;
				r.value = st;
			}else{
				r.type = 1;
				r.value = name_table[s];
			}
			rule_set[i].push_back(r);
		}
	}
	int length = recur(rule_set[0], 0);
	int Ntot = Na + Nt + Ng + Nc;
	if(length > Ntot){
		cout << 0 << endl;
		return 0;
	}
	dp[0][0][0][0] = 1;
	for(int i = 0; i < length; ++i){
		for(int a = 0; a <= Na; ++a){
			for(int t = 0; t <= Nt; ++t){
				for(int g = 0; g <= Ng; ++g){
					if(a + t + g > i){ continue; }
					int c = i - a - t - g;
					ll cur = dp[i][a][t][g];
					if((decoded[i] & 1) && (a < Na)){
						dp[i + 1][a + 1][t][g] = (dp[i + 1][a + 1][t][g] + cur) % MOD;
					}
					if((decoded[i] & 2) && (t < Nt)){
						dp[i + 1][a][t + 1][g] = (dp[i + 1][a][t + 1][g] + cur) % MOD;
					}
					if((decoded[i] & 4) && (g < Ng)){
						dp[i + 1][a][t][g + 1] = (dp[i + 1][a][t][g + 1] + cur) % MOD;
					}
					if((decoded[i] & 8) && (c < Nc)){
						dp[i + 1][a][t][g] = (dp[i + 1][a][t][g] + cur) % MOD;
					}
				}
			}
		}
	}
	ll answer = 0;
	answer = dp[length][Na][Nt][Ng];
	cout << answer << endl;
	return 0;
}