#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 5, M = 2e6 + 5, Mod = 1e9 + 7;
int add(int a, int b) { return ((a += b) >= Mod) ? (a - Mod) : (a); }
int gcd(int a, int b) { return (!b) ? (a) : (gcd(b, a % b)); }
bool _pool[M << 1];
bool *_top = _pool;
bool *alloc(int sz) {
  bool *top = _top;
  _top += sz;
  return top;
}
int n, a, b;
char s[M];
int sz[N];
bool *own[N];
bool G[N][N];
stack<int> S;
vector<int> SCC;
bool ins[N], vis[M];
int dfs_clock, cnt_scc;
int dfn[N], low[N], bel[N];
int sz_sc[N];
bool *own_sc[N];
void dispose() {
  int D = 0;
  for (auto p : SCC) {
    D = gcd(D, sz[p]);
  }
  sz_sc[cnt_scc] = D;
  own_sc[cnt_scc] = alloc(D);
  bool *app = own_sc[cnt_scc];
  for (auto &p : SCC) {
    for (int i = 0; i < sz[p]; i++) {
      if (own[p][i]) {
        app[i % D] = true;
      }
    }
  }
}
void tarjan(int p) {
  dfn[p] = low[p] = ++dfs_clock;
  vis[p] = ins[p] = true;
  S.push(p);
  for (int e = 1; e <= n; e++) {
    if (G[p][e]) {
      if (!vis[e]) {
        tarjan(e);
        low[p] = min(low[p], low[e]);
      } else if (ins[e]) {
        low[p] = min(low[p], dfn[e]);
      }
    }
  }
  if (dfn[p] == low[p]) {
    int cur;
    SCC.clear();
    ++cnt_scc;
    do {
      cur = S.top();
      S.pop();
      SCC.push_back(cur);
      bel[cur] = cnt_scc;
      ins[cur] = false;
    } while (cur != p);
    dispose();
  }
}
int deg[N];
int order[N];
bool nG[N][N];
void rebuild() {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (bel[i] != bel[j] && G[i][j]) {
        nG[bel[i]][bel[j]] = true;
      }
    }
  }
  for (int i = 1; i <= cnt_scc; i++) {
    for (int j = i + 1; j <= cnt_scc; j++) {
      if (nG[i][j]) {
        deg[j]++;
      } else {
        deg[i]++;
      }
    }
  }
  for (int i = 1; i <= cnt_scc; i++) {
    order[deg[i]] = i;
  }
}
pair<int, int> A[N];
int comb[N][N];
int main() {
  scanf("%d%d%d", &n, &a, &b);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    for (int j = 1; j <= n; j++) {
      G[i][j] = s[j] - '0';
    }
  }
  for (int i = 1; i <= n; i++) {
    scanf("%d", sz + i);
    own[i] = alloc(sz[i]);
    scanf("%s", s);
    for (int j = 0; j < sz[i]; j++) {
      own[i][j] = s[j] - '0';
    }
  }
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      tarjan(i);
    }
  }
  rebuild();
  for (int i = 1; i < cnt_scc; i++) {
    int x = order[i - 1], y = order[i];
    int d = gcd(sz_sc[x], sz_sc[y]);
    memset(vis, false, d);
    for (int j = 0; j < sz_sc[x]; j++) {
      if (own_sc[x][j]) {
        vis[j % d] = true;
      }
    }
    for (int j = 0; j < sz_sc[y]; j++) {
      own_sc[y][j] = own_sc[y][j] || vis[j % d];
    }
  }
  for (int i = 1; i <= n; i++) {
    bool *app = own_sc[bel[i]];
    int D = sz_sc[bel[i]];
    for (int j = 0; j < sz[i]; j++) {
      if (own[i][j]) {
        A[i].second++;
      } else if (app[j % D]) {
        A[i].first++;
      }
    }
    A[i].first += A[i].second;
  }
  sort(A + 1, A + n + 1);
  reverse(A + 1, A + n + 1);
  comb[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    comb[i][0] = comb[i][i] = 1;
    for (int j = 1; j < i; j++) {
      comb[i][j] = add(comb[i - 1][j - 1], comb[i - 1][j]);
    }
  }
  int c = a - b, ans = 0;
  for (int i = b; i <= n; i++) {
    int x = 0, y;
    for (int j = 1; j < i; j++) {
      if (A[j].second > A[i].first) {
        x++;
      }
    }
    y = max(x - c, 0);
    for (int j = y; j < b; j++) {
      ans = (ans + comb[x][j] * 1ll * comb[i - x - 1][b - j - 1]) % Mod;
    }
  }
  printf("%d\n", ans);
  return 0;
}
