#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
long long gcd(long long a, long long b) {
  if (a == 0) return b;
  if (b == 0) return a;
  if (a > b) return gcd(b, a % b);
  return gcd(a, b % a);
}
vector<std::vector<long long> > cnk(5001, std::vector<long long>(5001, 0));
char g[5000][5000];
char reach[5000][5000];
const int MAXN = 5100;
vector<int> lst[MAXN];
int parent[MAXN];
void make_set(int v) {
  lst[v] = vector<int>(1, v);
  parent[v] = v;
}
int find_set(int v) { return parent[v]; }
void union_sets(int a, int b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (lst[a].size() < lst[b].size()) swap(a, b);
    while (!lst[b].empty()) {
      int v = lst[b].back();
      lst[b].pop_back();
      parent[v] = a;
      lst[a].push_back(v);
    }
  }
}
vector<char> used;
vector<int> order, component;
int n, a, b;
void dfs1(int v) {
  used[v] = true;
  for (int u = 0; u < n; u++)
    if (g[v][u])
      if (!used[u]) dfs1(u);
  order.push_back(v);
}
void dfs2(int v) {
  used[v] = true;
  component.push_back(v);
  for (int u = 0; u < n; u++)
    if (g[u][v])
      if (!used[u]) dfs2(u);
}
std::vector<int> ss;
std::vector<string> s;
void cond() {
  used.assign(n, false);
  for (int i = 0; i < n; ++i)
    if (!used[i]) dfs1(i);
  used.assign(n, false);
  for (int i = 0; i < n; ++i) {
    int v = order[n - 1 - i];
    if (!used[v]) {
      dfs2(v);
      for (int j = 0; j < component.size() - 1; j++) {
        int a = component[j];
        int b = component[j + 1];
        union_sets(a, b);
      }
      component.clear();
    }
  }
}
int main() {
  for (int i = 0; i < 5001; i++) cnk[i][0] = 1;
  for (int i = 1; i < 5001; i++) {
    for (int j = 1; j < min(i + 1, 5001); j++) {
      cnk[i][j] = (cnk[i - 1][j] + cnk[i - 1][j - 1]) % mod;
    }
  }
  scanf("%d %d %d\n", &n, &a, &b);
  for (int i = 0; i < n; i++) make_set(i);
  for (int i = 0; i < n; i++) {
    char c[5001];
    scanf("%s", c);
    string s(c);
    for (int j = 0; j < n; j++) {
      if (s[j] == '1') {
        g[i][j] = 1;
      }
    }
  }
  cond();
  std::vector<int> grp;
  ss.resize(n);
  s.resize(n);
  char c[2000001];
  for (int i = 0; i < n; i++) {
    scanf("%d %s", &ss[i], c);
    s[i] = string(c);
    for (auto& c : s[i])
      if (c == '0')
        c = '1';
      else
        c = '0';
  }
  std::vector<std::vector<int> > ns(n);
  for (int i = 0; i < n; i++) {
    if (lst[i].size() > 0) {
      grp.push_back(i);
      int d = 0;
      for (auto v : lst[i]) {
        d = gcd(d, ss[v]);
      }
      ns[i] = std::vector<int>(d, 0);
      for (auto v : lst[i]) {
        for (int j = 0; j < ss[v]; j++) {
          if (s[v][j] == '0') ns[i][j % d] = 1;
        }
      }
    }
  }
  std::vector<std::vector<int> > dout(n);
  std::vector<int> din(n, 0);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      if (g[i][j] != 1) continue;
      int a = find_set(i);
      int b = find_set(j);
      if (a != b && reach[a][b] == 0) {
        din[b]++;
        dout[a].push_back(b);
        for (int k = 0; k < n; k++) {
          reach[a][k] |= reach[b][k];
        }
        reach[a][b] = 1;
      }
    }
  std::vector<int> done(n, 0);
  int did = 0;
  while (did < n) {
    for (int i = 0; i < n; i++) {
      if (done[i]) continue;
      if (din[i] == 0) {
        for (auto u : dout[i]) {
          int a = ns[i].size();
          int b = ns[u].size();
          int d = gcd(a, b);
          for (int res = 0; res < d; res++) {
            int can = 0;
            for (int ta = res; ta < a; ta += d)
              if (ns[i][ta]) can = 1;
            if (can)
              for (int tb = res; tb < b; tb += d) ns[u][tb] = 1;
          }
          din[u]--;
        }
        done[i] = 1;
        did++;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    int host = find_set(i);
    int d = ns[host].size();
    for (int j = 0; j < ss[i]; j++) {
      if (s[i][j] == '1' && ns[host][j % d] == 1) s[i][j] = '2';
    }
  }
  std::vector<int> amx, amn;
  for (int i = 0; i < n; i++) {
    int mn = 0;
    int mx = 0;
    for (auto c : s[i]) {
      if (c == '0')
        mn++;
      else if (c == '2')
        mx++;
    }
    mx += mn;
    amx.push_back(mx);
    amn.push_back(mn);
  }
  sort((amx).begin(), (amx).end());
  sort((amn).begin(), (amn).end());
  reverse((amx).begin(), (amx).end());
  reverse((amn).begin(), (amn).end());
  long long ans = 0;
  int pt = 0;
  for (int i = 0; i < n; i++) {
    int cur = amx[i];
    while (amn[pt] > cur) pt++;
    for (int x = max(pt + b - a, 0); x < min(b, pt + 1); x++) {
      ans = (ans + cnk[pt][x] * cnk[i - pt][b - 1 - x]) % mod;
    }
  }
  cout << ans;
}
