#include <bits/stdc++.h>
using namespace std;
const int N = 200 + 3, K = 200 + 3, INF = 1000 * 1000 * 1000;
const int M = 20 + 1;
const long double eps = 1e-9;
const int mod = 1000000007;
struct node {
  int next[M];
  int go[M];
  int link;
  int p;
  int c, val;
  int add;
  node() {
    memset(next, -1, sizeof next);
    memset(go, -1, sizeof go);
    link = add = -1;
    p = 0;
    c = val = 0;
  }
};
int n, m, k;
int nsz;
node nodes[N];
void add(vector<int> v, int c) {
  int cur = 0;
  for (int i = 0; i < int(v.size()); ++i) {
    if (nodes[cur].next[v[i]] == -1) {
      nodes[nsz] = node();
      node &next = nodes[nsz];
      next.p = cur;
      next.val = v[i];
      nodes[cur].next[v[i]] = nsz++;
      assert(nsz < N);
    }
    cur = nodes[cur].next[v[i]];
  }
  nodes[cur].c += c;
}
inline int go(int v, int &to);
inline int link(int v) {
  node &res = nodes[v];
  if (res.link != -1) return res.link;
  if (v == 0 || nodes[v].p == 0) return res.link = 0;
  return res.link = go(link(res.p), res.val);
}
inline int go(int v, int &to) {
  node &res = nodes[v];
  if (res.go[to] != -1) return res.go[to];
  if (res.next[to] != -1) return res.go[to] = res.next[to];
  if (v == 0) return res.go[to] = 0;
  return res.go[to] = go(link(v), to);
}
inline int getadd(int v) {
  node &res = nodes[v];
  if (res.add != -1) return res.add;
  if (v == 0) return res.add = 0;
  return res.add = res.c + getadd(link(v));
  ;
}
int z[2][N][2][2][K];
int calc(vector<int> v) {
  memset(z, 0, sizeof z);
  z[0][0][1][0][0] = 1;
  for (int i = 0; i < int(v.size()); ++i) {
    int cur = i & 1;
    int next = cur ^ 1;
    memset(z[next], 0, sizeof z[next]);
    for (int j = 0; j < nsz; ++j) {
      for (int p = 0; p < 2; ++p) {
        for (int was = 0; was < 2; ++was)
          for (int k = 0; k < ::k + 1; ++k) {
            int dv = z[cur][j][p][was][k];
            if (dv == 0) continue;
            for (int n = 0; n < m; ++n) {
              if (p && n > v[i]) break;
              int nj = go(j, n);
              int np = p && (n == v[i]);
              int nwas = was || (n != 0);
              int add = getadd(nj);
              if (!nwas) {
                add = 0;
                nj = 0;
              }
              z[next][nj][np][nwas][min(::k + 1, k + add)] += dv;
              if (z[next][nj][np][nwas][min(::k + 1, k + add)] >= mod)
                z[next][nj][np][nwas][min(::k + 1, k + add)] -= mod;
            }
          }
      }
    }
  }
  int ans = 0;
  for (int j = 0; j < nsz; ++j)
    for (int p = 0; p < 2; ++p)
      for (int kk = 0; kk < k + 1; ++kk) {
        ans += z[int(v.size()) & 1][j][p][1][kk];
        if (ans >= mod) ans -= mod;
      }
  return ans;
}
bool solve() {
  if (scanf("%d%d%d", &n, &m, &k) != 3) return false;
  nsz = 1;
  nodes[0] = node();
  vector<int> l;
  vector<int> r;
  int len;
  scanf("%d", &len);
  l.resize(len);
  for (int i = 0; i < len; ++i) {
    scanf("%d", &l[i]);
  }
  scanf("%d", &len);
  r.resize(len);
  for (int i = 0; i < len; ++i) {
    scanf("%d", &r[i]);
  }
  for (int i = 0; i < n; ++i) {
    vector<int> v;
    scanf("%d", &len);
    v.resize(len);
    for (int i = 0; i < len; ++i) {
      scanf("%d", &v[i]);
    }
    int c;
    scanf("%d", &c);
    add(v, c);
  }
  for (int v = 0; v < nsz; ++v)
    for (int i = 0; i < m; ++i) go(v, i);
  long long ans = calc(r);
  l[int(l.size()) - 1]--;
  for (int i = int(l.size()) - 1; i > 0; i--) {
    if (l[i] < 0) {
      l[i] += m;
      l[i - 1]--;
    }
  }
  ans = (ans - calc(l) + mod) % mod;
  cout << ans << endl;
  return true;
}
int main() {
  while (solve()) puts("");
  cerr << "TIME: " << clock() << endl;
  return 0;
}
