#include <bits/stdc++.h>
using namespace std;
int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
  return s;
}
const int L = 2e6 + 5;
const int N = 5005;
const int mo = 1e9 + 7;
int n, A, B;
bool mp[N][N];
char str[N];
int sta[N], tp;
bool pd[N];
int dfn[N], f[N], k;
int be[N], m;
void tarjan(int x) {
  dfn[x] = f[x] = ++k;
  pd[sta[++tp] = x] = 1;
  for (int y = 1; y <= n; y++)
    if (mp[x][y]) {
      if (!dfn[y]) {
        tarjan(y);
        f[x] = min(f[x], f[y]);
      } else if (pd[y])
        f[x] = min(f[x], dfn[y]);
    }
  if (f[x] == dfn[x]) {
    m++;
    while (sta[tp + 1] != x) {
      be[sta[tp]] = m;
      pd[sta[tp--]] = 0;
    }
  }
}
int siz[N];
int St[N], Ed[N];
int Len;
int Real[L], Fake[L];
int d[N];
bool ins[N][N];
int num[N];
bool cmp(int x, int y) { return d[x] < d[y]; }
int key[N];
int sz[N], tr[N];
int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }
struct sstack {
  int st, len;
} st[20];
int top, tot;
int tv[L * 4];
void merge() {
  tot = 0;
  int u_ = 0;
  for (int i = 1; i <= top; i++) {
    if (i > 1 && st[i].len == st[u_].len) {
      for (int x = 0; x <= st[i].len - 1; x++)
        tv[st[u_].st + x] |= tv[st[i].st + x];
      continue;
    }
    u_++;
    st[u_].len = st[i].len;
    st[u_].st = tot + 1;
    for (int x = 0; x <= st[i].len - 1; x++)
      tv[st[u_].st + x] = tv[st[i].st + x];
    tot += st[i].len;
  }
  top = u_;
}
struct gang {
  int fake, real;
} a[N];
bool cmp1(gang a, gang b) {
  return a.fake + a.real != b.fake + b.real ? a.fake + a.real < b.fake + b.real
                                            : a.real < b.real;
}
long long js[N], inv[N];
long long calc(int n, int m) {
  return n < m ? 0 : js[n] * inv[m] % mo * inv[n - m] % mo;
}
int main() {
  n = get();
  A = get();
  B = get();
  for (int i = 1; i <= n; i++) {
    scanf("%s", str + 1);
    for (int j = 1; j <= n; j++) mp[i][j] = (str[j] == '1');
  }
  for (int i = 1; i <= n; i++) {
    siz[i] = get();
    St[i] = Len + 1;
    for (int j = 1; j <= siz[i]; j++) {
      char ch;
      while (ch = getchar(), ch < '0' || ch > '9')
        ;
      Real[++Len] = ch - '0';
    }
    Ed[i] = Len;
  }
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (mp[i][j] && be[i] != be[j] && !ins[be[j]][be[i]]) {
        ins[be[j]][be[i]] = 1;
        d[be[j]]++;
      }
  for (int i = 1; i <= m; i++) num[i] = i;
  sort(num + 1, num + 1 + m, cmp);
  for (int i = 1; i <= m; i++) tr[num[i]] = i;
  for (int i = 1; i <= n; i++) be[i] = tr[be[i]];
  top = 0;
  for (int id = 1; id <= m; id++) {
    k = 0;
    for (int i = 1; i <= n; i++)
      if (be[i] == id) key[++k] = i;
    sz[id] = siz[key[1]];
    for (int i = 1; i <= k; i++) sz[id] = gcd(sz[id], siz[key[i]]);
    st[++top].st = tot + 1;
    st[top].len = sz[id];
    for (int i = tot + 1; i <= tot + sz[id]; i++) tv[i] = 0;
    for (int i = 1; i <= k; i++)
      for (int j = St[key[i]]; j <= Ed[key[i]]; j++)
        tv[tot + 1 + (j - St[key[i]]) % sz[id]] |= Real[j];
    tot += sz[id];
    for (int u = 1; u <= top - 1; u++) {
      int d = gcd(st[u].len, sz[id]);
      for (int x = 0; x <= d - 1; x++) {
        for (int w = x; w < st[u].len; w += d)
          tv[x + st[u].st] |= tv[w + st[u].st];
        for (int w = x; w < sz[id]; w += d)
          tv[st[top].st + w] |= tv[st[u].st + x];
      }
      st[u].len = d;
    }
    for (int i = 1; i <= k; i++)
      for (int j = St[key[i]]; j <= Ed[key[i]]; j++)
        Fake[j] = tv[st[top].st + (j - St[key[i]]) % sz[id]] ^ Real[j];
    merge();
  }
  for (int i = 1; i <= n; i++) {
    a[i].real = a[i].fake = 0;
    for (int j = St[i]; j <= Ed[i]; j++)
      if (Real[j])
        a[i].real++;
      else if (Fake[j])
        a[i].fake++;
  }
  long long ans = 0;
  sort(a + 1, a + 1 + n, cmp1);
  js[0] = js[1] = 1;
  for (int i = 2; i <= n; i++) js[i] = js[i - 1] * i % mo;
  inv[0] = inv[1] = 1;
  for (int i = 2; i <= n; i++) inv[i] = 1ll * (mo - mo / i) * inv[mo % i] % mo;
  for (int i = 2; i <= n; i++) inv[i] = inv[i] * inv[i - 1] % mo;
  for (int i = 1; i <= n; i++) {
    int p = 0, q = 0;
    for (int j = i + 1; j <= n; j++)
      if (a[j].real > a[i].real + a[i].fake)
        p++;
      else
        q++;
    for (int x = max(0, p + B - A); x <= min(p, B - 1); x++)
      ans = (ans + calc(q, B - 1 - x) * calc(p, x) % mo) % mo;
  }
  cout << ans << endl;
  return 0;
}
