#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
namespace lc {
class NameTable {
private:
	std::unordered_map<std::string, int> m_table;
	std::vector<std::string> m_inv_table;
public:
	NameTable(){ }
	int add_name(const std::string &s){
		return (*this)[s];
	}
	int operator[](const std::string &s){
		const auto it = m_table.find(s);
		if(it != m_table.end()){ return it->second; }
		const int t = m_inv_table.size();
		m_table.insert(std::make_pair(s, t));
		m_inv_table.push_back(s);
		return t;
	}
	const std::string &operator[](size_t i) const {
		return m_inv_table[i];
	}
	size_t size() const { return m_inv_table.size(); }
};
}
namespace lc {
template <int MAX_CODE = std::numeric_limits<char>::max()>
class AhoCorasick {
private:
	struct State {
		int next[MAX_CODE + 1];
		int failure;
		std::vector<int> accept;
		State() : failure(0), accept() {
			const int EMPTY_LINK = std::numeric_limits<int>::min();
			std::fill(next, next + MAX_CODE + 1, EMPTY_LINK);
		}
	};
	std::vector<State> m_states;
	template <class Iterator>
	void construct_trie(Iterator first, Iterator last){
		m_states.emplace_back();
		int i = 0;
		for(Iterator it = first; it != last; ++it, ++i){
			int cur = 0;
			for(const int c : *it){
				if(m_states[cur].next[c] < 0){
					m_states[cur].next[c] = m_states.size();
					m_states.emplace_back();
				}
				cur = m_states[cur].next[c];
			}
			m_states[cur].accept.push_back(i);
		}
	}
	void write_failure_links(){
		std::queue<int> q;
		q.push(0);
		while(!q.empty()){
			const int index = q.front();
			q.pop();
			const State &s = m_states[index];
			for(int i = 0; i <= MAX_CODE; ++i){
				const int next = s.next[i];
				if(next < 0){ continue; }
				q.push(next);
				if(index == 0){ continue; }
				int f = s.failure;
				while(f != 0 && m_states[f].next[i] < 0){
					f = m_states[f].failure;
				}
				const int failure = std::max(0, m_states[f].next[i]);
				m_states[next].failure = failure;
				const auto &accept = m_states[failure].accept;
				std::copy(
					accept.begin(), accept.end(),
					std::back_inserter(m_states[next].accept));
			}
		}
	}
	int shorten_recur(int i, int c){
		const int EMPTY_LINK = std::numeric_limits<int>::min();
		State &s = m_states[i];
		if(i == 0 || s.next[c] >= 0){ return ~i; }
		if(s.next[c] != EMPTY_LINK){ return s.next[c]; }
		s.next[c] = shorten_recur(s.failure, c);
		return s.next[c];
	}
	void shorten_failure_links(){
		const int n = m_states.size();
		for(int i = 1; i < n; ++i){
			for(int j = 0; j <= MAX_CODE; ++j){ shorten_recur(i, j); }
		}
	}
public:
	AhoCorasick()
		: m_states(1)
	{ }
	template <class Iterator>
	AhoCorasick(Iterator first, Iterator last)
		: m_states()
	{
		construct_trie(first, last);
		write_failure_links();
		shorten_failure_links();
	}
	std::pair<int, const std::vector<int> &> iterate(int c, int s) const {
		if(s != 0 && m_states[s].next[c] < 0){ s = ~m_states[s].next[c]; }
		s = std::max(0, m_states[s].next[c]);
		return std::pair<int, const std::vector<int> &>(s, m_states[s].accept);
	}
	size_t size() const {
		return m_states.size();
	}
};
}
using namespace std;
typedef lc::AhoCorasick<'z'> AhoCorasick;
static const int MOD = 1000000007;
int main(){
	ios_base::sync_with_stdio(false);
	while(true){
		int n, m, k;
		cin >> n >> m >> k;
		if(n == 0 && m == 0 && k == 0){ break; }
		vector< vector<int> > next_words(2 * n + 1);
		lc::NameTable words;
		words.add_name("");
		for(int i = 0; i < n; ++i){
			string from, to;
			cin >> from >> to;
			const int from_key = words[from], to_key = words[to];
			next_words[from_key].push_back(to_key);
		}
		for(size_t i = 1; i < words.size(); ++i){
			next_words[0].push_back(i);
		}
		vector<string> season_words(k);
		for(int i = 0; i < k; ++i){ cin >> season_words[i]; }
		AhoCorasick ac(season_words.begin(), season_words.end());
		map<int, int> dp[21][501][2];
		dp[0][0][0].insert(make_pair(0, 1));
		for(int i = 0; i < m; ++i){
			for(size_t j = 0; j < words.size(); ++j){
				for(int f = 0; f < 2; ++f){
					for(const auto &p : dp[i % 21][j][f]){
						for(const int next : next_words[j]){
							const string &word = words[next];
							if(static_cast<int>(i + word.size()) > m){
								continue;
							}
							int state = p.first, sum = f;
							for(const char c : word){
								const auto res = ac.iterate(c, state);
								state = res.first;
								sum += res.second.size();
							}
							if(sum >= 2){ continue; }
							const int rot = (i + word.size()) % 21;
							dp[rot][next][sum][state] += p.second;
							dp[rot][next][sum][state] %= MOD;
						}
					}
					dp[i % 21][j][f].clear();
				}
			}
		}
		int answer = 0;
		for(size_t i = 0; i < words.size(); ++i){
			for(size_t j = 0; j < ac.size(); ++j){
				answer += dp[m % 21][i][1][j];
				answer %= MOD;
			}
		}
		cout << answer << endl;
	}
	return 0;
}

Measured memory_bytes: 16272