#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200 + 2, MAXM = 20, inf = 1000000000 + 7;
const int MAXS = 200, MAXK = 500;
int n, m, K, max_id = 0;
struct Node;
typedef Node* pNode;
pNode root, node[MAXS];
struct Node {
  pNode nxt[MAXM], fail;
  int val, id, s_val;
  Node() : fail(0), val(0), s_val(0), id(max_id) {
    memset(nxt, 0, sizeof(nxt));
    node[max_id++] = this;
  }
};
void Insert(int a[], int len, int val) {
  pNode u = root;
  int key, i;
  for (u = root, i = 0; key = a[i], i < len; u = u->nxt[key], i++) {
    if (u->nxt[key] == 0) u->nxt[key] = new Node;
  }
  u->val += val;
}
void Build() {
  pNode u, v, cur;
  queue<pNode> que;
  for (int key = 0; key < m; key++)
    if (v = root->nxt[key]) {
      que.push(v);
      v->fail = root;
    } else
      root->nxt[key] = root;
  while (!que.empty()) {
    u = que.front();
    que.pop();
    for (int key = 0; key < m; key++) {
      cur = u->fail->nxt[key];
      if (!cur) cur = root;
      if (v = u->nxt[key]) {
        que.push(v);
        v->fail = cur;
        v->val += cur->val;
      } else {
        u->nxt[key] = cur;
      }
    }
  }
}
int f[MAXN][MAXS][MAXK][2];
int dp(vector<int> lim) {
  memset(f, 0, sizeof(f));
  int Len = lim.size();
  int ret = 1;
  if (Len == 1 && lim[0] == 0) return ret;
  for (int len = 0; len < Len; len++) {
    int state = 0, k = 0;
    if (len == 0) {
      for (int key = 1; key <= lim[len]; key++) {
        int new_s = node[state]->nxt[key]->id;
        int val = node[state]->nxt[key]->val;
        if (k + val > K) continue;
        f[len + 1][new_s][k + val][key == lim[len]] += 1;
      }
    } else {
      for (int key = 1; key < m; key++) {
        int new_s = node[state]->nxt[key]->id;
        int val = node[state]->nxt[key]->val;
        if (k + val > K) continue;
        f[len + 1][new_s][k + val][0] += 1;
      }
    }
    for (int state = 0; state < max_id; state++)
      for (int k = 0; k <= K; k++) {
        if (f[len][state][k][1]) {
          for (int key = 0; key <= lim[len]; key++) {
            int new_s = node[state]->nxt[key]->id;
            int val = node[state]->nxt[key]->val;
            if (k + val > K) continue;
            f[len + 1][new_s][k + val][key == lim[len]] += f[len][state][k][1];
            f[len + 1][new_s][k + val][key == lim[len]] %= inf;
          }
        }
        if (f[len][state][k][0]) {
          for (int key = 0; key < m; key++) {
            int new_s = node[state]->nxt[key]->id;
            int val = node[state]->nxt[key]->val;
            if (k + val > K) continue;
            f[len + 1][new_s][k + val][0] += f[len][state][k][0];
            f[len + 1][new_s][k + val][0] %= inf;
          }
        }
      }
  }
  for (int state = 0; state < max_id; state++)
    for (int k = 0; k <= K; k++) {
      ret += (f[Len][state][k][0] + f[Len][state][k][1]) % inf;
      ret %= inf;
    }
  return ret;
}
int reduce(vector<int>& a) {
  int n = a.size();
  if (a[0] == 0 && n == 1) return 1;
  for (int i = n - 1; i >= 0; i--) {
    if (a[i] > 0) {
      a[i]--;
      break;
    } else
      a[i] = m - 1;
  }
  return 0;
}
int main() {
  while (cin >> n >> m >> K) {
    vector<int> upper_bound, lower_bound;
    root = new Node;
    int str[MAXN], len, val;
    cin >> len;
    for (int i = 0; i < len; i++) {
      cin >> val;
      lower_bound.push_back(val);
    }
    int residual = reduce(lower_bound);
    cin >> len;
    for (int i = 0; i < len; i++) {
      cin >> val;
      upper_bound.push_back(val);
    }
    while (n--) {
      cin >> len;
      for (int i = 0; i < len; i++) cin >> str[i];
      cin >> val;
      Insert(str, len, val);
    }
    Build();
    int ans = dp(upper_bound) - dp(lower_bound) + inf + residual;
    if (ans >= inf) ans -= inf;
    cout << ans << endl;
  }
  return 0;
}
