#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 5000;
const int MAXS = 2000000;
const int MOD = 1000000007;
int n, A, B;
char g[MAXN][MAXN + 1];
int off[MAXN + 1], cnt[MAXN];
char s[MAXS + 1];
vector<int> compnodes[MAXN];
int comp[MAXN], ncomp;
int id[MAXN], lid[MAXN], nid;
int stck[MAXN], nstck;
bool done[MAXN];
int top[MAXN], ntop;
bool have[MAXS];
int gcomp[MAXN];
int mn[MAXN], mx[MAXN];
pair<int, int> o[MAXN];
priority_queue<int> q;
int C[MAXN + 1][MAXN + 1];
void tarjan(int at) {
  id[at] = lid[at] = nid++;
  stck[nstck++] = at;
  for (int to = (0); to < (n); ++to)
    if (g[at][to] == '1') {
      if (id[to] == -1) {
        tarjan(to);
        if (lid[to] < lid[at]) lid[at] = lid[to];
      } else if (comp[to] == -1) {
        if (id[to] < lid[at]) lid[at] = id[to];
      }
    }
  if (lid[at] >= id[at]) {
    compnodes[ncomp].clear();
    while (comp[at] == -1)
      comp[stck[--nstck]] = ncomp, compnodes[ncomp].push_back(stck[nstck]);
    ++ncomp;
  }
}
void dfstop(int c) {
  done[c] = true;
  for (int i = (0); i < (((int)(compnodes[c]).size())); ++i) {
    int at = compnodes[c][i];
    for (int to = (0); to < (n); ++to)
      if (g[at][to] == '1' && !done[comp[to]]) dfstop(comp[to]);
  }
  top[ntop++] = c;
}
void run() {
  scanf("%d%d%d", &n, &A, &B);
  for (int i = (0); i < (n); ++i) scanf("%s", g[i]);
  off[0] = 0;
  for (int i = (0); i < (n); ++i) {
    scanf("%d%s", &cnt[i], s + off[i]);
    off[i + 1] = off[i] + cnt[i];
  }
  for (int i = (0); i < (n); ++i) comp[i] = id[i] = -1;
  nid = nstck = ncomp = 0;
  for (int i = (0); i < (n); ++i)
    if (comp[i] == -1) tarjan(i);
  ntop = 0;
  for (int i = (0); i < (ncomp); ++i) done[i] = false;
  for (int i = (0); i < (ncomp); ++i)
    if (!done[i]) dfstop(i);
  assert(ntop == ncomp);
  reverse(top, top + ntop);
  for (int i = (0); i < (ncomp); ++i) {
    int c = top[i];
    int g = 0;
    for (int j = (0); j < (((int)(compnodes[c]).size())); ++j) {
      int at = compnodes[c][j];
      g = gcd(g, cnt[at]);
    }
    gcomp[c] = g;
  }
  for (int i = (0); i < (ncomp); ++i) {
    int c = top[i];
    {
      int g = gcomp[c];
      for (int i = (0); i < (g); ++i) have[i] = false;
      for (int j = (0); j < (((int)(compnodes[c]).size())); ++j) {
        int at = compnodes[c][j];
        for (int k = (0); k < (cnt[at]); ++k)
          if (s[off[at] + k] != '0') have[k % g] = true;
      }
      for (int j = (0); j < (((int)(compnodes[c]).size())); ++j) {
        int at = compnodes[c][j];
        for (int k = (0); k < (cnt[at]); ++k)
          if (s[off[at] + k] == '0' && have[k % g]) s[off[at] + k] = 'F';
      }
    }
    if (i + 1 < ncomp) {
      int nc = top[i + 1];
      int g = gcd(gcomp[c], gcomp[nc]);
      for (int i = (0); i < (g); ++i) have[i] = false;
      for (int j = (0); j < (((int)(compnodes[c]).size())); ++j) {
        int at = compnodes[c][j];
        for (int k = (0); k < (cnt[at]); ++k)
          if (s[off[at] + k] != '0') have[k % g] = true;
      }
      for (int j = (0); j < (((int)(compnodes[nc]).size())); ++j) {
        int at = compnodes[nc][j];
        for (int k = (0); k < (cnt[at]); ++k)
          if (s[off[at] + k] == '0' && have[k % g]) s[off[at] + k] = 'F';
      }
    }
  }
  for (int i = (0); i <= (n); ++i) {
    C[i][0] = C[i][i] = 1;
    for (int j = (1); j < (i); ++j)
      if ((C[i][j] = C[i - 1][j - 1] + C[i - 1][j]) >= MOD) C[i][j] -= MOD;
  }
  for (int i = (0); i < (n); ++i) {
    mn[i] = mx[i] = 0;
    for (int j = (0); j < (cnt[i]); ++j)
      if (s[off[i] + j] == '1')
        ++mn[i], ++mx[i];
      else if (s[off[i] + j] == 'F')
        ++mx[i];
  }
  for (int i = (0); i < (n); ++i) o[i] = make_pair(-mx[i], i);
  sort(o, o + n);
  for (int i = (0); i < (n); ++i) o[i].first = -o[i].first;
  q = priority_queue<int>();
  int nopt = 0, nalways = 0;
  int ret = 0;
  for (int i = (0); i < (n); ++i) {
    int at = o[i].second;
    while (((int)(q).size()) > 0 && q.top() > mx[at])
      --nopt, ++nalways, q.pop();
    if (nalways < A && nalways + nopt >= B - 1) {
      for (int j = (max(0, B - 1 - nalways));
           j <= (min(min(B - 1, nopt), A - 1 - nalways)); ++j)
        ret = (ret + (long long)C[nopt][j] * C[nalways][B - 1 - j]) % MOD;
    }
    ++nopt;
    q.push(mn[at]);
  }
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}
