#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

const int MM = 150;

struct Node {
  int id;
  int next[MM];
  int fail;
  vector<int> value;
  Node() {
    for(int i=0; i<MM; ++i) next[i] = 0;
    value.clear();
  }
};

class Trie {
public:
  Trie(const vector<string> &vs) {
    nodes.push_back(new Node()); // dummy
    nodes.push_back(new Node());
    for(int i=0; i<vs.size(); ++i)
      insert(vs[i],i);
  }
  Trie() {
    nodes.clear();
  }

  void insert(const string &s,int k) {
    Node *cur = nodes[1];
    for(int i=0; i<s.length(); ++i) {
      if(cur->next[s[i]] == 0) {
        cur->next[s[i]] = nodes.size();
        nodes.push_back(new Node());
      }
      cur = nodes[cur->next[s[i]]];
    }
    cur->value.push_back(k);
  }
  vector<Node*> nodes;
};

class Aho_Corasick {
public:
  Aho_Corasick(const vector<string> &vs) {
    nodes = Trie(vs).nodes;
    make_failure_link();
  }

  void make_failure_link() {
    queue<int> q;
    Node *root = nodes[1];
    for(int i=0; i<MM; ++i) {
      if(root->next[i]) {
        nodes[root->next[i]]->fail = 1;
        q.push(root->next[i]);
      }else root->next[i] = 1;
    }

    while(!q.empty()) {
      Node *t = nodes[q.front()]; q.pop();
      for(int i=0; i<MM; ++i) {
        int u = t->next[i];
        if(u) {
          q.push(u);
          int r = t->fail;
          while(!nodes[r]->next[i]) r = nodes[r]->fail;
          nodes[u]->fail = nodes[r]->next[i];
          FOR(it, nodes[nodes[u]->fail]->value) {
            nodes[u]->value.push_back(*it);
          }
        }
      }
    }
  }

  pair<int, int> match(int v, const string &s) {
    int cnt = 0;
    for(int i=0; i<s.length(); ++i) {
      while(!nodes[v]->next[s[i]]) {
        v = nodes[v]->fail;
      }
      v = nodes[v]->next[s[i]];
      if(!(nodes[v]->value.empty())) { // found the word
        cnt += nodes[v]->value.size();
      }
    }
    return make_pair(v, cnt);
  }

  // ツ個サツ催敖づ個湘ウツ妥板づ閉カツ篠堋づーツ与ツつヲツづ湘ウツ妥板遷ツ暗堋つウツつケツづゥツ。
  // AOJ2212ツづづ債マツッツチツつオツつスツづァツつセツづ淞つセツづつスツづ個づ、ツマツッツチツつオツつスツづつォ-1ツづーツ陛板つキツづヲツつ、ツづ可つオツづつ「ツづゥツ。
  int next(int v, char c) {
    while(!nodes[v]->next[c]) {
      v = nodes[v]->fail;
    }
    v = nodes[v]->next[c];
    // if(!(nodes[v]->value.empty())) { // found the word
    //   return -1;
    // }
    return v;
  }
  
  int match(int v) {
    return nodes[v]->value.size();
  }
  
  void free() {
    for(int i=0; i<nodes.size(); ++i)
      delete nodes[i];
  }

  vector<Node*> nodes;
};

struct P {
  int state, now;
  bool f;
  P(int state, int now, bool f) : state(state),now(now),f(f) {}
};
bool operator<(const P &a, const P &b) {
  return a.state!=b.state ? a.state<b.state :
    a.now!=b.now ? a.now<b.now : a.f<b.f;
}
map<P,int> dp[21];

const int MOD = 1e9+7;
const int M = 21;
int main() {
  int n, m, k;
  while(cin >> n >> m >> k, n||m||k) {
    map<string, int> mp;
    int num = 0;
    vector<int> g[500];
    string str[500];
    REP(i, n) {
      string a, b;
      cin >> a >> b;
      if (mp.count(a) == 0) {
        str[num] = a;
        mp[a] = num++;
      }
      if (mp.count(b) == 0) {
        str[num] = b;
        mp[b] = num++;
      }
      g[mp[a]].push_back(mp[b]);
    }
    vector<string> vs(k);
    REP(i, k) cin >> vs[i];
    Aho_Corasick pma(vs);
    int ssize = pma.nodes.size();

    
    pii PMA[ssize][num];
    vector<int> v[num];
    for (int i=1; i<ssize; ++i) {
      REP(j, num) {
        PMA[i][j] = pma.match(i,str[j]);
        if (PMA[i][j].second <= 1)
          v[j].push_back(PMA[i][j].first);
      }
    }
    REP(i, num) {
      sort(ALL(v[i]));
      v[i].erase(unique(ALL(v[i])), v[i].end());
    }
    REP(i, M) dp[i].clear();
    REP(i, num) {
      pii p = pma.match(1, str[i]);
      int ss = p.first, f = p.second;
      if (f<=1) {
        dp[str[i].size()][P(ss,i,f)] = 1;
        //cout << str[i].size() << ": " << ss << " " << i << " " << f << endl;
      }
    }
    //cout << ssize << " " << num << endl;
    for (int i=1; i<=m; ++i) {
      dp[(i+M-1)%M].clear();
      FOR(it, dp[i%M]) {
        const P *p = &it->first;
        FOR(jt, g[p->now]) {
          int ss = PMA[p->state][*jt].first;
          int f = PMA[p->state][*jt].second;
          if (p->f+f<=1) {
            (dp[(i+str[*jt].size())%M][P(ss,*jt,p->f+f)] += it->second) %= MOD;
          }
        }
      }
    }
    int ans = 0;
    REP(i, num) {
      for (int s=1; s<ssize; ++s) {
        ans = (ans + dp[m%M][P(s,i,1)]) % MOD;
      }
    }
    cout << ans << endl;
  }
}

Measured memory_bytes: 17000