#include <bits/stdc++.h>
using namespace std;
struct ACnode {
  int fail, val;
  int ch[22];
  ACnode() {}
  void Init() {
    memset(ch, 0, sizeof(ch));
    val = 0;
  }
} A[1020304];
int ACnow = 0;
struct AC_Automaton {
  int root;
  void clr() { A[root = ++ACnow].Init(); }
  void ins(int t, int *a, int Val) {
    if (a[1] == 11126) {
      A[t].val += Val;
      return;
    }
    int s = a[1];
    if (A[t].ch[s] == 0) A[t].ch[s] = ++ACnow;
    int tt = A[t].ch[s];
    ins(tt, a + 1, Val);
  }
  int q[1020304];
  void GetFail() {
    int hd(0), tl(1);
    A[root].fail = root;
    q[1] = root;
    while (hd < tl) {
      int vex = q[++hd];
      A[vex].val += A[A[vex].fail].val;
      for (int x = 0; x <= 20; ++x)
        if (A[vex].ch[x]) {
          int tSon = A[vex].ch[x], t;
          int tAlp = x;
          q[++tl] = tSon;
          for (t = A[vex].fail; (t != root) && (A[t].ch[x] == 0); t = A[t].fail)
            ;
          if (A[t].ch[x] && vex != root) t = A[t].ch[x];
          A[tSon].fail = t;
        } else {
          int t;
          for (t = A[vex].fail; t != root; t = A[t].fail)
            if (A[t].ch[x]) break;
          if (A[t].ch[x]) t = A[t].ch[x];
          A[vex].ch[x] = t;
        }
    }
  }
} AC;
void getInt(int *A) {
  int len = 0;
  for (int i = 1; i <= 200; ++i) A[i] = 0;
  scanf("%d", &len);
  for (int i = 200 - len + 1; i <= 200; ++i) scanf("%d", &A[i]);
}
int Range[222];
int f[222][555][222];
bool calc[222][555][222];
int n, BASE, k;
int dp(int n, int curval, int curnode, bool w, bool Started) {
  if (n == 0) {
    return curval >= 0 && Started;
  }
  if (curval < 0) return 0;
  int c = Range[200 - n + 1];
  if (!Started) {
    int ans = 0;
    {
      ans = (ans + (dp(n - 1, curval, curnode, w && (c == 0), false))) %
            1000000007;
    };
    for (int j = 1; j <= ((w) ? (c) : (BASE - 1)); ++j) {
      int nextNode = A[curnode].ch[j];
      {
        ans = (ans + (dp(n - 1, curval - A[nextNode].val, nextNode,
                         w && (j == c), true))) %
              1000000007;
      };
    }
    return ans;
  }
  if (w) {
    int ans = 0;
    for (int j = 0; j <= c; ++j) {
      int nextNode = A[curnode].ch[j];
      {
        ans = (ans + (dp(n - 1, curval - A[nextNode].val, nextNode,
                         w && (j == c), true))) %
              1000000007;
      };
    }
    return ans;
  }
  if (calc[n][curval][curnode]) return f[n][curval][curnode];
  calc[n][curval][curnode] = true;
  int ans = 0;
  for (int j = 0; j <= BASE - 1; ++j) {
    int nextNode = A[curnode].ch[j];
    {
      ans =
          (ans + (dp(n - 1, curval - A[nextNode].val, nextNode, false, true))) %
          1000000007;
    };
  }
  return f[n][curval][curnode] = ans;
}
int solve(int *R) {
  for (int i = 1; i <= 200; ++i) Range[i] = R[i];
  return dp(200, k, AC.root, 1, 0);
}
int ask(int *L, int *R) {
  int ansr = solve(R);
  --L[200];
  int c = 200;
  while (L[c] < 0) {
    --L[c - 1];
    L[c] += BASE;
    --c;
  }
  int ansl = solve(L);
  return (ansr + 1000000007 - ansl) % 1000000007;
}
int L[222], R[222], tmp[222];
int main() {
  cin >> n >> BASE >> k;
  getInt(L);
  getInt(R);
  AC.clr();
  for (int i = 1; i <= n; ++i) {
    int tl = 0;
    scanf("%d", &tl);
    for (int j = 1; j <= tl; ++j) scanf("%d", &tmp[j]);
    tmp[tl + 1] = 11126;
    int tval = 0;
    scanf("%d", &tval);
    AC.ins(1, tmp, tval);
  }
  AC.GetFail();
  memset(calc, 0, sizeof(calc));
  int ans = ask(L, R);
  cout << ans << endl;
  return 0;
}
