#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 505
#define SIZE 21
#define TRIE_SIZE 605

enum Type{
    Unknown,
    TRUE,
    FALSE,
};

struct Node{
	int parent_id,children[26],suffix_link;
	bool finish_FLG,bad_finish;
};

struct Info{
    Info(int arg_node_id,int arg_ch){
        node_id = arg_node_id;
        ch = arg_ch;
    }

    int node_id,ch;
};

struct State{
	State(int arg_total_length,int arg_last_word,int arg_num_match){
		total_length = arg_total_length;
		last_word = arg_last_word;
		num_match = arg_num_match;
	}
	int total_length,last_word,num_match;
};

int num_relation,LENGTH,num_season_word;
int num_word,word_len[NUM];
int root,trie_index;
char table[NUM][SIZE],buf_from[SIZE],buf_to[SIZE],buf_season[SIZE];
vector<int> G[NUM];
Node nodes[TRIE_SIZE];
map<int,int> DP[NUM][2][501]; //DP[最後の文字][一致回数][総長][trie_pos] = 場合の数
Type memo[TRIE_SIZE];

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

int get_next_loc(int current_loc,int next){

	if(nodes[current_loc].children[next] != -1){

		return nodes[current_loc].children[next];

	}else{

		if(current_loc == root){
			return root;
		}

		for(current_loc = nodes[current_loc].suffix_link; current_loc != root; current_loc = nodes[current_loc].suffix_link){
			if(nodes[current_loc].children[next] != -1){
				break;
			}
		}
		if(nodes[current_loc].children[next] != -1){

			return nodes[current_loc].children[next];

		}else{

			return root;
		}
	}
}

int recursive(int total_length,int last_word,int trie_pos,int num_match){

	int ret = 0;

	//メモがあれば返却
	auto at = DP[last_word][num_match][total_length].find(trie_pos);
	if(at != DP[last_word][num_match][total_length].end()){
		return DP[last_word][num_match][total_length][trie_pos];
	}

	//文字が完成した場合
	if(total_length == LENGTH){
		if(num_match == 1){
			return 1;
		}else{
			return 0;
		}
	}

	int next_word,next_trie_pos,add_match;
	bool FLG;

	for(int i = 0; i < G[last_word].size(); i++){

		next_word = G[last_word][i];
		if(total_length+word_len[next_word] > LENGTH)continue;

		next_trie_pos = trie_pos;
		add_match = 0;
		FLG = true;

		//next_word分文字を進める。途中で、num_matchが2以上になったら不可
		for(int k = 0; k < word_len[next_word]; k++){
			next_trie_pos = get_next_loc(next_trie_pos,table[next_word][k]-'a');

			if(nodes[next_trie_pos].bad_finish){
				//★★2つ以上の、季語の終端を通過するのは不可★★
				FLG = false;
				break;
			}

			if(memo[next_trie_pos] == TRUE){ //★1つの季語の終端である場合★
				add_match++;
				if(num_match+add_match > 1){
					FLG = false;
					break;
				}
			}
		}
		if(FLG == false)continue;

		ret += recursive(total_length+word_len[next_word],next_word,next_trie_pos,num_match+add_match);
		ret %= MOD;
	}

	return DP[last_word][num_match][total_length][trie_pos] = ret;
}

void func(){

	num_word = 0;

	for(int i = 0; i < NUM; i++)G[i].clear();

	int from_index,to_index,length;

	for(int loop = 0; loop < num_relation; loop++){
		scanf("%s %s",buf_from,buf_to);

		from_index = -1;
		for(int i = 0; i < num_word; i++){
			if(strCmp(buf_from,table[i])){
				from_index = i;
				break;
			}
		}
		if(from_index == -1){
			for(length = 0; buf_from[length] != '\0'; length++);
			word_len[num_word] = length;
			strcpy(table[num_word],buf_from);
			from_index = num_word++;
		}

		to_index = -1;
		for(int i = 0; i < num_word; i++){
			if(strCmp(buf_to,table[i])){
				to_index = i;
				break;
			}
		}
		if(to_index == -1){
			for(length = 0; buf_to[length] != '\0'; length++);
			word_len[num_word] = length;
			strcpy(table[num_word],buf_to);
			to_index = num_word++;
		}
		G[from_index].push_back(to_index);
	}

	//★★空文字列を定義する(全ての文字に接続可能)★★
	word_len[num_word] = 0;
	for(int i = 0; i < num_word; i++){
		G[num_word].push_back(i);
	}
	num_word++;

	root = 0;
	trie_index = 1;

	//トライ木のノードを初期化
	for(int i = 0; i < TRIE_SIZE; i++){
		nodes[i].parent_id = -1;
		nodes[i].finish_FLG = false;
		nodes[i].suffix_link = root; //siffx_link先はとりあえずrootにしておく
		nodes[i].bad_finish = false;
		for(int k = 0; k < 26; k++){
			nodes[i].children[k] = -1;
		}
	}

	int tmp_ch,tmp_loc,parent_id,tmp_index;

	bool FLG;

	//トライ木を構成する
	for(int loop = 0; loop < num_season_word; loop++){

		scanf("%s",buf_season);

		tmp_index = 0;
		tmp_ch = buf_season[tmp_index]-'a';

		tmp_loc = root;
		tmp_index = 0;

		while(true){

			 parent_id = tmp_loc;
			 FLG = false;

			if(nodes[tmp_loc].children[tmp_ch] == -1){
				FLG = true;
				nodes[tmp_loc].children[tmp_ch] = trie_index++; //★新しいノードへ移動する場合★
			}
			//子ノードに移動
			tmp_loc = nodes[tmp_loc].children[tmp_ch];

			if(FLG){
				nodes[tmp_loc].parent_id = parent_id;
			}
			tmp_index++;

			if(buf_season[tmp_index] == '\0'){ //今回の数字が最後の文字だった場合
				nodes[tmp_loc].finish_FLG = true;
				break;
			}
			tmp_ch = buf_season[tmp_index]-'a';
		}
	}

	//Suffix_linkを構築する
	int node_id;
	queue<Info> MAKE_SL;
	for(int i = 0; i < 26; i++){
		if(nodes[root].children[i] != -1){
			node_id = nodes[root].children[i];
			nodes[node_id].suffix_link = root; //★root直下のsuffix_linkは必ずrootなので、queueには突っ込まない★
			for(int k = 0; k < 26; k++){
				if(nodes[node_id].children[k] != -1){
					MAKE_SL.push(Info(nodes[node_id].children[k],k)); //ノードのidと、最後の経路をpushする
				}
			}
		}
	}

	while(!MAKE_SL.empty()){
		node_id = MAKE_SL.front().node_id; //★新たにsuffix_linkを張りたいノードのid★
		tmp_ch = MAKE_SL.front().ch;
		MAKE_SL.pop();

		for(int i = 0; i < 26; i++){
			if(nodes[node_id].children[i] != -1){
				MAKE_SL.push(Info(nodes[node_id].children[i],i));
			}
		}

		for(tmp_loc = nodes[nodes[node_id].parent_id].suffix_link; tmp_loc != root; tmp_loc = nodes[tmp_loc].suffix_link){
			if(nodes[tmp_loc].children[tmp_ch] != -1){
				break;
			}
		}

		if(tmp_loc == root){
			if(nodes[root].children[tmp_ch] != -1){
				nodes[node_id].suffix_link = nodes[root].children[tmp_ch];
			}else{
				nodes[node_id].suffix_link = root;
			}
		}else{
			nodes[node_id].suffix_link = nodes[tmp_loc].children[tmp_ch];
		}
	}

	 //suffix_linkを辿り、finish_flgがtrueのものに出くわすか調べる
	for(int i = 0; i < trie_index; i++){
		memo[i] = Unknown;
	}

	queue<int> Q;
	for(int i = 0; i < 26; i++){
		if(nodes[root].children[i] != -1){
			Q.push(nodes[root].children[i]);
		}
	}

	//ノードに近いものから調べる
	while(!Q.empty()){
		tmp_loc = Q.front();
		Q.pop();
		for(int i = 0; i < 26; i++){
			if(nodes[tmp_loc].children[i] != -1){
				Q.push(nodes[tmp_loc].children[i]);
			}
		}

		if(nodes[tmp_loc].finish_FLG){
			memo[tmp_loc] = TRUE;
		}else{
			for(int k = nodes[tmp_loc].suffix_link; k != root; k = nodes[k].suffix_link){
				if(memo[k] != Unknown){
					memo[tmp_loc] = memo[k];
					break;
				}
				if(nodes[k].finish_FLG){
					memo[tmp_loc] = TRUE;
					break;
				}
			}
			if(memo[tmp_loc] == Unknown){
				memo[tmp_loc] = FALSE;
			}
		}
	}

	for(int i = 0; i < trie_index; i++){
		if(nodes[i].finish_FLG == true && memo[nodes[i].suffix_link] == TRUE){
			//printf("%dが不可\n",i);
			nodes[i].bad_finish = true;
		}
	}

	for(int i = 0; i < 26; i++){
		if(nodes[root].children[i] != -1){
			Q.push(nodes[root].children[i]);
		}
	}

	while(!Q.empty()){
		tmp_loc = Q.front();
		Q.pop();
		for(int i = 0; i < 26; i++){
			if(nodes[tmp_loc].children[i] != -1){
				Q.push(nodes[tmp_loc].children[i]);
			}
		}

		if(nodes[tmp_loc].bad_finish){
			//Do nothing
		}else{
			for(int k = nodes[tmp_loc].suffix_link; k != root; k = nodes[k].suffix_link){
				if(nodes[k].bad_finish){
					nodes[tmp_loc].bad_finish = true;
					break;
				}
			}
		}
	}

	for(int i = 0; i < num_word; i++){
		for(int k = 0; k < 2; k++){
			for(int a = 0; a <= LENGTH; a++){
				DP[i][k][a].clear();
			}
		}
	}

	printf("%d\n",recursive(0,num_word-1,root,0));
}


int main(){

	while(true){
		scanf("%d %d %d",&num_relation,&LENGTH,&num_season_word);
		if(num_relation == 0 && LENGTH == 0 && num_season_word == 0)break;

		func();
	}

	return 0;
}



Measured memory_bytes: 174788