//cpy from International grander master Wangzhanpeng
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define PI pair<int,int>
#define mp make_pair
inline ll read(){
	bool pos=1; ll x=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar())if(ch=='-')pos=0;
	for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	return pos?x:-x;
}
void write(ll x){
	if(x<0){x=-x; putchar('-');}
	if(x>=10)write(x/10);putchar(x%10+'0');
}
void writeln(ll x){write(x);putchar('\n');}
const int N=5005,M=2000005,mod=1000000007;
char ch[M];
int c[N][N],s[N],l[N],r[N],top,ans,G[N],q[N],bel[N],fa[N];
bool zs[M],vis[M];
vector<bool> v[N],GG[N];
inline int gf(int x){
	return fa[x]==x?x:x=gf(fa[x]);
}
void Mer(int x,int y){
	int tx=gf(x),ty=gf(y);
	fa[tx]=ty;
}
void bao(vector<bool> &v,vector<bool> &GG){
	int x=v.size(),y=GG.size(),t=__gcd(x,y);
	for(int i=0;i<t;i++)zs[i]=0;
	for(int i=0;i<x;i++)if(v[i])zs[i%t]=1;
	for(int i=0;i<y;i++)if(!GG[i])GG[i]=zs[i%t];
}
void del(int pos){
	for(int i=pos;i<top;i++)q[i]=q[i+1]; top--;
}
void ins(int pos,int de){
	for(int i=top;i>=pos;i--)q[i+1]=q[i]; q[pos]=de; top++;
}
int main(){
	int n=read(),a=read(),b=read();
	for(int i=0;i<=n;i++){
		for(int j=c[i][0]=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	}
	top=0;
	for(int i=1;i<=n;i++){
		scanf("%s",ch+1); fa[i]=i;
		int mx=0,mn=top+1,ne=i;
		for(int j=1;j<i;j++)if(ch[j]=='1')mx=max(mx,bel[gf(j)]); else mn=min(mn,bel[gf(j)]);
		if(mx>=mn){
			for(int i=mx;i>mn;i--)Mer(ne,q[i]); Mer(ne,q[mn]);
			for(int i=mx;i>mn;i--)del(i);
		}else{
			ins(mn,ne);
		}
		for(int j=1;j<=top;j++)bel[q[j]]=j;
	}
	for(int i=1;i<=n;i++){
		s[i]=read();
		v[i].resize(s[i]);
		scanf("%s",ch);
		for(int j=0;j<s[i];j++)l[i]+=(v[i][j]=ch[j]-'0');
		G[gf(i)]=__gcd(G[gf(i)],s[i]);
	}
	for(int i=1;i<=n;i++)if(gf(i)==i)GG[i].resize(G[i]);
	for(int i=1;i<=n;i++){
		bao(v[i],GG[gf(i)]);
	}
	for(int i=top;i>1;i--){
		int x=q[i],y=q[i-1];
		bao(GG[x],GG[y]);
	}
	for(int i=1;i<=n;i++){
		bao(GG[gf(i)],v[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<s[i];j++)r[i]+=v[i][j]; vis[r[i]]=1;
	}
	for(int i=0;i<M;i++)if(vis[i]){
		int s1=0,s2=0,s3=0,s4=0;
		for(int j=1;j<=n;j++)if(l[j]>i)s1++; else if(r[j]>i)s2++; else if(r[j]==i)s3++; else s4++;
		int s5=max(0,s1-(a-b));
		for(int i=s5;i<=s1&&b>=i;i++)ans=(ans+c[s1][i]*((ll)c[s2+s3][b-i]-c[s2][b-i]))%mod;
		//b集合中至少要有1个s3，集合外不能超过a-b个s1，也就是集合内至少有s1-(a-b)
	}
	cout<<(ans+mod)%mod<<endl;
}
/*
5 2 1
00000
10000
11011
11000
11010
2 00
1 1
6 100110
1 0
1 0

考虑一个元素他能赢的集合
一个大小为b的集合可以出现当且仅当
对于集合(b)内元素r的最小值>=集合外元素(n-b)l的a-b+1大值
[2,2] [1,6]
考虑DP,枚举最小值之后,集合b内只能包含一些元素:r>=x
也就是说集合n-b包含不超过a-b个元素 :l>x
也就是说集合b包含至少...个元素 :l>x
对于i有的,i-j有边的,考虑他们的更新

*/

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
vector <int> have_real[5005],have_gold[5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			L[i]+=x;
			have_real[i].push_back(x);
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=tot;i++) have_gold[i].resize(siz_new[i]+1);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz_new[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=1ll*all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=1ll*C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			if(ans>MOD) ans-=MOD;
			if(ans<0) ans+=MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXM 2000005
#define MAXN 5005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}

stack <int> S;
vector <int> G[MAXN],g[MAXN],f[MAXN];
int n,k1,k2,cnt,Index,s[MAXN],mn[MAXN],mx[MAXN],bg[MAXN],dfn[MAXN],low[MAXN],bel[MAXN],vis[MAXN],tot[MAXN];

int gcd (int a,int b){return !b ? a : gcd (b,a % b);}
void Tarjan (int u){
	S.push (u),dfn[u] = low[u] = ++ Index,vis[u] = 1;
	for (Int i = 0,v,len = G[u].size();i < len;++ i){
		v = G[u][i];
		if (!dfn[v]){
			Tarjan (v);
			low[u] = min (low[u],low[v]);
		}
		else if (vis[v]) low[u] = min (low[u],dfn[v]);
	}
	if (dfn[u] == low[u]){
		++ cnt;
		while (1){
			int now = S.top();S.pop ();
			vis[now] = 0,bel[now] = cnt,bg[cnt] = gcd (bg[cnt],s[now]);
			if (u == now) break;
		}
	}
}

char str[MAXM];

void Putin (){
	read (n,k1,k2);
	for (Int i = 1;i <= n;++ i){
		scanf ("%s",str + 1);
		for (Int j = 1;j <= n;++ j) if (str[j] == '1') G[i].push_back (j);
	}
	for (Int i = 1;i <= n;++ i){
		read (s[i]),scanf ("%s",str + 1);
		for (Int j = 1;j <= s[i];++ j) g[i].push_back (str[j] - '0'),mn[i] += str[j] - '0';
	}
}

namespace Part1{
	void Solve (){
		for (Int i = 1;i <= n;++ i) if (!dfn[i]) Tarjan (i);
		for (Int i = 1;i <= cnt;++ i) f[i].resize (bg[i] + 1);
		for (Int i = 1;i <= n;++ i) for (Int j = 0;j < s[i];++ j) f[bel[i]][j % bg[bel[i]]] |= g[i][j];
		for (Int i = cnt;i > 1;-- i){
			int now = gcd (bg[i],bg[i - 1]);
			for (Int j = 0;j < bg[i];++ j) f[i - 1][j % now] |= f[i][j],tot[i] += f[i][j];
		}
		for (Int i = 0;i < bg[1];++ i) tot[1] += f[1][i];
		for (Int i = 1;i <= n;++ i) mx[i] = 1ll * tot[bel[i]] * s[i] / bg[bel[i]];
	}
}

namespace Part2{
#define mod 1000000007
	int fac[MAXM],ifac[MAXM];
	int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
	int qkpow (int a,int b){int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;return res;}
	int binom (int a,int b){return (a < b || a < 0 || b < 0) ? 0 : 1ll * fac[a] * ifac[b] % mod * ifac[a - b] % mod;}
	void Solve (){
		int up = MAXM - 5;
		fac[0] = 1;for (Int i = 1;i <= up;++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
		ifac[up] = qkpow (fac[up],mod - 2);for (Int i = up;i;-- i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
		int ans = 0;
		for (Int i = 1;i <= n;++ i){
			int cnt1 = 0,cnt2 = 0;
			for (Int j = 1;j <= n;++ j){
				if (i == j) continue;
				else if (mx[i] < mn[j]) cnt1 ++;
				else if (mx[i] < mx[j] || (mx[i] == mx[j] && i < j)) cnt2 ++;
			}
			if (cnt1 >= k1) continue;
			for (Int j = min (k2,min (k1 - 1 - cnt1,cnt2));j + cnt1 + 1 >= k2;-- j) ans = add (ans,1ll * binom (cnt1,k2 - j - 1) * binom (cnt2,j) % mod);
		}
		write (ans),putchar ('\n');
	}
#undef mod
}

signed main(){
	Putin (),Part1::Solve (),Part2::Solve ();
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef bool boolean;

const int N = 5e3 + 5, M = 2e6 + 5, Mod = 1e9 + 7;

int add(int a, int b) {
	return ((a += b) >= Mod) ? (a - Mod) : (a);
}

#define pii pair<int, int>

int gcd(int a, int b) {
	return (!b) ? (a) : (gcd(b, a % b));
}

boolean _pool[M << 1];
boolean *_top = _pool;

boolean* alloc(int sz) {
	boolean *top = _top;
	_top += sz;
	return top;
}

int n, a, b;
char s[M];
int sz[N];
boolean* own[N];
boolean G[N][N];

stack<int> S;
vector<int> SCC;
boolean ins[N], vis[M];
int dfs_clock, cnt_scc;
int dfn[N], low[N], bel[N];

int sz_sc[N];
boolean *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);
	boolean *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];
boolean 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;
	}
}

pii 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++) {
		boolean *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;
}

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
inline int read()
{
    int x=0; char ch=getchar(); bool f=0;
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
    return f?-x:x;
}
#define CASET fo(___,1,read())
const int N=5005;
const int M=2e6+3;
int n;

namespace Part1{
    string s[N]; char t[N];
    int m[N];
    int st[N],dfn[N],low[N],top,cnt,belong[N],tim,in[N],g[N],now[N];
    bool instack[N],vi[M];
    vector<int> adj[N],vec[N],p[N];
    vector<bool> vis[N];
    inline void add(int x,int y)
    {
        adj[x].pb(y);
    }
    inline void dfs(int u,int pre)
    {
        instack[u]=1;
        st[++top]=u;
        dfn[u]=low[u]=++tim;
        for(auto v:adj[u])
            if(!dfn[v]) dfs(v,u),low[u]=min(low[u],low[v]);
            else if(instack[v]) low[u]=min(low[u],dfn[v]);
        if(low[u]==dfn[u])
        {
            cnt++;
            int d=0,v;
            do
            {
                v=st[top--];
                instack[v]=0;
                d=__gcd(d,m[v]);
                belong[v]=cnt;
                p[cnt].pb(v);
            }while(u!=v);
            g[cnt]=d;
        }
    }
    inline void work()
    {
        fo(i,1,n) if(!dfn[i]) dfs(i,0);
        fo(i,1,n)
            for(auto v:adj[i])
                if(belong[v]!=belong[i])
                    vec[belong[i]].pb(belong[v]);
        fo(i,1,cnt) sort(all(vec[i])),vec[i].resize(unique(all(vec[i]))-vec[i].begin());
        fo(u,1,cnt) for(auto v:vec[u]) in[v]++;
    }
    queue<int> q;
    inline void solve(int *mn,int *mx)
    {
        fo(i,1,n)
        {
            scanf("%s",t+1);
            fo(j,1,n) if(t[j]=='1') add(i,j);
        }
        fo(i,1,n)
        {
            m[i]=read();
            cin>>s[i];
            fo(j,0,m[i]-1) mn[i]+=(s[i][j]=='1');
        }
        work();
        fo(u,1,cnt) if(!in[u]) q.push(u);
        fo(u,1,cnt) now[u]=g[u],vis[u].resize(g[u]);
        for(int u;!q.empty();)
        {
            u=q.front(); q.pop();
            for(auto i:p[u])
            {
                fo(j,0,m[i]-1)
                    if(s[i][j]=='1')
                        vis[u][j%g[u]]=1;
            }
            for(auto v:vec[u])
            {
                --in[v];
                if(!in[v])
                {
                    q.push(v);
                    now[v]=__gcd(now[u],now[v]);
                    fo(i,0,g[u]-1)
                        if(vis[u][i])
                            vi[i%now[v]]=1;
                    fo(i,0,now[v]-1)
                        if(vi[i])
                            for(int j=i;j<g[v];j+=now[v])
                                vis[v][j]=1;
                    fo(i,0,now[v]-1) vi[i]=0;
                }
            }
        }

        fo(i,1,cnt)
        {
            int sum=0;
            fo(j,0,g[i]-1) if(vis[i][j]) sum++;
            for(auto v:p[i]) mx[v]=(1ll*m[v]*sum)/g[i];
        }
    }
}
const ll mod=1e9+7;
inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;}
inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;}
inline ll Mul(ll x,ll y){return x*y%mod;}
inline ll Pow(ll x,ll y){y%=(mod-1);ll ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1) ans=ans*x%mod;return ans;}
namespace Part2{
    ll fac[N],inv[N];
    inline void init(int n)
    {
        fac[0]=1;
        fo(i,1,n) fac[i]=fac[i-1]*i%mod;
        inv[n]=Pow(fac[n],mod-2);
        fd(i,n,1) inv[i-1]=inv[i]*i%mod;
    }
    inline ll C(int n,int m)
    {
        return fac[n]*inv[m]%mod*inv[n-m]%mod;
    }
    inline ll solve(int *l,int *r,int A,int B)
    {
        A=min(A,n);
        init(n);
        ll x,y,ans=0;
        fo(i,1,n)
        {
            x=y=0;
            fo(j,1,n)
            {
                if(l[j]>r[i]) x++;
                if(l[j]<=r[i]&&((r[i]<r[j])||(r[i]<=r[j]&&i>j))) y++;//???
            }
            if(x>=A) continue;
            int tmp=min(y,A-1-x);
            tmp=min(B-1,tmp);
            fo(j,0,tmp)
                if(B-j-1<=x)
                    ans=Add(ans,Mul(C(y,j),C(x,B-j-1)));
        }
        return ans;
    }
}
int A,B;
int mi[N],mx[N];
int main()
{
    n=read(); A=read(); B=read();
    Part1::solve(mi,mx);
    printf("%lld",Part2::solve(mi,mx,A,B));
    return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n, a, b, c;
char str[MAXL + 5];
vector<int> G[MAXN + 5];
vector<int> per[MAXN + 5];
int siz[MAXN + 5], dfn[MAXN + 5], low[MAXN + 5], dcnt;
int blo[MAXN + 5], bgcd[MAXN + 5], blocnt;
int stk[MAXN + 5], t;
int num[MAXN + 5], mx[MAXN + 5], mn[MAXN + 5];
bool instk[MAXN + 5];
int fact[MAXN + 5], inv[MAXN + 5];
int PowMod(int x, int y)
{
    int ret = 1;
    while (y)
    {
        if (y & 1)
            ret = 1LL * ret * x % MO;
        x = 1LL * x * x % MO;
        y >>= 1;
    }
    return ret;
}
int gcd(int x, int y)
{
    if (y == 0)
        return x;
    return gcd(y, x % y);
}
void InPut()
{
    scanf("%d %d %d", &n, &a, &b);
    for (int i = 1; i <= n; i++)
    {
        scanf("%s", str + 1);
        for (int j = 1; j <= n; j++)
            if (str[j] == '1')
                G[i].push_back(j);
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &siz[i]);
        per[i].resize(siz[i] + 1);
        scanf("%s", str);
        for (int j = 0; j < siz[i]; j++)
            if (str[j] == '1')
                per[i][j] = 1;
            else if (str[j] == '0')
                per[i][j] = 0;
    }
}
void Tarjan(int u, int fa)
{
    dfn[u] = low[u] = ++dcnt;
    instk[u] = true;
    stk[t++] = u;
    for (int i = 0; i < (int)G[u].size(); i++)
    {
        int v = G[u][i];
        if (dfn[v] == 0)
        {
            Tarjan(v, u);
            low[u] = min(low[u], low[v]);
        }
        else if (instk[v] == true)
            low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u])
    {
        int fro = 0;
        blocnt++;
        do
        {
            fro = stk[--t];
            instk[fro] = false;
            blo[fro] = blocnt;
            bgcd[blocnt] = gcd(bgcd[blocnt], siz[fro]);
        } while (fro != u);
    }
}
void Part1()
{
    for (int i = 1; i <= n; i++)
        if (dfn[i] == 0)
            Tarjan(i, -1);
    for (int i = 1; i <= blocnt; i++)
        per[i + n].resize(bgcd[i] + 1); //预先设定大小
    for (int i = 1; i <= n; i++)
        for (int j = 0; j < siz[i]; j++)
            per[blo[i] + n][j % bgcd[blo[i]]] |= per[i][j]; //存到虚拟黑帮中
    int nw;
    for (int i = blocnt; i > 1; i--) //自然形成了哈密顿路径
    {
        nw = gcd(bgcd[i], bgcd[i - 1]); //当前的剩余系
        for (int j = 0; j < bgcd[i]; j++)
            if (per[i + n][j])
            {
                per[i - 1 + n][j % nw] |= 1; //对下一个点进行更新
                num[i]++;                    //num就是总的金条数
            }
    }
    for (int j = 0; j < bgcd[1]; j++)
        num[1] += per[1 + n][j]; //记得一定要统计block1的值
    for (int i = 1; i <= n; i++)
    {
        mx[i] = mn[i] = 0;
        mx[i] = 1LL * num[blo[i]] * siz[i] / bgcd[blo[i]];
        for (int j = 0; j < siz[i]; j++)
            mn[i] += per[i][j];
    }
}
void Prepare()
{
    fact[0] = 1;
    for (int i = 1; i <= MAXN; i++)
        fact[i] = 1LL * fact[i - 1] * i % MO;
    inv[MAXN] = PowMod(fact[MAXN], MO - 2);
    for (int i = MAXN - 1; i >= 0; i--)
        inv[i] = 1LL * inv[i + 1] * (1LL * i + 1LL) % MO;
}
inline int C(int x, int y)
{
    return 1LL * fact[x] * inv[y] % MO * inv[x - y] % MO;
}
int Part2()
{
    Prepare();
    int cnt1 = 0, cnt2 = 0, ret = 0;
    for (int i = 1; i <= n; i++)
    {
        cnt1 = cnt2 = 0;
        for (int j = 1; j <= n; j++)
        {
            if (i != j && mn[j] > mx[i])
                cnt1++;
            if (i != j && mn[j] <= mx[i] && (mx[j] > mx[i] || (mx[j] == mx[i] && j < i))) //避免重复
                cnt2++;
        }
        if (cnt1 > a - 1)
            continue;
        for (int j = min(b, min(a - 1 - cnt1, cnt2)); j >= 0 && j + 1 + cnt1 >= b; j--) //一堆限制
            ret = (1LL * ret + 1LL * C(cnt2, j) * C(cnt1, b - j - 1) % MO) % MO;
    }
    return ret;
}
int main()
{
    InPut();
    Part1();
    int ans = Part2();
    printf("%d\n", ans);
    return 0;
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		   inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
	}
	return printf( "%d\n", ans ), 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int N=5e3+100;
int low[N],dfn[N],sta[N],col[N],b[N],gmin[N],up[N],down[N],nxt[N],sum[N];
int *mat[N];
string c[N];
char s[N];
bool a[N][N],d[N][N];
int n,A,B,dfstime,cnt,top,root;
ll fac[N],inv[N],ans;
int gcd(int x,int y){
	if (!x||!y) return x+y;
	int z=x%y;
	while (z){
		x=y;y=z;z=x%y;
	}
	return y;
}
void tarjan(int now){
	sta[++top]=now; dfn[now]=++dfstime; low[now]=dfstime;
	for (int i=1;i<=n;i++) if (a[now][i]) {
		if (dfn[i]&&!col[i]) low[now]=min(low[now],dfn[i]);
		else if (!col[i]){
			tarjan(i); low[now]=min(low[now],low[i]);
		}
	}
	if (low[now]>=dfn[now]) {
		int x=0; cnt++; int r=top;
		while (sta[top]!=now) {
			col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
 		}
		col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
		mat[cnt]=new int[x]; gmin[cnt]=x;
		memset(mat[cnt],0,sizeof(mat[cnt]));
		for (int i=top+1;i<=r;i++) {
			int u=sta[i];
			for (int j=0;j<b[u];j++) if (c[u][j]=='1') mat[cnt][j%x]=1;
		}
	}
}
void init(){
	fac[0]=1; for(int i=1;i<N;i++) fac[i]=(1ll*fac[i-1]*i)%mod;
	inv[0]=1; inv[1]=1; for(int i=2;i<N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for (int i=1;i<N;i++) inv[i]=(inv[i-1]*inv[i])%mod;
}
ll C(int x,int y){
	if (x<0||y<0||x<y) return 0;
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
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++) if (s[j]=='1') a[i][j]=1; else a[i][j]=0;
	}
	for (int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		cin >> c[i];
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) dfstime=0,tarjan(i);
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++) if (a[i][j]&&col[i]!=col[j]) d[col[i]][col[j]]=1;
	}
	int head=1,tail=1;
	for (int i=2;i<=cnt;i++) {
		if (d[i][head]) nxt[i]=head,head=i; else if (d[tail][i]) nxt[tail]=i,tail=i;
		else {
			int x=head;
			while (x!=tail) {
				if (d[x][i]&&d[i][nxt[x]]) {nxt[i]=nxt[x],nxt[x]=i;break;} else x=nxt[x];
			}
		}
	}
	while (head!=tail){
		int x=gcd(gmin[head],gmin[nxt[head]]);
		if (gmin[head]) for (int i=0;i<gmin[head];i++) if (mat[head][i]) mat[nxt[head]][i%x]=1;
		head=nxt[head];
	}
	for (int i=1;i<=cnt;i++)
		for (int j=0;j<gmin[i];j++) if (mat[i][j]) sum[i]++;
	for (int i=1;i<=n;i++) {
		for (int j=0;j<b[i];j++) if (c[i][j]=='1') down[i]++;
		up[i]=sum[col[i]]*(b[i]/gmin[col[i]]);
	}
	init();
//	for (int i=1;i<=n;i++) cout << down[i] << ' ' << up[i] << endl;
	for (int i=1;i<=n;i++)  {
		int cnt1=0,cnt2=0;
		for (int j=1;j<=n;j++) if (j!=i&&(down[j]>up[i])) cnt1++;
		else if (j!=i&&(up[j]>up[i]||((up[j]==up[i])&&(j<i)))) cnt2++;
//		cout << cnt1 << ' ' << cnt2 << endl;
		for (int j=0;j<=min(B-1,cnt2);j++) if (j+cnt1+1<=A) ans=(ans+C(cnt2,j)*C(cnt1,B-j-1)%mod)%mod;
//		cout << ans << ' ' << i << endl;
	}
	printf("%lld\n",ans);
}

#include <bits/stdc++.h>

#define x first
#define y second
#define y1 Y1
#define y2 Y2
#define mp make_pair
#define pb push_back
#define DEBUG(x) cout << #x << " = " << x << endl;

using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

template <typename T> inline int Chkmax (T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline int Chkmin (T &a, T b) { return a > b ? a = b, 1 : 0; }
template <typename T> inline T read ()
{
	T sum = 0, fl = 1; char ch = getchar();
	for (; !isdigit(ch); ch = getchar()) if (ch == '-') fl = -1;
	for (; isdigit(ch); ch = getchar()) sum = (sum << 3) + (sum << 1) + ch - '0';
	return sum * fl;
}

inline void proc_status ()
{
	ifstream t ("/proc/self/status");
	cerr << string (istreambuf_iterator <char> (t), istreambuf_iterator <char> ()) << endl;
}

const int Maxn = 8e6 + 5;
const int Mod = 1e9 + 7;

int N, A, B;
int size[Maxn], Belong[Maxn];
int L[Maxn], R[Maxn];
bool Map[5010][5010];
vector <int> S[Maxn];

namespace MATH
{
	int fac[Maxn], ifac[Maxn];

	inline void Add (int &a, int b) { if ((a += b) >= Mod) a -= Mod; }

	inline int Pow (int a, int b)
	{
		int ans = 1;
		for (int i = b; i; i >>= 1, a = (LL) a * a % Mod) if (i & 1) ans = (LL) ans * a % Mod;
		return ans;
	}

	inline int C (int n, int m)
	{
		if (n < 0 || n < m) return 0;
		return (LL) fac[n] * ifac[m] % Mod * ifac[n - m] % Mod;
	}

	inline void init (int n = 1e4)
	{
		fac[0] = 1;
		for (int i = 1; i <= n; ++i) fac[i] = (LL) fac[i - 1] * i % Mod;
		ifac[n] = Pow (fac[n], Mod - 2);
		for (int i = n - 1; i >= 0; --i) ifac[i] = (LL) ifac[i + 1] * (i + 1) % Mod;
	}
}

using namespace MATH;

namespace P1
{
	int tot;
	int dfn[Maxn], low[Maxn], dfs_clock, in_stk[Maxn];
	int stk[Maxn], top;

	inline void tarjan (int x)
	{
		stk[++top] = x; in_stk[x] = 1;
		dfn[x] = low[x] = ++dfs_clock;

		for (int y = 1; y <= N; ++y) if (Map[x][y])
		{
			if (!dfn[y]) tarjan (y), Chkmin (low[x], low[y]);
			else if (in_stk[y]) Chkmin (low[x], dfn[y]);
		}

		if (dfn[x] == low[x])
		{
			++tot;
			int tmp = top;
			while (1)
			{
				int a = stk[top--];

				in_stk[a] = 0;
				size[tot] = __gcd (size[tot], size[a]);
				Belong[a] = tot;

				if (a == x) break;
			}

			for (int i = 0; i <= size[tot]; ++i) S[tot].pb (0);
			for (int i = top + 1; i <= tmp; ++i)
				for (int j = 0; j < size[stk[i]]; ++j)
					S[tot][j % size[tot]] |= S[stk[i]][j];
		}
	}

	int Sum[Maxn];

	inline void main ()
	{
		tot = N;
		for (int i = 1; i <= N; ++i) if (!dfn[i]) tarjan (i);

		for (int i = tot - 1; i > N; --i)
		{
			int g = __gcd (size[i], size[i + 1]);
			for (int j = 0; j < size[i + 1]; ++j) S[i][j % g] |= S[i + 1][j];
			for (int j = 0; j < size[i]; ++j) S[i][j] |= S[i][j % g];
		}

		for (int i = N + 1; i <= tot; ++i)
			for (int j = 0; j < size[i]; ++j)
				Sum[i] += S[i][j];

		for (int i = 1; i <= N; ++i)
		{
			int x = Belong[i];
			R[i] = (LL) size[i] / size[x] * Sum[x];
		}
	}
}

int ans;

namespace P2
{
	inline void main ()
	{
		for (int i = 1; i <= N; ++i)
		{
			int cnt1 = 0, cnt2 = 0;
			for (int j = 1; j <= N; ++j)
			{
				if (i == j) continue;
				if (L[j] > R[i]) ++cnt1;
				else if (R[j] > R[i] || (R[i] == R[j] && j < i)) ++cnt2;
			}

			for (int j = 0; j <= min (A - cnt1 - 1, B - 1); ++j)
				Add (ans, (LL) C (cnt2, j) * C (cnt1, B - 1 - j) % Mod);
		}
	}
}

inline void Solve ()
{
	MATH :: init ();
	P1 :: main();
	P2 :: main();
	cout << ans << endl;
}

inline void Input ()
{
	N = read<int>(), A = read<int>(), B = read<int>();
	for (int i = 1; i <= N; ++i)
	{
		char Str[Maxn];
		scanf("%s", Str + 1);
		for (int j = 1; j <= N; ++j) if (Str[j] == '1') Map[i][j] = 1;
	}

	for (int i = 1; i <= N; ++i)
	{
		size[i] = read<int>();
		char Str[Maxn];
		scanf("%s", Str);
		for (int j = 0; j < size[i]; ++j)  if (Str[j] == '1') S[i].pb (1), ++L[i]; else S[i].pb (0);
		S[i].pb (0);
	}
}

int main()
{

	Input ();
	Solve ();

	return 0;
}

#include <iostream>
#include <vector>
#include <stack>

typedef long long LL;

using namespace std;

const int maxN = 5e3 + 2;
const int mod = 1e9 + 7;

int n, a, b, dfst, colcnt, ans;
int dfn[maxN], low[maxN], col[maxN], minn[maxN], maxx[maxN]; // point
int gcd[maxN], cnt[maxN]; // SCC
int fac[maxN]; // math
stack<int> stk;
vector<int> G[maxN]; // graph, not g
vector<bool> tmp, F[maxN];
string S[maxN];

inline bool Chkmin(int& x, int y)
{ return x > y ? x = y, true : false; }

inline void Mod(int& x)
{ x >= mod ? x -= mod : 0; }

inline int GCD(int x, int y)
{
    while (y)
        std::swap(x, y), y %= x;
    return x;
}

inline int Qpow(int a, int n)
{
    if (a == 1)
        return 1;
    if (n == -1)
        return Qpow(a, mod - 2);
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = (LL)res * a % mod;
        a = (LL)a * a % mod;
        n >>= 1;
    }
    return res;
}

void Tarjan(int u)
{
    dfn[u] = low[u] = ++dfst;
    stk.push(u);
    for (int v : G[u])
    {
        if (!dfn[v])
            Tarjan(v), Chkmin(low[u], low[v]);
        else if (!col[v])
            Chkmin(low[u], dfn[v]);
    }
    if (low[u] == dfn[u])
    {
        ++colcnt;
        col[u] = colcnt, gcd[colcnt] = S[u].size();
        while (stk.top() != u)
        {
            int v = stk.top();
            stk.pop();
            col[v] = colcnt, gcd[colcnt] = GCD(gcd[colcnt], S[v].size());
        }
        stk.pop();
    }
}

inline int C(int n, int m) // C _n ^m
{ return (LL)fac[n] * Qpow(fac[m], -1) % mod * Qpow(fac[n - m], -1) % mod; }

int main()
{
#ifndef ONLINE_JUDGE
    freopen("wib.in", "r", stdin);
    freopen("wib.out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    cin >> n >> a >> b;
    for (int i = 1; i <= n; ++i)
    {
        cin >> S[1];
        for (int j = 1; j <= n; ++j)
            if (S[1][j - 1] == '1')
                G[i].push_back(j);
    }
    for (int i = 1; i <= n; ++i)
    {
        int sth; // something... whatever - -
        cin >> sth >> S[i];
    }
    for (int i = 1; i <= n; ++i)
        if (!dfn[i])
            Tarjan(i);
    for (int i = 1; i <= colcnt; ++i)
        F[i].resize(gcd[i]);
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < S[i].size(); ++j)
            if (S[i][j] == '1')
                ++minn[i], F[col[i]][j % gcd[col[i]]] = true;
    for (int i = colcnt; i > 1; --i)
    {
        int curr = GCD(gcd[i], gcd[i - 1]);
        tmp.clear(), tmp.resize(curr);
        for (int j = 0; j < gcd[i]; ++j)
            if (F[i][j])
                tmp[j % curr] = true;
        for (int j = 0; j < gcd[i - 1]; ++j)
            if (tmp[j % curr])
                F[i - 1][j] = true;
    }
    for (int i = 1; i <= colcnt; ++i)
        for (int j = 0; j < gcd[i]; ++j)
            cnt[i] += F[i][j];
    for (int i = 1; i <= n; ++i)
        maxx[i] = S[i].size() / gcd[col[i]] * cnt[col[i]];
    // for (int i = 1; i <= n; ++i)
        // cout << minn[i] << ' ' << maxx[i] << endl;
    // subtask1 end
    fac[0] = 1;
    for (int i = 1; i <= n; ++i)
        fac[i] = (LL)fac[i - 1] * i % mod;
    for (int i = 1; i <= n; ++i)
    {
        int cnt1 = 0, cnt2 = 0;
        for (int j = 1; j <= n; ++j)
        {
            if (i == j)
                continue;
            if (minn[j] > maxx[i])
                ++cnt1;
            else if (maxx[j] > maxx[i] or (maxx[j] == maxx[i] and j < i))
                ++cnt2;
        }
        if (cnt1 >= a)
            continue;
        for (int x = min(b - 1, min(cnt2, a - 1 - cnt1)); x + cnt1 + 1 >= b and x >= 0; --x)
            Mod(ans += (LL)C(cnt1, b - x - 1) * C(cnt2, x) % mod);
    }
    cout << ans << endl;
    return 0;
}

#include <iostream>
#include <vector>
#include <stack>

typedef long long LL;

using namespace std;

const int maxN = 5e3 + 2;
const int mod = 1e9 + 7;

int n, a, b, dfst, colcnt, ans;
int dfn[maxN], low[maxN], col[maxN], minn[maxN], maxx[maxN]; // point
int gcd[maxN], cnt[maxN]; // SCC
int fac[maxN]; // math
stack<int> stk;
vector<int> G[maxN]; // graph, not g
vector<bool> tmp, F[maxN];
string S[maxN];

inline bool Chkmin(int& x, int y)
{ return x > y ? x = y, true : false; }

inline void Mod(int& x)
{ x >= mod ? x -= mod : 0; }

inline int GCD(int x, int y)
{
    while (y)
        std::swap(x, y), y %= x;
    return x;
}

inline int Qpow(int a, int n)
{
    if (a == 1)
        return 1;
    if (n == -1)
        return Qpow(a, mod - 2);
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = (LL)res * a % mod;
        a = (LL)a * a % mod;
        n >>= 1;
    }
    return res;
}

void Tarjan(int u)
{
    dfn[u] = low[u] = ++dfst;
    stk.push(u);
    for (int v : G[u])
    {
        if (!dfn[v])
            Tarjan(v), Chkmin(low[u], low[v]);
        else if (!col[v])
            Chkmin(low[u], dfn[v]);
    }
    if (low[u] == dfn[u])
    {
        ++colcnt;
        col[u] = colcnt, gcd[colcnt] = S[u].size();
        while (stk.top() != u)
        {
            int v = stk.top();
            stk.pop();
            col[v] = colcnt, gcd[colcnt] = GCD(gcd[colcnt], S[v].size());
        }
        stk.pop();
    }
}

inline int C(int n, int m) // C _n ^m
{
    if (n < 0 or m < 0 or n < m)
        return 0;
    return (LL)fac[n] * Qpow(fac[m], -1) % mod * Qpow(fac[n - m], -1) % mod;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("wib.in", "r", stdin);
    freopen("wib.out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    cin >> n >> a >> b;
    for (int i = 1; i <= n; ++i)
    {
        cin >> S[1];
        for (int j = 1; j <= n; ++j)
            if (S[1][j - 1] == '1')
                G[i].push_back(j);
    }
    for (int i = 1; i <= n; ++i)
    {
        int sth; // something... whatever - -
        cin >> sth >> S[i];
    }
    for (int i = 1; i <= n; ++i)
        if (!dfn[i])
            Tarjan(i);
    for (int i = 1; i <= colcnt; ++i)
        F[i].resize(gcd[i]);
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < S[i].size(); ++j)
            if (S[i][j] == '1')
                ++minn[i], F[col[i]][j % gcd[col[i]]] = true;
    for (int i = colcnt; i > 1; --i)
    {
        int curr = GCD(gcd[i], gcd[i - 1]);
        tmp.clear(), tmp.resize(curr);
        for (int j = 0; j < gcd[i]; ++j)
            if (F[i][j])
                tmp[j % curr] = true;
        for (int j = 0; j < gcd[i - 1]; ++j)
            if (tmp[j % curr])
                F[i - 1][j] = true;
    }
    for (int i = 1; i <= colcnt; ++i)
        for (int j = 0; j < gcd[i]; ++j)
            cnt[i] += F[i][j];
    for (int i = 1; i <= n; ++i)
        maxx[i] = S[i].size() / gcd[col[i]] * cnt[col[i]];
    // for (int i = 1; i <= n; ++i)
        // cout << minn[i] << ' ' << maxx[i] << endl;
    // subtask1 end
    fac[0] = 1;
    for (int i = 1; i <= n; ++i)
        fac[i] = (LL)fac[i - 1] * i % mod;
    for (int i = 1; i <= n; ++i)
    {
        int cnt1 = 0, cnt2 = 0;
        for (int j = 1; j <= n; ++j)
        {
            if (i == j)
                continue;
            if (minn[j] > maxx[i])
                ++cnt1;
            else if (maxx[j] > maxx[i] or (maxx[j] == maxx[i] and j < i))
                ++cnt2;
        }
        if (cnt1 >= a)
            continue;
        for (int x = min(b, min(cnt2, a - 1 - cnt1)); x + cnt1 + 1 >= b and x >= 0; --x)
            Mod(ans += (LL)C(cnt1, b - x - 1) * C(cnt2, x) % mod);
    }
    cout << ans << endl;
    return 0;
}

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define RG register
#define N 5010
#define L 2000010
char B[1<<15],*S=B,*T=B;
#define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
inline int read()
{
	RG int x=0;RG char c=getc;
	while(c<'0'|c>'9')c=getc;
	while(c>='0'&c<='9')x=10*x+(c^48),c=getc;
	return x;
}
inline int get01()
{
	RG char c=getc;
	while(c<'0'|c>'1')c=getc;
	return c^48;
}
int n,a,b,ge[N],e,adj[N];
vector<int>mem[N],con[N],can[N];
struct edge{int zhong,next;}s[N*N>>1];
inline void add(int qi,int zhong)
	{s[++e].zhong=zhong;s[e].next=adj[qi];adj[qi]=e;}
int dfn[N],low[N],num,sta[N],top;
int sz[N],belong[N],tot;
inline int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
#define vi vector<int>::iterator
inline void tarjan(int rt)
{
	RG int i,u;
	dfn[rt]=low[rt]=++num;sta[++top]=rt;
	for(i=adj[rt];i;i=s[i].next)
		if(!dfn[u=s[i].zhong])tarjan(u),low[rt]=min(low[rt],low[u]);
		else if(!belong[u])low[rt]=min(low[rt],dfn[u]);
	if(dfn[rt]==low[rt])
	{
		++tot;
		do
		{
			belong[u=sta[top--]]=tot;
			sz[tot]=gcd(sz[tot],ge[u]);
			con[tot].push_back(u);
		}while(u!=rt);
		can[tot].resize(sz[tot]);
		for(vi it=con[tot].begin();it!=con[tot].end();++it)
			for(vi j=mem[*it].begin();j!=mem[*it].end();++j)
				can[tot][*j % sz[tot]]=1;
	}
}
int mn[N],mx[N],C[N][N];
#define mod 1000000007
#define LL long long
#define min(x,y) ((x)<(y)?(x):(y))
int main()
{
	// freopen("Ark.in","r",stdin);
	// return 0;
	RG int i,j,x,ans=0,cnt1,cnt2;
	n=read();a=read();b=read();

	for(i=1;i<=n;++i)
		for(j=1;j<=n;++j)
			if(get01())add(i,j);

	for(i=1;i<=n;++i)
		for(ge[i]=read(),j=0;j<ge[i];++j)
			if(get01())++mn[i],mem[i].push_back(j);

	for(i=1;i<=n;++i)if(!dfn[i])tarjan(i);

	for(i=tot;i>1;--i)
		for(sz[i-1]=gcd(sz[i],sz[i-1]),j=0;j<sz[i];++j)
			if(can[i][j])can[i-1][ j % sz[i-1] ]=1;

	for(i=1;i<=n;++i)
		for(x=belong[i],j=0;j<ge[i];++j)
			mx[i]+=can[x][j%sz[x]];

	for(C[0][0]=i=1;i<=n;++i)
		for(C[i][0]=j=1;j<=i;++j)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;

	for(i=1;i<=n;++i)
	{
		for(cnt1=0,j=1;j<=n;++j)if(mn[j]>mx[i])++cnt1;
		if(cnt1>=a)continue;
		for(cnt2=0,j=1;j<=n;++j)
			if(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)))++cnt2;
		for(j=min(b-1,min(cnt2,a-cnt1-1));j>=0;--j)
			ans=(ans+(LL)C[cnt2][j]*C[cnt1][b-1-j])%mod;
	}
	printf("%d\n",ans);
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
long long read() {
  long long x = 0, w = 1;
  char ch = getchar();
  while (!isdigit(ch)) w = ch == '-' ? -1 : 1, ch = getchar();
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * w;
}
const int Max_n = 5005, Max_S = 2e6 + 5, mod = 1e9 + 7;
int n, A, B, ans;
int S[Max_n], s1[Max_n], s2[Max_n];
int tim, top, dfn[Max_n], low[Max_n], stk[Max_n];
int cntc, vis[Max_n], Gcd[Max_n], bel[Max_n], du[Max_n];
int h, t, q[Max_n];
int jc[Max_n], inv[Max_n];
int cnt1, cnt2;
vector<bool> s[Max_n], cs[Max_n];
bool r[Max_n][Max_n], cr[Max_n][Max_n];
void Mod(int &x) { x %= mod; }
void Upd(int cnt, int x) {
  bel[x] = cnt, Gcd[cnt] = __gcd(Gcd[cnt], S[x]), vis[x] = -1;
}
void dfs(int x) {
  stk[++top] = x, vis[x] = 1, dfn[x] = low[x] = ++tim;
  for (int i = 1; i <= n; i++)
    if (r[x][i])
      if (!vis[i])
        dfs(i), low[x] = min(low[x], low[i]);
      else if (vis[i] == 1)
        low[x] = min(low[x], dfn[i]);
  if (dfn[x] == low[x]) {
    Gcd[++cntc] = S[stk[top]], bel[stk[top]] = cntc, vis[stk[top]] = -1;
    while (stk[top] != x) Upd(cntc, stk[--top]);
    Upd(cntc, stk[top--]);
  }
}
int ksm(int a, int b) {
  int base = 1;
  while (b) {
    if (b & 1) base = 1ll * base * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return base;
}
int C(int n, int m) {
  if (!n) return 1;
  return 1ll * jc[m] * inv[n] % mod * inv[m - n] % mod;
}
int main() {
  scanf("%d%d%d", &n, &A, &B);
  char P[Max_S];
  for (int i = 1; i <= n; i++) {
    scanf("%s", P + 1);
    for (int j = 1; j <= n; j++) r[i][j] = P[j] - '0';
  }
  for (int i = 1; i <= n; i++) {
    scanf("%d%s", &S[i], P);
    for (int j = 0; j < S[i]; j++)
      s[i].push_back(P[j] - '0'), s1[i] += P[j] - '0';
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i);
  for (int i = 1; i <= cntc; i++)
    for (int j = 0; j < Gcd[i]; j++) cs[i].push_back(0);
  for (int i = 1; i <= n; i++) {
    int x = bel[i];
    for (int j = s[i].size() - 1; ~j; j--)
      cs[x][j % Gcd[x]] = cs[x][j % Gcd[x]] | s[i][j];
    for (int j = 1; j <= n; j++)
      if (bel[j] != x) cr[x][bel[j]] |= r[i][j];
  }
  for (int i = 1; i <= cntc; i++)
    for (int j = 1; j <= cntc; j++) du[j] += cr[i][j];
  for (int i = 1; i <= cntc; i++)
    if (!du[i]) q[t = 1] = i;
  while (h < t) {
    int x = q[++h];
    for (int i = 1; i <= cntc; i++)
      if (cr[x][i]) {
        du[i]--;
        if (!du[i]) q[++t] = i;
      }
    if (h > 1) {
      int bef = q[h - 1];
      int gcd = __gcd(cs[x].size(), cs[bef].size());
      bool bk[gcd] = {0};
      for (int i = cs[bef].size() - 1; ~i; i--) bk[i % gcd] |= cs[bef][i];
      for (int i = cs[x].size() - 1; ~i; i--) cs[x][i] = cs[x][i] | bk[i % gcd];
    }
  }
  jc[0] = inv[0] = 1;
  for (int i = 1; i <= n; i++) {
    jc[i] = 1ll * jc[i - 1] * i % mod;
    inv[i] = ksm(jc[i], mod - 2);
  }
  for (int i = 1; i <= n; i++)
    for (int j = s[i].size() - 1; ~j; j--)
      s[i][j] = cs[bel[i]][j % Gcd[bel[i]]], s2[i] += s[i][j];
  for (int i = 1; i <= n; i++) {
    cnt1 = cnt2 = 0;
    for (int j = 1; j <= n; j++)
      if (i != j)
        if (s1[j] > s2[i])
          cnt1++;
        else if (s2[j] > s2[i] || (s2[j] == s2[i] && j > i))
          cnt2++;
    for (int j = 0; j <= min(B - 1, cnt2); j++)
      if (B - j - 1 <= cnt1 && cnt1 + j + 1 <= A)
        Mod(ans += 1ll * C(j, cnt2) * C(B - j - 1, cnt1) % mod);
  }
  cout << ans;
}

#include <bits/stdc++.h>
using namespace std;
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define MK make_pair
#define PB push_back
#define fi first
#define se second
#define RG register
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int N= 5e3 +10;
const LL MOD = 1e9+7;
vector<int> can[N], mem[N], con[N], g[N];

int ge[N], sz[N], dfn[N], n, m, mn[N], mx[N],low[N], dfs_clock=0, belong[N], tot=0;
LL C[N][N];
int gcd(int a, int b){ return b==0 ? a : gcd( b, a%b);}
int get01(){
	char c ; for (c=getchar(); c<'0' || c>'1'; c=getchar());
	return c^48;
}
stack<int> sk;
void dfs(int u){
	dfn[u] = low[u]= ++dfs_clock;
	sk.push(u);
	for (auto v: g[u])
		if ( !dfn[v]){dfs(v); low[u] = min(low[u], low[v]);}	else
		if( !belong[v])  low[u] = min(low[u] , dfn[v]);
	if ( dfn[u] == low[u]){
		RG int x;
		++tot; sz[tot] = 0;
		do{
			x= sk.top(); sk.pop();
			sz[tot] = gcd(sz[tot] , ge[x]); belong[x] = tot;
			con[tot].PB(x);
		}while ( x!=u);
		can[tot].resize(sz[tot]);
		for (auto i:con[tot]) for( auto j: mem[i])
			can[tot][j%sz[tot]]=1;
	}
}
int main(){
	#ifdef che
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
	#endif
	RG int i, j,n,a, b,x;
	scanf("%d%d%d", &n, &a, &b);
	for (i=1; i<=n; ++i)	for (j=1; j<=n; ++j)
		if ( get01()) g[i].PB(j);
	for (i=1; i<=n; ++i){
		scanf("%d", &ge[i]);
		for (j=0; j<ge[i]; ++j)	if( get01()) mem[i].PB(j);
		mn[i] = mem[i].size();
	}
	for (i=1; i<=n; ++i)if ( !dfn[i]) dfs(i);
//-------------------------------------
	for (i=tot; i>1; --i){
		for ( sz[i-1] = gcd(sz[i], sz[i-1]) , j=0; j<sz[i]; ++j)
			if ( can[i][j] ) can[i-1][j%sz[i-1]] = 1;
	}
	for (i=1; i<=n; ++i)
		for (x=belong[i], j=0; j<ge[i]; ++j)
			if ( can[x][ j%sz[x]]) ++mx[i];
	#ifdef che
	for (i=1; i<=n; ++i) debug("[%d]  mn[]= %d,  mx[] = %d\n", i, mn[i], mx[i]);
	#endif
//-------------------------------------
	for (i=0; i<=n; ++i){
		C[i][0] = 1;
		for (j=1; j<=i; ++j) C[i][j]= (C[i-1][j] + C[i-1][j-1])%MOD;
	}

	LL ans= 0, cnt1, cnt2;
	for (i=1; i<=n; ++i){
		cnt1=cnt2= 0;
		for (j=1; j<=n; ++j) if ( mn[j] > mx[i] ) ++cnt1;

		for (j=1; j<=n; ++j)
			if ( mn[j] <= mx[i] && (mx[j]>mx[i] || (mx[j]==mx[i] && j >i))) ++cnt2;

		for (j= min( 1ll*b-1, min(cnt2, a-1-cnt1)); j>=0; --j)
			 ans =(ans + C[cnt2][j] *C[cnt1][b-1-j])%MOD;
	}
	cout<<ans<<endl;
	return 0;
}

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cctype>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
#define ri register int
const int MOD=1000000007;
int n,a,b,s[5005],minjt[5005],maxjt[5005],cols[5005],coljt[5005],x,ss,cnt1,cnt2,ans;
int dfn[5005],low[5005],col[5005],now,colnum;
int fac[5005],inv[5005];
bool g1[5005][5005],bo[2000005];
char ch;
vector<bool> v[5005],colv[5005];
stack<int> sta;
inline void mo(int &x)
{
	if(x>=MOD)x-=MOD;
}
inline int gcd(int a,int b)
{
	while(b)
	{
		a%=b;
		swap(a,b);
	}
	return a;
}
inline int ksm(int b,int p)
{
	int a=1;
	while(p)
	{
		if(p&1)a=1ll*a*b%MOD;
		b=1ll*b*b%MOD;
		p=p>>1;
	}
	return a;
}
inline int C(int n,int m)
{
	return 1ll*fac[n]*inv[n-m]%MOD*inv[m]%MOD;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++now;
	sta.push(x);
	for(int i=1;i<=n;i++)
		if(g1[x][i])
		{
			if(!dfn[i])tarjan(i),low[x]=min(low[x],low[i]);
			else if(!col[i])low[x]=min(low[x],dfn[i]);
		}
	if(low[x]==dfn[x])
	{
		col[x]=++colnum;
		while(sta.top()!=x)col[sta.top()]=colnum,sta.pop();
		sta.pop();
	}
}
int main()
{
	scanf("%d%d%d",&n,&a,&b);
	fac[0]=1;
	for(ri i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%MOD;
	inv[n]=ksm(fac[n],MOD-2);
	for(ri i=n;i;i--)inv[i-1]=1ll*inv[i]*i%MOD;
	for(ri i=1;i<=n;i++)
		for(ri j=1;j<=n;j++)
		{
			ch=getchar();
			while(!isdigit(ch))ch=getchar();
			g1[i][j]=ch=='1';
		}
	for(ri i=1;i<=n;i++)
	{
		scanf("%d",s+i);
		v[i].resize(s[i]);
		for(ri j=0;j<s[i];j++)
		{
			ch=getchar();
			while(!isdigit(ch))ch=getchar();
			if(ch=='1')minjt[i]++;
			v[i][j]=ch=='1';
		}
	}
	for(ri i=1;i<=n;i++)
		if(!dfn[i])tarjan(i);
	for(ri i=1;i<=n;i++)cols[col[i]]=gcd(s[i],cols[col[i]]);
	for(ri i=1;i<=colnum;i++)colv[i].resize(cols[i]),fill(colv[i].begin(),colv[i].end(),0);
	for(ri i=1;i<=n;i++)
		for(ri j=0;j<s[i];j++)
			if(v[i][j])colv[col[i]][j%cols[col[i]]]=1;
	for(ri i=colnum;i>1;i--)
	{
		x=gcd(cols[i],cols[i-1]);
		memset(bo,0,x);
		for(ri j=0;j<cols[i];j++)
			if(colv[i][j])bo[j%x]=1;
		for(ri j=0;j<cols[i-1];j++)
			if(bo[j%x])colv[i-1][j]=1;
	}
	for(ri i=1;i<=colnum;i++)
		for(ri j=0;j<cols[i];j++)
			if(colv[i][j])coljt[i]++;
	for(ri i=1;i<=n;i++)maxjt[i]=1ll*coljt[col[i]]*s[i]/cols[col[i]];
	for(ri i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(ri j=1;j<=n;j++)
		{
			if(minjt[j]>maxjt[i])cnt1++;
			else if(maxjt[j]>maxjt[i]||j<i&&maxjt[j]==maxjt[i])cnt2++;
		}
		for(ri j=max(b-1-cnt1,0);j<b&&j<=cnt2&&j<a-cnt1;j++)ans+=1ll*C(cnt2,j)*C(cnt1,b-1-j)%MOD,mo(ans);
	}
	printf("%d",ans);
}

#include<bits/stdc++.h>
inline int read(){
	int x=0,w=1;
	char ch=0;
	while (ch<'0' || ch>'9'){
		ch=getchar();
		if (ch=='-') w=-1;
	}
	while (ch<='9' && ch>='0'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*w;
}
using namespace std;
typedef long long ll;
const int N=5005;
const int M=2e6+5;
const int Mod=1e9+7;
char str[M];
int n,k1,k2,tot,tim,ans;
int s[N],bg[N],vis[N];
int dfn[N],low[N],b[N];
int mn[N],mx[N],cnt[N];
int fac[M],inv[M];
inline void ad(int &x,int y){
	x+=y;
	if (x>=Mod) x-=Mod;
	if (x<0) x+=Mod;
}
inline int Pow(int x,int y){
	int res=1;
	while (y){
		if (y&1) res=1ll*res*x%Mod;
		x=1ll*x*x%Mod;
		y>>=1;
	}
	return res;
}
inline void math_init(int nn){
	fac[0]=1;
	for (int i=1;i<=nn;++i)
		fac[i]=1ll*fac[i-1]*i%Mod;
	inv[nn]=Pow(fac[nn],Mod-2);
	for (int i=nn;i;--i)
		inv[i-1]=1ll*inv[i]*i%Mod;
}
inline int C(int x,int y){
	if (x<y || x<0 || y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%Mod)*inv[x-y]%Mod;
}
vector<int>G[N],g[N],f[N];
stack<int>sta;
int gcd(int x,int y){
	if (!y) return x;
	return gcd(y,x%y);
}
inline void input(){
	n=read(),k1=read(),k2=read();
	for (int i=1;i<=n;++i){
		scanf("%s",str+1);
		for (int j=1;j<=n;++j)
			if (str[j]=='1') G[i].push_back(j);
	}
	for (int i=1;i<=n;++i){
		s[i]=read();
		scanf("%s",str+1);
		for (int j=1;j<=s[i];++j){
			g[i].push_back(str[j]-'0');
			mn[i]+=str[j]-'0';
		}
	}
}
void tarjan(int x){
	dfn[x]=low[x]=++tim;
	sta.push(x),vis[x]=1;
	for (int i=0,sz=G[x].size();i<sz;++i){
		int y=G[x][i];
		if (!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}else if (vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if (low[x]==dfn[x]){
		int now=0;++tot;
		do{
			now=sta.top(),sta.pop(),vis[now]=0;
			b[now]=tot,bg[tot]=gcd(bg[tot],s[now]);
		}while (now!=x);
	}
}
namespace sub1{
	inline void build(){
		for (int i=1;i<=n;++i)
			if (!dfn[i]) tarjan(i);
		for (int i=1;i<=tot;++i)
			f[i].resize(bg[i]+1);
		for (int i=1;i<=n;++i)
			for (int j=0;j<s[i];++j)
				f[b[i]][j%bg[b[i]]]|=g[i][j];
	}
	inline void solve(){
		build();
		for (int i=tot;i>1;--i){
			int now=gcd(bg[i],bg[i-1]);
			for (int j=0;j<bg[i];++j){
				f[i-1][j%now]|=f[i][j];
				cnt[i]+=f[i][j];
			}
		}
		for (int i=0;i<bg[1];++i) cnt[1]+=f[1][i];
		for (int i=1;i<=n;++i)
			mx[i]=1ll*cnt[b[i]]*s[i]/bg[b[i]];
	}
}
namespace sub2{
	inline void solve(){
		for (int i=1;i<=n;++i){
			int cnt1=0,cnt2=0;
			for (int j=1;j<=n;++j){
				if (i==j) continue;
				if (mn[j]>mx[i]) ++cnt1;
				else if (mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) ++cnt2;
			}
			if (cnt1>k1-1) continue;
			for (int j=min(k2,min(k1-1-cnt1,cnt2));j+cnt1+1>=k2;--j)
				ad(ans,1ll*C(cnt2,j)*C(cnt1,k2-j-1)%Mod);
		}
		printf("%d\n",ans);
	}
}
int main(){
//	freopen("fake.in","r",stdin);
//	freopen("fake.out","w",stdout);
	math_init(M-5),input();
	sub1::solve(),sub2::solve();
	return 0;
}

#include<iostream>
#include<cstdio>
#include<vector>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=5050,M=2000200,P=1e9+7;
int n,m,u,v,ti,tp,D,A,B,X,Y,ans;
int df[N],lo[N],s[N],l[N],in[N],c[N],d[N],a[N];
int f[N][N],g[N][N],mi[N],mx[N],su[N],iv[N],fc[N],vf[N];
char S[M];
bool T[M];
vector<bool>b[N],t[N];
vector<int>ve[N];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int C(int x,int y){return x<0||y<0||x<y?0:1ll*fc[x]*vf[x-y]%P*vf[y]%P;}
void tarjan(int u){
	df[u]=lo[u]=++ti;in[s[++tp]=u]=1;
	FOR(v,1,n)if(g[u][v]){
		if(!df[v]) tarjan(v);
		if( in[v]) lo[u]=min(lo[u],lo[v]);
	}
	if(df[u]==lo[u]){
		++m;
		for(int x=0,v;v=s[tp],x!=u;x=s[tp--])
			c[v]=m,in[v]=0,d[m]=gcd(d[m],l[v]),ve[m].push_back(v);
		FOR(i,1,d[m]) t[m].push_back(0);
		for(int v:ve[m])FOR(i,0,l[v]-1) t[m][i%d[m]]=t[m][i%d[m]]|b[v][i];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&A,&B);
	iv[1]=fc[0]=vf[0]=1;
	FOR(i,2,n) iv[i]=1ll*iv[P%i]*(P-P/i)%P;
	FOR(i,1,n) fc[i]=1ll*fc[i-1]*i%P,vf[i]=1ll*vf[i-1]*iv[i]%P;
	FOR(i,1,n){
		scanf("%s",S+1);
		FOR(j,1,n) g[i][j]=S[j]=='1';
	}
	FOR(i,1,n){
		scanf("%d%s",&l[i],S+1);
		FOR(j,1,l[i]) b[i].push_back(S[j]^48),mi[i]+=S[j]^48;
	}
	FOR(i,1,n)if(!df[i]) tarjan(i);
	ROF(i,m,2){
		u=i,v=i-1;D=gcd(d[u],d[v]);
		FOR(j,0,D-1) T[j]=0;
		FOR(j,0,d[u]-1) T[j%D]|=t[u][j];
		FOR(j,0,d[v]-1) t[v][j]=t[v][j]|T[j%D];
	}
	FOR(i,1,m)for(int x:t[i]) su[i]+=x;
	FOR(i,1,n) mx[i]=l[i]/d[c[i]]*su[c[i]];
	FOR(i,1,n){
		X=Y=0;
		FOR(j,1,n)if(i!=j){
			if(mi[j]>mx[i]) X++;
			else if(mx[i]<mx[j] || (mx[i]==mx[j] && i>j)) Y++;
		}
		if(X>=A) continue;
		FOR(j,0,min(A-X-1,Y)) (ans+=1ll*C(Y,j)*C(X,B-1-j)%P)%=P;
	}
	cout<<ans<<'\n';
}

#include<bits/stdc++.h>
inline int read(){
    int x=0,w=1;
    char ch=0;
    while (ch<'0' || ch>'9'){
        ch=getchar();
        if (ch=='-') w=-1;
    }
    while (ch<='9' && ch>='0'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    return x*w;
}
using namespace std;
typedef long long ll;
const int N=5005;
const int M=2e6+5;
const int Mod=1e9+7;
char str[M];
int n,k1,k2,tot,tim,ans;
int s[N],bg[N],vis[N];
int dfn[N],low[N],b[N];
int mn[N],mx[N],cnt[N];
int fac[M],inv[M];
inline void ad(int &x,int y){
    x+=y;
    if (x>=Mod) x-=Mod;
    if (x<0) x+=Mod;
}
inline int Pow(int x,int y){
    int res=1;
    while (y){
        if (y&1) res=1ll*res*x%Mod;
        x=1ll*x*x%Mod;
        y>>=1;
    }
    return res;
}
inline void math_init(int nn){
    fac[0]=1;
    for (int i=1;i<=nn;++i)
        fac[i]=1ll*fac[i-1]*i%Mod;
    inv[nn]=Pow(fac[nn],Mod-2);
    for (int i=nn;i;--i)
        inv[i-1]=1ll*inv[i]*i%Mod;
}
inline int C(int x,int y){
    if (x<y || x<0 || y<0) return 0;
    return 1ll*(1ll*fac[x]*inv[y]%Mod)*inv[x-y]%Mod;
}
vector<int>G[N],g[N],f[N];
stack<int>sta;
int gcd(int x,int y){
    if (!y) return x;
    return gcd(y,x%y);
}
inline void input(){
    n=read(),k1=read(),k2=read();
    for (int i=1;i<=n;++i){
        scanf("%s",str+1);
        for (int j=1;j<=n;++j)
            if (str[j]=='1') G[i].push_back(j);
    }
    for (int i=1;i<=n;++i){
        s[i]=read();
        scanf("%s",str+1);
        for (int j=1;j<=s[i];++j){
            g[i].push_back(str[j]-'0');
            mn[i]+=str[j]-'0';
        }
    }
}
void tarjan(int x){
    dfn[x]=low[x]=++tim;
    sta.push(x),vis[x]=1;
    for (int i=0,sz=G[x].size();i<sz;++i){
        int y=G[x][i];
        if (!dfn[y]){
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }else if (vis[y]) low[x]=min(low[x],dfn[y]);
    }
    if (low[x]==dfn[x]){
        int now=0;++tot;
        do{
            now=sta.top(),sta.pop(),vis[now]=0;
            b[now]=tot,bg[tot]=gcd(bg[tot],s[now]);
        }while (now!=x);
    }
}
namespace sub1{
    inline void build(){
        for (int i=1;i<=n;++i)
            if (!dfn[i]) tarjan(i);
        for (int i=1;i<=tot;++i)
            f[i].resize(bg[i]+1);
        for (int i=1;i<=n;++i)
            for (int j=0;j<s[i];++j)
                f[b[i]][j%bg[b[i]]]|=g[i][j];
    }
    inline void solve(){
        build();
        for (int i=tot;i>1;--i){
            int now=gcd(bg[i],bg[i-1]);
            for (int j=0;j<bg[i];++j){
                f[i-1][j%now]|=f[i][j];
                cnt[i]+=f[i][j];
            }
        }
        for (int i=0;i<bg[1];++i) cnt[1]+=f[1][i];
        for (int i=1;i<=n;++i)
            mx[i]=1ll*cnt[b[i]]*s[i]/bg[b[i]];
    }
}
namespace sub2{
    inline void solve(){
        for (int i=1;i<=n;++i){
            int cnt1=0,cnt2=0;
            for (int j=1;j<=n;++j){
                if (i==j) continue;
                if (mn[j]>mx[i]) ++cnt1;
                else if (mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) ++cnt2;
            }
            if (cnt1>k1-1) continue;
            for (int j=min(k2,min(k1-1-cnt1,cnt2));j+cnt1+1>=k2;--j)
                ad(ans,1ll*C(cnt2,j)*C(cnt1,k2-j-1)%Mod);
        }
        printf("%d\n",ans);
    }
}
int main(){
    math_init(M-5),input();
    sub1::solve(),sub2::solve();
    return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read()
{
    int s=0,k=1;
    char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges
{
    int v;
    edges *last;
} edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v)
{
    *ecnt=(edges) {v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b)
{
    int ret=1;
    while (b)
    {
        if(b&1) ret=(ll)ret*a%mod;
        a=(ll)a*a%mod;
        b>>=1;
    }
    return ret;
}

inline int gcd(int x,int y)
{
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],
s[N],n,a,b,instk[N];

inline void tarjan(int x)
{
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    for (edges *i=head[x]; i; i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x])
    {
        bcc_cnt++;
        int t;
        do instk[t=stk[top--]]=false,
            bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);
        while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

int  main()
{
    //freopen("1.in","r",stdin);
    //freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1; i<=n; ++i)
    {
        scanf("%s",me+1);
        for (int j=1; j<=n; ++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1; i<=n; ++i)
    {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    for (int i=1; i<=n; ++i)  if(!dfn[i])
            tarjan(i);
    bgcd[0]=s[n];
    for (int i=1; i<=bcc_cnt; ++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0; i<fr[n+1]; ++i)
        gold[i]^=48;
    for (int i=1; i<=n; ++i)
    {
        for (edges *j=head[i]; j; j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i]; j<fr[i+1]; ++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt; i>1; --i)
    {
        now[i-1]=gcd(bgcd[i],bgcd[i-1]);
        for (int j=0; j<bgcd[i]; ++j)
            if(gold[fr[i+n]+j])
                ++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
    }
    for (int j=0; j<bgcd[1]; ++j)
        if(gold[fr[1+n]+j])
            ++num[1];
    for (int i=1; i<=n; ++i)
    {
        mx[i]=(ll)num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i]; j<fr[i+1]; ++j)
            mn[i]+=gold[j];
    }
    fac[0]=1;
    for (int i=1; i<=n; ++i) fac[i]=(ll)fac[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2; i<=n; ++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2; i<=n; ++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1; i<=n; ++i)
    {
        int c1=0,c2=0;
        for (int j=1; j<=n; ++j)
            if (mn[j]>mx[i]) ++c1;
        if (c1>=a)
            continue;
        for (int j=1; j<=n; ++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)))
                ++c2;
        for (int j=min(b-1,min(c2,a-1-c1)); b-j-1<=c1&&j>=0; --j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#pragma GCC optimze(3)
#include <bits/stdc++.h>
const int MAXN = 10010;
const int MAXL = 2000010;
const int Mod = 1000000007;
using namespace std;
int n,a,b,c;
char str[MAXL];
vector<int> G[MAXN];
vector<int> per[MAXN];
int siz[MAXN],dfn[MAXN],low[MAXN],dcnt,blo[MAXN],bgcd[MAXN],blocnt;
int stk[MAXN],t,num[MAXN],mx[MAXN],mn[MAXN],fact[MAXN],inv[MAXN];
bool instk[MAXN];
int PowMod(int x,int y){
    int ret=1;
    while(y){
        if(y&1) ret=1LL*ret*x%Mod;
        x=1LL*x*x%Mod,y>>=1;
    }return ret;
}
inline int gcd(int x,int y){
    return y==0?x:gcd(y,x%y);
}
inline void InPut(){
    scanf("%d %d %d",&n,&a,&b);
    for(int i=1;i<=n;i++){
        scanf("%s",str+1);
        for(int j=1;j<=n;j++)
            if(str[j]=='1') G[i].push_back(j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&siz[i]);
        per[i].resize(siz[i]+1);
        scanf("%s",str);
        for(int j=0;j<siz[i];j++)
            if(str[j]=='1') per[i][j]=1;
            else if(str[j]=='0') per[i][j]=0;
    }
}
inline void Tarjan(int u,int fa){
    dfn[u]=low[u]=++dcnt,instk[u]=true,stk[t++]=u;
    for(int i=0;i<(int)G[u].size();i++){
        int v=G[u][i];
        if(dfn[v]==0){
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }else if(instk[v]==true) low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        int fro=0;blocnt++;
        do{
            fro=stk[--t];instk[fro]=false;
            blo[fro]=blocnt;
            bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
        }while(fro!=u);
    }
}
inline void Part1(){
    for(int i=1;i<=n;i++)
        if(dfn[i]==0) Tarjan(i,-1);
    for(int i=1;i<=blocnt;i++)
        per[i+n].resize(bgcd[i]+1);
    for(int i=1;i<=n;i++)
        for(int j=0;j<siz[i];j++)
            per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];
    for(int i=blocnt;i>1;i--){
        int now=gcd(bgcd[i],bgcd[i-1]);
        for(int j=0;j<bgcd[i];j++)
            if(per[i+n][j]) per[i-1+n][j%now]|=1,num[i]++;
    }
    for(int j=0;j<bgcd[1];j++) num[1]+=per[1+n][j];
    for(int i=1;i<=n;i++){
        mx[i]=mn[i]=0;
        mx[i]=1LL*num[blo[i]]*siz[i]/bgcd[blo[i]];
        for(int j=0;j<siz[i];j++) mn[i]+=per[i][j];
    }
}
inline void Prepare(){
    fact[0]=1;
    for(int i=1;i<MAXN;i++) fact[i]=1LL*fact[i-1]*i%Mod;
    inv[MAXN-1]=PowMod(fact[MAXN-1],Mod-2);
    for(int i=MAXN-2;i>=0;i--) inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%Mod;
}
inline int C(int x,int y){
    return 1LL*fact[x]*inv[y]%Mod*inv[x-y]%Mod;
}
inline int Part2(){
    Prepare();
    int cnt1=0,cnt2=0,ret=0;
    for(int i=1;i<=n;i++){
        cnt1=cnt2=0;
        for(int j=1;j<=n;j++){
            if(i!=j && mn[j]>mx[i]) cnt1++;
            if(i!=j && mn[j]<=mx[i] && (mx[j]>mx[i] || (mx[j]==mx[i] && j<i))) cnt2++;
        }
        if(cnt1>a-1) continue;
        for(int j=min(b,min(a-1-cnt1,cnt2));j>=0 && j+1+cnt1>=b;j--)
            ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%Mod)%Mod;
    }
    return ret;
}
int main(){
    InPut();
    Part1();
    printf("%d\n",Part2());
    return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=5005;
const int M=2000005;
const int mo=1000000007;
bool e[N][N];
int dfn[N],low[N],vis[N];
int n,A,B,tot,fac[N],inv[N];
int l[N],G[N],be[N],stk[N];
int lo[N],hi[N],ans;
vector<int> v[N],ok[N];
char s[M];
void init(){
	fac[0]=inv[0]=inv[1]=1;
	For(i,2,N-1) inv[i]=1ll*inv[mo%i]*(mo-mo/i)%mo;
	For(i,1,N-1) inv[i]=1ll*inv[i-1]*inv[i]%mo;
	For(i,1,N-1) fac[i]=1ll*fac[i-1]*i%mo;
}
int C(int x,int y){
	if (x<0||y<0||y>x) return 0;
	return 1ll*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
void tarjan(int x){
	dfn[x]=low[x]=++*dfn;
	vis[x]=1; stk[++*stk]=x;
	For(i,1,n)
		if (i!=x&&e[x][i]){
			if (!dfn[i]){
				tarjan(i);
				low[x]=min(low[x],low[i]);
			}
			else if (vis[i])
				low[x]=min(low[x],dfn[i]);
		}
	if (low[x]==dfn[x]){
		++tot;
		int y=19260817;
		for (;y!=x;){
			y=stk[(*stk)--];
			vis[y]=0; be[y]=tot;
		}
	}
}
int gcd(int x,int y){
	return y?gcd(y,x%y):x;
}
int main(){
	scanf("%d%d%d",&n,&A,&B);
	For(i,1,n){
		scanf("%s",s+1);
		For(j,1,n) e[i][j]+=(s[j]=='1');
	}
	For(i,1,n){
		scanf("%d%s",&l[i],s+1);
		For(j,1,l[i]) v[i].PB(s[j]=='1');
	}
	For(i,1,n)
		if (!dfn[i])
			tarjan(i);
	For(i,1,n) G[be[i]]=gcd(G[be[i]],l[i]);
	//For(i,1,n) cout<<be[i]<<endl;
	For(i,1,tot) ok[i].resize(G[i]);
	For(i,1,n) For(j,0,l[i]-1)
		ok[be[i]][j%G[be[i]]]|=v[i][j];
	//Rep(i,tot,1) cout<<G[i]<<endl;
	Rep(i,tot,2){
		static int OK[M];
		int l=gcd(G[i],G[i-1]);
		For(j,0,l-1) OK[j]=0;
		For(j,0,G[i]-1) OK[j%l]|=ok[i][j];
		For(j,0,G[i-1]-1) ok[i-1][j]|=OK[j%l];
	}
	For(i,1,n){
		For(j,0,l[i]-1) lo[i]+=v[i][j];
		For(j,0,l[i]-1) hi[i]+=ok[be[i]][j%G[be[i]]];
		//cout<<lo[i]<<' '<<hi[i]<<endl;
	}
	init();
	For(i,1,n) For(j,i+1,n)
		if (hi[i]<hi[j]){
			swap(lo[i],lo[j]);
			swap(hi[i],hi[j]);
		}
	For(i,1,n){
		int s1=0;
		For(j,1,i-1) if (lo[j]>hi[i]) ++s1;
		For(j,0,s1) if (B>j&&s1-j<=A-B)
			ans=(ans+1ll*C(s1,j)*C(i-s1-1,B-j-1))%mo;
	}
	printf("%d\n",ans);
}
/*
枚举hi最小的元素。
统计在他之前有多少个lo比它大的元素
*/

//   Author:Arturia
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<ctime>
#include<cstdlib>
#include<string>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];~x;x=nx[x])
#define ll long long
#define inf (1<<29)
#define pii pair<int,int>
#define pdd pair<double,double>
#define mk(a,b) make_pair(a,b)
#define fs first
#define sc second
#define pb push_back
#define VI vector<int>
#define VS vector<string>
using namespace std;
inline ll rd(){
	ll x=0;int ch=getchar(),f=1;
	while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
	if (ch=='-'){f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
inline void rt(ll x){
	if (x<0) putchar('-'),x=-x;
	if (x>=10) rt(x/10),putchar(x%10+'0');
		else putchar(x+'0');
}
const int maxn=5005,maxs=2000005,p=1000000007;
char mp[maxn][maxn],ch[maxs];
int n,vb[maxs],*b[maxn],vc[maxs],*c[maxn];
int sb[maxn],sc[maxn];
int gcd(int a,int b){return !b?a:gcd(b,a%b);}

namespace Graph{
	int dfn[maxn],low[maxn],tim;
	int ins[maxn],stk[maxn],top;
	int lst[maxn],lc,ks;
	int blt[maxn],topo[maxn];
	void dfs(int u){
	//	printf("u=%d\n",u);
		dfn[u]=low[u]=++tim;stk[++top]=u,ins[u]=1;
		rep(v,1,n){
			if (mp[u][v]=='0') continue;
			if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
			else if (ins[v]) low[u]=min(low[u],dfn[v]);
		}
		if (low[u]==dfn[u]){
			++ks;lc=0;
			int g=0;
			while (stk[top+1]!=u){
				int t=stk[top];
				lst[++lc]=t,blt[t]=ks,ins[t]=0,top--;
				g=gcd(g,sb[t]);
			}
			c[ks]=c[ks-1]+sc[ks-1];
			sc[ks]=g;
			for (int _=1,i=lst[_];_<=lc;_++,i=lst[_])
				rep(j,0,sb[i]-1) c[ks][j%g]|=b[i][j];
		}
	}
	int tmp[maxs];
	void walk(){
		drp(i,ks-1,1){
			int g=gcd(sc[i],sc[i+1]);
			rep(j,0,g-1) tmp[j]=0;
			rep(j,0,sc[i+1]-1) tmp[j%g]|=c[i+1][j];
			rep(j,0,sc[i]-1) c[i][j]|=tmp[j%g];
		}
		rep(i,1,n){
			int x=blt[i];
			rep(j,0,sb[i]-1) b[i][j]|=c[x][j%sc[x]];
		}
	}
}
using namespace Graph;
int mn[maxn],mx[maxn];
int fac[maxn],inv[maxn],cnt;
int qpow(int a,int b){
	int ret=1;
	for (;b;b>>=1,a=(ll)a*a%p) if (b&1) ret=(ll)ret*a%p;
	return ret;
}
int prepare(){
	fac[0]=1;rep(i,1,n) fac[i]=(ll)fac[i-1]*i%p;
	inv[n]=qpow(fac[n],p-2);
	drp(i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%p;
}
int A,B;
bool cmp(const int &a,const int &b){return a>b;}
int C(int n,int m){return (ll)fac[n]*inv[m]%p*inv[n-m]%p;}
int main(){
	n=rd(),A=rd(),B=rd();
	rep(i,1,n) scanf("%s",mp[i]+1);
	b[0]=vb;c[0]=vc;
	rep(i,1,n){
		sb[i]=rd();
		scanf("%s",ch);
		b[i]=b[i-1]+sb[i-1];
		rep(j,0,sb[i]-1) b[i][j]=ch[j]-'0',mn[i]+=b[i][j];
	}
	rep(i,1,n) if (!dfn[i]) dfs(i);
	walk();
	rep(i,1,n) rep(j,0,sb[i]-1) mx[i]+=b[i][j];
	prepare();
	int ans=0;
	rep(i,1,n){
		int must=0,might=0;
		rep(j,1,n){
			if (mn[j]>mx[i]) must++;
			else if (mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)) might++;
		}
		for (int j=max(0,B-must-1);j+must+1<=A&&j<=min(might,B-1);j++)
			ans=((ll)C(might,j)*C(must,B-j-1)+ans)%p;
	}
	rt(ans),putchar('\n');
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[M+5],inv[M+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<M;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<M;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<M;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[M];
char truegold[M];
int gold[M];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    sum1[n+1]=sum1[n]+sz[n];
    for(int i=0;i<sum1[n+1];i++)
        truegold[i]-='0';
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=scnt;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        //for(int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&j>=0;j--){
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<ctime>
#include<cstdlib>
#include<string>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];~x;x=nx[x])
#define ll long long
#define inf (1<<29)
#define pii pair<int,int>
#define pdd pair<double,double>
#define mk(a,b) make_pair(a,b)
#define fs first
#define sc second
#define pb push_back
#define VI vector<int>
#define VS vector<string>
using namespace std;
inline ll rd(){
	ll x=0;int ch=getchar(),f=1;
	while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
	if (ch=='-'){f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
inline void rt(ll x){
	if (x<0) putchar('-'),x=-x;
	if (x>=10) rt(x/10),putchar(x%10+'0');
		else putchar(x+'0');
}
const int maxn=5005,maxs=2000005,p=1000000007;
char mp[maxn][maxn],ch[maxs];
int n,vb[maxs],*b[maxn],vc[maxs],*c[maxn];
int sb[maxn],sc[maxn];
int gcd(int a,int b){return !b?a:gcd(b,a%b);}

namespace Graph{
	int dfn[maxn],low[maxn],tim;
	int ins[maxn],stk[maxn],top;
	int lst[maxn],lc,ks;
	int blt[maxn],topo[maxn];
	void dfs(int u){
	//	printf("u=%d\n",u);
		dfn[u]=low[u]=++tim;stk[++top]=u,ins[u]=1;
		rep(v,1,n){
			if (mp[u][v]=='0') continue;
			if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
			else if (ins[v]) low[u]=min(low[u],dfn[v]);
		}
		if (low[u]==dfn[u]){
			++ks;lc=0;
			int g=0;
			while (stk[top+1]!=u){
				int t=stk[top];
				lst[++lc]=t,blt[t]=ks,ins[t]=0,top--;
				g=gcd(g,sb[t]);
			}
			c[ks]=c[ks-1]+sc[ks-1];
			sc[ks]=g;
			for (int _=1,i=lst[_];_<=lc;_++,i=lst[_])
				rep(j,0,sb[i]-1) c[ks][j%g]|=b[i][j];
		}
	}
	int tmp[maxs];
	void walk(){
		drp(i,ks-1,1){
			int g=gcd(sc[i],sc[i+1]);
			rep(j,0,g-1) tmp[j]=0;
			rep(j,0,sc[i+1]-1) tmp[j%g]|=c[i+1][j];
			rep(j,0,sc[i]-1) c[i][j]|=tmp[j%g];
		}
		rep(i,1,n){
			int x=blt[i];
			rep(j,0,sb[i]-1) b[i][j]|=c[x][j%sc[x]];
		}
	}
}
using namespace Graph;
int mn[maxn],mx[maxn];
int fac[maxn],inv[maxn],cnt;
int qpow(int a,int b){
	int ret=1;
	for (;b;b>>=1,a=(ll)a*a%p) if (b&1) ret=(ll)ret*a%p;
	return ret;
}
int prepare(){
	fac[0]=1;rep(i,1,n) fac[i]=(ll)fac[i-1]*i%p;
	inv[n]=qpow(fac[n],p-2);
	drp(i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%p;
}
int A,B;
bool cmp(const int &a,const int &b){return a>b;}
int C(int n,int m){return (ll)fac[n]*inv[m]%p*inv[n-m]%p;}
int main(){
	n=rd(),A=rd(),B=rd();
	rep(i,1,n) scanf("%s",mp[i]+1);
	b[0]=vb;c[0]=vc;
	rep(i,1,n){
		sb[i]=rd();
		scanf("%s",ch);
		b[i]=b[i-1]+sb[i-1];
		rep(j,0,sb[i]-1) b[i][j]=ch[j]-'0',mn[i]+=b[i][j];
	}
	rep(i,1,n) if (!dfn[i]) dfs(i);
	walk();
	rep(i,1,n) rep(j,0,sb[i]-1) mx[i]+=b[i][j];
	prepare();
	int ans=0;
	rep(i,1,n){
		int must=0,might=0;
		rep(j,1,n){
			if (mn[j]>mx[i]) must++;
			else if (mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)) might++;
		}
		for (int j=max(0,B-must-1);j+must+1<=A&&j<=min(might,B-1);j++)
			ans=((ll)C(might,j)*C(must,B-j-1)+ans)%p;
	}
	rt(ans),putchar('\n');
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n,a,b,c;
char str[MAXL+5];
vector<int> G[MAXN+5];
vector<int> per[MAXN+5];
int siz[MAXN+5],dfn[MAXN+5],low[MAXN+5],dcnt;
int blo[MAXN+5],bgcd[MAXN+5],blocnt;
int stk[MAXN+5],t;
int num[MAXN+5],mx[MAXN+5],mn[MAXN+5];
bool instk[MAXN+5];
int fact[MAXN+5],inv[MAXN+5];
int PowMod(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret=1LL*ret*x%MO;
		x=1LL*x*x%MO;
		y>>=1;
	}
	return ret;
}
int gcd(int x,int y)
{
	if(y==0)
		return x;
	return gcd(y,x%y);
}
void InPut()
{
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				G[i].push_back(j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		per[i].resize(siz[i]+1);
		scanf("%s",str);
		for(int j=0;j<siz[i];j++)
			if(str[j]=='1')
				per[i][j]=1;
			else if(str[j]=='0')
				per[i][j]=0;
	}
}
void Tarjan(int u,int fa)
{
	dfn[u]=low[u]=++dcnt;
	instk[u]=true;stk[t++]=u;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(dfn[v]==0)
		{
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]==true)
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int fro=0;blocnt++;
		do
		{
			fro=stk[--t];instk[fro]=false;
			blo[fro]=blocnt;
			bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
		}while(fro!=u);
	}
}
void Part1()
{
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			Tarjan(i,-1);
	for(int i=1;i<=blocnt;i++)
		per[i+n].resize(bgcd[i]+1);//预先设定大小
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];//存到虚拟黑帮中
	int nw;
	for(int i=blocnt;i>1;i--)//自然形成了哈密顿路径
	{
		nw=gcd(bgcd[i],bgcd[i-1]);//当前的剩余系
		for(int j=0;j<bgcd[i];j++)
			if(per[i+n][j])
			{
				per[i-1+n][j%nw]|=1;//对下一个点进行更新
				num[i]++;//num就是总的金条数
			}
	}
	for(int j=0;j<bgcd[1];j++)
		num[1]+=per[1+n][j];//记得一定要统计block1的值
	for(int i=1;i<=n;i++)
	{
		mx[i]=mn[i]=0;
		mx[i]=1LL*num[blo[i]]*siz[i]/bgcd[blo[i]];//根据性质三进行还原
		for(int j=0;j<siz[i];j++)
			mn[i]+=per[i][j];//直接利用初始信息算
	}
}
void Prepare()
{
	fact[0]=1;
	for(int i=1;i<=MAXN;i++)
		fact[i]=1LL*fact[i-1]*i%MO;
	inv[MAXN]=PowMod(fact[MAXN],MO-2);
	for(int i=MAXN-1;i>=0;i--)
		inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%MO;
}
inline int C(int x,int y)
{
	return 1LL*fact[x]*inv[y]%MO*inv[x-y]%MO;
}
int Part2()
{
	Prepare();
	int cnt1=0,cnt2=0,ret=0;
	for(int i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i!=j&&mn[j]>mx[i])
				cnt1++;
			if(i!=j&&mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)))//避免重复
				cnt2++;
		}
		if(cnt1>a-1)
			continue;
		for(int j=min(b,min(a-1-cnt1,cnt2));j>=0&&j+1+cnt1>=b;j--)//一堆限制
			ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%MO)%MO;
	}
	return ret;
}
int main()
{
	InPut();
	Part1();
	int ans=Part2();
	printf("%d\n",ans);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
#include <vector>
#define LL long long
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], fac[maxn], ifac[maxn];
void input() {
    char str[(int)(2e6) + 2];
    scanf("%d %d %d", &n, &A, &B);
    for (int i = 1; i <= n; ++i) {
        scanf("%s", str + 1);
        for (int j = 1; j <= n; ++j)
            if (str[j] == '1')
                g[i].push_back(j);
    }
    for (int i = 1; i <= n; ++i) {
        scanf("%d %s", &s[i], str);
        city[i].resize(s[i]);
        for (int j = 0; j < s[i]; ++j)
            city[i][j] = str[j] - '0';
    }
}
LL qpow(LL a, LL b) {
    LL res(1);
    while (b) {
        if (b & 1) {
            res = res * a % MOD;
        }
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}
void init() {
    fac[0] = 1;
    int N = maxn - 3;
    for (int i = 1; i <= N; ++i)
        fac[i] = 1ll * fac[i - 1] * i % MOD;
    ifac[N] = qpow(fac[N], MOD - 2);
    for (int i = N - 1; i >= 0; --i)
        ifac[i] = 1ll * ifac[i + 1] * (i + 1) % MOD;
}
vector<bool> colbull[maxn];
int Gcdcol[maxn], cntbull[maxn], maxbull[maxn], minbull[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], colcnt, stk[maxn], top;
void tarjan(int u) {
    dfn[u] = low[u] = ++dfst;
    stk[++top] = u;
    for (int i = 0; i < (int)g[u].size(); ++i) {
        int v= g[u][i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (!col[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if (low[u] == dfn[u]) {
        ++colcnt;
        int v;
        do {
            v = stk[top--];
            col[v] = colcnt;
        } while (u != v);
        Gcdcol[colcnt] = s[u];
    }
}
void solve1() {
    for (int i = 1; i <= n; ++i)
        if (!dfn[i])
            tarjan(i);
    for (int i = 1; i <= n; ++i)
        Gcdcol[col[i]] = __gcd(Gcdcol[col[i]], s[i]);
    for (int i = 1; i <= n; ++i)  {
        colbull[col[i]].resize(Gcdcol[col[i]]);
        for (int j = 0; j < s[i]; ++j)
            if (city[i][j] == 1) {
                colbull[col[i]][j % Gcdcol[col[i]]] = 1;
            }
    }
    vector<bool> tmp;
    for (int i = colcnt; i >= 2; --i) {
        int g = __gcd(Gcdcol[i], Gcdcol[i - 1]);
        tmp.clear();
        tmp.resize(g);
        for (int j = 0; j < Gcdcol[i]; ++j)
            tmp[j % g] = tmp[j % g] | colbull[i][j];
        for (int j = 0; j < Gcdcol[i - 1]; ++j)
            colbull[i - 1][j] = colbull[i - 1][j] | tmp[j % g];
    }
    for (int i = 1; i <= colcnt; ++i)
        for (int j = 0; j < Gcdcol[i]; ++j)
            cntbull[i] += colbull[i][j];
    for (int i = 1; i <= n; ++i)
        maxbull[i] = s[i] / Gcdcol[col[i]] * cntbull[col[i]];
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < s[i]; ++j)
            minbull[i] += city[i][j];
}
LL ans;
LL combine(int n, int m) {
    if (m < 0 || n < 0 || m > n) return 0;
    return 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}
void solve2() {
    for (int i = 1; i <= n; ++i) {
        int cnt1 = 0, cnt2 = 0;
        for (int j = 1; j <= n; ++j) {
            if (i == j) continue;
            if (minbull[j] > maxbull[i]) ++cnt1;
            else if (maxbull[j] > maxbull[i] || (maxbull[j] == maxbull[i] and j < i)) ++cnt2;
        }
        if (cnt1 >= A) continue;
        for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) {
            ans = (1ll * ans + 1ll * combine(cnt1, B - j - 1) * combine(cnt2, j) % MOD) % MOD;
        }
    }
    cout << ans << endl;
}
int main() {
    input();
    init();
    solve1();
    solve2();
    return 0;
}

#pragma GCC optimize(2)
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<tr1/unordered_map>
#define il inline
#define FOR(i,a,b) for(i=a;i<=b;++i)
#define ROF(i,a,b) for(i=a;i>=b;--i)
#define TU(x) for(k=head[x];v=e[k].to;k=e[k].nex)
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
static char buf[100000],*p1(buf),*p2(buf);
using namespace std;
using namespace tr1;
const int N(5010),M(2000010),P(1e9+7);
int n,A,B,cn1,tc,tp,cn2,ans;
int head[N],jc[M],njc[M],ni[M],sze[N],mn[N],mx[N];
int dfn[N],low[N],sta[N],col[N],bg[N],cnt[N];
char s[M];
bool vis[N];
vector<int>S[N];
unordered_map<int,bool>f[N];
struct Edge{int nex,to;}e[N*N];
il void add(int x,int y){e[++cn1]=(Edge){head[x],y};head[x]=cn1;}
int read()
{
	int x(0),t(1);char ch(gc);
	while((ch<'0'||ch>'9')&&ch!='-')ch=gc;
	if(ch=='-')t=-1,ch=gc;
	while(ch>='0'&&ch<='9')x=x*10+(ch^'0'),ch=gc;
	return x*t;
}
int rds(char*s)
{
	int i(0);char ch(gc);
	while(ch!='0'&&ch!='1')ch=gc;
	while(ch=='0'||ch=='1')s[++i]=ch,ch=gc;
	return i;
}
il int min(const int&x,const int&y){return x<y?x:y;}
il int gcd(const int&x,const int&y){return y==0?x:gcd(y,x%y);}
il void pls(int&x,const int&y){x+=y;if(x>=P)x-=P;else if(x<0)x+=P;}
il int C(const int&n,const int&m){return n<0||m<0||n<m?0:1LL*jc[n]*njc[n-m]%P*njc[m]%P;}
void tarjan(int x)
{
	dfn[x]=low[x]=++tc;
	sta[++tp]=x;vis[x]=1;
	int k,v;TU(x)
	if(!dfn[v])
	{
		tarjan(v);
		low[x]=min(low[x],low[v]);
	}
	else if(vis[v])low[x]=min(low[x],dfn[v]);
	if(dfn[x]==low[x])
	{
		++cn2;
		while(sta[tp]!=x)
		{
			col[sta[tp]]=cn2;
			bg[cn2]=gcd(bg[cn2],sze[sta[tp]]);
			vis[sta[tp--]]=0;
		}
		col[x]=cn2;
		bg[cn2]=gcd(bg[cn2],sze[x]);
		vis[x]=0;--tp;
	}
}
il void init()
{
	freopen("fake.in","r",stdin);
	freopen("fake.out","w",stdout);
}
int main()
{
	int i,j;//init();
	n=read();A=read();B=read();
	FOR(i,1,n)
	{
		rds(s);FOR(j,1,n)
		if(s[j]=='1')add(i,j);
	}
	FOR(i,1,n)
	{
		sze[i]=read();rds(s);
		FOR(j,1,sze[i])
		{
			S[i].push_back(s[j]-'0');
			if(s[j]=='1')++mn[i];
		}
	}
	FOR(i,1,n)if(!dfn[i])tarjan(i);
	FOR(i,1,n)FOR(j,0,sze[i]-1)
	f[col[i]][j%bg[col[i]]]|=S[i][j];
	ROF(i,cn2,2)
	{
		int now(gcd(bg[i],bg[i-1]));
		FOR(j,0,bg[i]-1)
		{
			f[i-1][j%now]|=f[i][j];
			if(f[i][j])++cnt[i];
		}
	}
	FOR(i,0,bg[1]-1)if(f[1][i])++cnt[1];
	FOR(i,1,n)mx[i]=1LL*cnt[col[i]]*sze[i]/bg[col[i]];
//	FOR(i,1,n)printf("%d %d\n",mx[i],mn[i]);
	ni[1]=jc[0]=jc[1]=njc[0]=njc[1]=1;
	FOR(i,2,2000000)
	{
		jc[i]=1LL*jc[i-1]*i%P;
		ni[i]=1LL*(P-P/i)*ni[P%i]%P;
		njc[i]=1LL*njc[i-1]*ni[i]%P;
	}
	FOR(i,1,n)
	{
		cn1=cn2=0;
		FOR(j,1,n)if(i!=j)
		{
			if(mn[j]>mx[i])++cn1;
			else if(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i))++cn2;
		}
		if(cn1>A-1)continue;
		FOR(j,B-1-cn1,min(B,min(A-1-cn1,cn2)))
		pls(ans,1ll*C(cn2,j)*C(cn1,B-j-1)%P);
	}
	printf("%d",ans);
	return 0;
}
/*
考虑缩强连通分量，后在dag上转移即可
最后统计有多少种大小为B的城市集合满足其中所有城市均可能成为有最多faker的城市。
2 2 1
01
00
5 11000
6 100000
*/

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		   inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
	}
	return printf( "%d\n", ans ), 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#define int long long
#define vi vector<int> :: iterator
using namespace std;
const int N = 5e3 + 5, mod = 1e9 + 7;
bool get01() {char c = getchar(); while(c < '0' | c > '1') c = getchar(); return c ^ 48;}
int read() {
	int x = 0, f = 1; char ch;
	while(! isdigit(ch = getchar())) (ch == '-') && (f = -f);
	for(x = ch^48; isdigit(ch = getchar()); x = (x << 3) + (x << 1) + (ch ^ 48));
	return x * f;
}
template <class T> T Max(T a, T b) { return a > b ? a : b; }
template <class T> T Min(T a, T b) { return a < b ? a : b; }
int n, a, b, ans, num, top, tot, s[N], mn[N], mx[N], sz[N], dfn[N], low[N], sta[N], scc[N], C[N][N];
vector <int> mem[N], con[N], can[N];
struct Edge {
	int to;
	Edge *nxt;
	Edge(int to, Edge *nxt) : to(to), nxt(nxt) {}
} *head[N];
void add(int x, int y) {head[x] = new Edge(y, head[x]);}
void Tarjan(int x) {
	dfn[x] = low[x] = ++ num; sta[++ top] = x;
	for(Edge *i = head[x]; i; i = i->nxt) {
		if(! dfn[i->to]) Tarjan(i->to), low[x] = min(low[x], low[i->to]);
		else if(! scc[i->to]) low[x] = min(low[x], dfn[i->to]);
	}
	if(dfn[x] == low[x]) {
		int y; ++ tot;
		do {
			y = sta[top --];
			scc[y] = tot;
			sz[tot] = __gcd(sz[tot], s[y]);
			con[tot].push_back(y);
		} while(x != y);
		can[tot].resize(sz[tot]);
		for(vi it = con[tot].begin(); it != con[tot].end(); ++ it) {
			for(vi j = mem[* it].begin(); j != mem[* it].end(); ++ j) can[tot][* j % sz[tot]] = 1;
		}
	}
}
signed main() {
	n = read(); a = read(); b = read();
	for(int i = 1; i <= n; ++ i) for(int j = 1; j <= n; ++ j) if(get01()) add(i, j);
	for(int i = 1; i <= n; ++ i) {
		s[i] = read();
		for(int j = 0; j < s[i]; ++ j) if(get01()) ++ mn[i], mem[i].push_back(j);
	}
	for(int i = 1; i <= n; ++ i) if(! dfn[i]) Tarjan(i);
	for(int i = tot; i > 1; -- i) {
		sz[i - 1] = __gcd(sz[i], sz[i - 1]);
		for(int j = 0; j < sz[i]; ++ j) if(can[i][j]) can[i - 1][j % sz[i - 1]] = 1;
	}
	for(int i = 1, x; i <= n; ++ i) {
		x = scc[i];
		for(int j = 0; j < s[i]; ++ j) mx[i] += can[x][j % sz[x]];
	}
	C[0][0] = 1;
	for(int i = 1; i <= n; ++ i) {
		C[i][0] = 1;
		for(int j = 1; j <= i; ++ j) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
	}
	for(int i = 1, cnt1, cnt2; i <= n; ++ i) {
		cnt1 = cnt2 = 0;
		for(int j = 1; j <= n; ++ j) if(mn[j] > mx[i]) ++ cnt1;
		if(cnt1 >= a) continue;
		for(int j = 1; j <= n; ++ j) {
			if(mn[j] <= mx[i] && (mx[j] > mx[i] || (mx[j] == mx[i] && j > i))) ++ cnt2;
		}
		for(int j = min(b - 1, min(cnt2, a - cnt1 - 1)); j >= 0; -- j) {
			(ans += C[cnt2][j] * C[cnt1][b - j - 1]) %= mod;
		}
	}
	printf("%lld\n", ans);
	return 0;
}
/*
2 2 1
01
00
5 11000
6 100000

*/

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
#define MX 2000005
#define SIZE 5005
#define MOD 1000000007

using namespace std;
typedef long long int ll;
typedef pair <int,int> P;

char mp[SIZE][SIZE];
ll C[SIZE][SIZE];
vector <int> nd[SIZE];
vector <int> vs;
int cmb[SIZE];
bool use[SIZE];
char str[MX];
string A[SIZE];
string B[SIZE];
P pos[SIZE];
int n;

void init()
{
	for(int i=0;i<SIZE;i++)
	{
		C[i][0]=C[i][i]=1;
		for(int j=1;j<i;j++)
		{
			C[i][j]=C[i-1][j-1]+C[i-1][j];
			if(C[i][j]>=MOD) C[i][j]%=MOD;
		}
	}
}
int gcd(int x,int y)
{
	if(x==0) return y;
	return gcd(y%x,x);
}
void dfs(int v)
{
	use[v]=true;
	for(int i=0;i<n;i++) if(!use[i]&&mp[v][i]=='1') dfs(i);
	vs.push_back(v);
}
void rdfs(int v,int k)
{
	use[v]=true;
	cmb[v]=k;
	nd[k].push_back(v);
	for(int i=0;i<n;i++) if(!use[i]&&mp[i][v]=='1') rdfs(i,k);
}
int scc()
{
	memset(use,false,sizeof(use));
	for(int i=0;i<n;i++) if(!use[i]) dfs(i);
	memset(use,false,sizeof(use));
	int k=0;
	for(int i=n-1;i>=0;i--) if(!use[vs[i]]) rdfs(vs[i],k++);
	return k;
}
int main()
{
	init();
	int a,b;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=0;i<n;i++) scanf("%s",&mp[i]);
	for(int i=0;i<n;i++)
	{
		int DM;
		scanf("%d %s",&DM,&str);
		A[i]=str;
	}
	int sz=scc();
	int nm=0;
	for(int i=0;i<sz;i++)
	{
		//for(int j=0;j<nd[i].size();j++) printf("%d ",nd[i][j]);puts("");
		int g=i>0?B[i-1].size():0;
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			g=gcd(g,A[v].size());
		}
		for(int j=0;j<g;j++) B[i]+="0";
		if(i>0)
		{
			for(int j=0;j<B[i-1].size();j++)
			{
				if(B[i-1][j]=='1')
				{
					B[i][j%g]='1';
				}
			}
		}
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			for(int k=0;k<A[v].size();k++)
			{
				if(A[v][k]=='1')
				{
					B[i][k%g]='1';
				}
			}
		}
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			int a=0,b=0;
			for(int k=0;k<A[v].size();k++)
			{
				if(A[v][k]=='1') a++;
				if(B[i][k%g]=='1') b++;
			}
			pos[nm++]=P(b,a);
		}
		//printf("%s\n",B[i].c_str());
	}
	sort(pos,pos+n);
	priority_queue <int> que;
	ll ret=0;
	int cnt=0;
	a--,b--;
	for(int i=n-1;i>=0;i--)
	{
		P p=pos[i];
		while(!que.empty()&&que.top()>p.first)
		{
			cnt++;
			que.pop();
		}
		//printf("%d %d : %d %d\n",p.first,p.second,i,cnt);
		for(int j=0;j<=min(b,cnt);j++)
		{
			int zb=b-j;
			if(zb<=que.size()&&b+(cnt-j)<=a)
			{
				ll way=C[que.size()][zb]*C[cnt][j]%MOD;
				ret+=way;
				if(ret>=MOD) ret-=MOD;
			}
		}
		que.push(p.second);
	}
	printf("%lld\n",ret);
	return 0;
}

#include<bits/stdc++.h>
inline int read(){
    int x=0,w=1;
    char ch=0;
    while (ch<'0' || ch>'9'){
        ch=getchar();
        if (ch=='-') w=-1;
    }
    while (ch<='9' && ch>='0'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    return x*w;
}
using namespace std;
typedef long long ll;
const int N=5005;
const int M=2e6+5;
const int Mod=1e9+7;
char str[M];
int n,k1,k2,tot,tim,ans;
int s[N],bg[N],vis[N];
int dfn[N],low[N],b[N];
int mn[N],mx[N],cnt[N];
int fac[M],inv[M];
inline void ad(int &x,int y){
    x+=y;
    if (x>=Mod) x-=Mod;
    if (x<0) x+=Mod;
}
inline int Pow(int x,int y){
    int res=1;
    while (y){
        if (y&1) res=1ll*res*x%Mod;
        x=1ll*x*x%Mod;
        y>>=1;
    }
    return res;
}
inline void math_init(int nn){
    fac[0]=1;
    for (int i=1;i<=nn;++i)
        fac[i]=1ll*fac[i-1]*i%Mod;
    inv[nn]=Pow(fac[nn],Mod-2);
    for (int i=nn;i;--i)
        inv[i-1]=1ll*inv[i]*i%Mod;
}
inline int C(int x,int y){
    if (x<y || x<0 || y<0) return 0;
    return 1ll*(1ll*fac[x]*inv[y]%Mod)*inv[x-y]%Mod;
}
vector<int>G[N],g[N],f[N];
stack<int>sta;
int gcd(int x,int y){
    if (!y) return x;
    return gcd(y,x%y);
}
inline void input(){
    n=read(),k1=read(),k2=read();
    for (int i=1;i<=n;++i){
        scanf("%s",str+1);
        for (int j=1;j<=n;++j)
            if (str[j]=='1') G[i].push_back(j);
    }
    for (int i=1;i<=n;++i){
        s[i]=read();
        scanf("%s",str+1);
        for (int j=1;j<=s[i];++j){
            g[i].push_back(str[j]-'0');
            mn[i]+=str[j]-'0';
        }
    }
}
void tarjan(int x){
    dfn[x]=low[x]=++tim;
    sta.push(x),vis[x]=1;
    for (int i=0,sz=G[x].size();i<sz;++i){
        int y=G[x][i];
        if (!dfn[y]){
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }else if (vis[y]) low[x]=min(low[x],dfn[y]);
    }
    if (low[x]==dfn[x]){
        int now=0;++tot;
        do{
            now=sta.top(),sta.pop(),vis[now]=0;
            b[now]=tot,bg[tot]=gcd(bg[tot],s[now]);
        }while (now!=x);
    }
}
namespace sub1{
    inline void build(){
        for (int i=1;i<=n;++i)
            if (!dfn[i]) tarjan(i);
        for (int i=1;i<=tot;++i)
            f[i].resize(bg[i]+1);
        for (int i=1;i<=n;++i)
            for (int j=0;j<s[i];++j)
                f[b[i]][j%bg[b[i]]]|=g[i][j];
    }
    inline void solve(){
        build();
        for (int i=tot;i>1;--i){
            int now=gcd(bg[i],bg[i-1]);
            for (int j=0;j<bg[i];++j){
                f[i-1][j%now]|=f[i][j];
                cnt[i]+=f[i][j];
            }
        }
        for (int i=0;i<bg[1];++i) cnt[1]+=f[1][i];
        for (int i=1;i<=n;++i)
            mx[i]=1ll*cnt[b[i]]*s[i]/bg[b[i]];
    }
}
namespace sub2{
    inline void solve(){
        for (int i=1;i<=n;++i){
            int cnt1=0,cnt2=0;
            for (int j=1;j<=n;++j){
                if (i==j) continue;
                if (mn[j]>mx[i]) ++cnt1;
                else if (mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) ++cnt2;
            }
            if (cnt1>k1-1) continue;
            for (int j=min(k2,min(k1-1-cnt1,cnt2));j+cnt1+1>=k2;--j)
                ad(ans,1ll*C(cnt2,j)*C(cnt1,k2-j-1)%Mod);
        }
        printf("%d\n",ans);
    }
}
int main(){
	//freopen("fake.in","r",stdin);
	//freopen("fake.out","w",stdout);

    math_init(M-5),input();
    sub1::solve(),sub2::solve();
    return 0;
}

#include<cstdio>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
#define int long long
const int mod=1000000007;
int fac[10010],inv[10010],dfn[10010],low[10010],idx,cnt;
int ins[10010],head[10010],col[10010],tot,gcdcol[10010],sum[10010];
int n,A,B,minn[10010],maxn[10010],ans,Cnt[1001000];
vector<int>v[1001000],Col[1001000];
char S[1001000];
stack<int>sta;
struct Edge{
	int to,nxt;
}edge[20001000];
void addedge(int x,int y){
	edge[++cnt].to=y;
	edge[cnt].nxt=head[x];
	head[x]=cnt;
}
int quickpow(int x,int y){
	int res=1;
	for(;y;y>>=1,x=x*x%mod)
		if(y&1)res=res*x%mod;
	return res;
}
int C(int x,int y){
	if(x<y||y<0)return 0;
	if(x==y||y==0)return 1;
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
void Tarjan(int x){
	sta.push(x);
	ins[x]=1;
	dfn[x]=low[x]=++idx;
	for(int i=head[x];i;i=edge[i].nxt){
		int upup=edge[i].to;
		if(!dfn[upup]){
			Tarjan(upup);
			low[x]=min(low[x],low[upup]);
		}
		else if(ins[upup]){
			low[x]=min(low[x],dfn[upup]);
		}
	}
	if(dfn[x]==low[x]){
		tot++;
		while(sta.top()!=x){
			col[sta.top()]=tot;
			ins[sta.top()]=0;
			sta.pop();
		}
		col[sta.top()]=tot;
		ins[sta.top()]=0;
		sta.pop();
	}
	gcdcol[tot]=sum[x];
}
signed main(){
	scanf("%lld%lld%lld",&n,&A,&B);
	for(int i=1;i<=n;i++){
		scanf("%s",S+1);
		for(int j=1;j<=n;j++)
			if(S[j]=='1')addedge(i,j);
	}
	for(int i=1;i<=n;i++){
		scanf("%lld%s",&sum[i],S+1);
		for(int j=1;j<=sum[i];j++)
			v[i].push_back(S[j]-'0'),minn[i]+=S[j]-'0';
	}
	fac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=fac[i-1]*i%mod;
	inv[n]=quickpow(fac[n],mod-2);
	for(int i=n-1;i>=0;i--)
		inv[i]=inv[i+1]*(i+1)%mod;
	for(int i=1;i<=n;i++)
		if(!dfn[i])Tarjan(i);
	for(int i=1;i<=n;i++)
		gcdcol[col[i]]=__gcd(gcdcol[col[i]],sum[i]);
	for(int i=1;i<=n;i++){
		Col[col[i]].resize(gcdcol[col[i]]);
		for(int j=0;j<sum[i];j++)
			if(v[i][j]==1)
				Col[col[i]][j%gcdcol[col[i]]]=1;
	}
	vector<bool>tmp;
	for(int i=tot;i>=2;i--){
		int g=__gcd(gcdcol[i],gcdcol[i-1]);
		tmp.clear();
		tmp.resize(g);
		for(int j=0;j<gcdcol[i];j++)
			tmp[j%g]=tmp[j%g]|Col[i][j];
		for(int j=0;j<gcdcol[i-1];j++)
			Col[i-1][j]=Col[i-1][j]|tmp[j%g];
	}
	for(int i=1;i<=tot;i++)
		for(int j=0;j<gcdcol[i];j++)
			Cnt[i]+=Col[i][j];
	for(int i=1;i<=n;i++)
		maxn[i]=sum[i]/gcdcol[col[i]]*Cnt[col[i]];
	for(int i=1;i<=n;i++){
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++){
			if(i==j)continue;
			if(minn[j]>maxn[i])cnt1++;
			else if(maxn[j]>maxn[i]||maxn[j]==maxn[i]&&j<i)cnt2++;
		}
		if(cnt1>=A)continue;
		for(int j=min(B-1,min(cnt2,A-1-cnt1));j>=B-cnt1-1&&j>=0;j--)
			(ans+=C(cnt1,B-j-1)*C(cnt2,j)%mod)%=mod;
	}
	printf("%lld\n",ans);
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b){
	int ret=1;
	while (b) {
		if(b&1) ret=(ll)ret*a%mod;
		a=(ll)a*a%mod;
		b>>=1;
	}return ret;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

 main(){
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    for (int i=1;i<=n;++i) {
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	for (int j=0;j<bgcd[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<bgcd[1];++j) if(gold[fr[1+n]+j])
		++num[1];
    for (int i=1;i<=n;++i)  {
        mx[i]=(ll)num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
	}
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        for (int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&(~j);--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b){
	int ret=1;
	while (b) {
		if(b&1) ret=(ll)ret*a%mod;
		a=(ll)a*a%mod;
		b>>=1;
	}return ret;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

 main(){
	//freopen("1.in","r",stdin);
	//freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        //printf ("bcc[%d]=%d\n",i,bccno[i]);
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<bgcd[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<bgcd[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
	 	printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=(ll)num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
       //
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;//,inv[i]=powmod(fac[i],mod-2);
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
    	//printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        //printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&(~j);--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
inline int read(){
	int x=0,w=1;
	char ch=0;
	while (ch<'0' || ch>'9'){
		ch=getchar();
		if (ch=='-') w=-1;
	}
	while (ch<='9' && ch>='0'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*w;
}
using namespace std;
typedef long long ll;
const int N=5005;
const int M=2e6+5;
const int Mod=1e9+7;
char str[M];
int n,k1,k2,tot,tim,ans;
int s[N],bg[N],vis[N];
int dfn[N],low[N],b[N];
int mn[N],mx[N],cnt[N];
int fac[M],inv[M],apr[M];
inline void ad(int &x,int y){
	x+=y;
	if (x>=Mod) x-=Mod;
	if (x<0) x+=Mod;
}
inline int Pow(int x,int y){
	int res=1;
	while (y){
		if (y&1) res=1ll*res*x%Mod;
		x=1ll*x*x%Mod;
		y>>=1;
	}
	return res;
}
inline void math_init(int nn){
	fac[0]=1;
	for (int i=1;i<=nn;++i)
		fac[i]=1ll*fac[i-1]*i%Mod;
	inv[nn]=Pow(fac[nn],Mod-2);
	for (int i=nn;i;--i)
		inv[i-1]=1ll*inv[i]*i%Mod;
}
inline int C(int x,int y){
	if (x<y || x<0 || y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%Mod)*inv[x-y]%Mod;
}
vector<int>G[N],g[N],f[N];
stack<int>sta;
int gcd(int x,int y){
	if (!y) return x;
	return gcd(y,x%y);
}
inline void input(){
	n=read(),k1=read(),k2=read();
	for (int i=1;i<=n;++i){
		scanf("%s",str+1);
		for (int j=1;j<=n;++j)
			if (str[j]=='1') G[i].push_back(j);
	}
	for (int i=1;i<=n;++i){
		s[i]=read();
		scanf("%s",str+1);
		for (int j=1;j<=s[i];++j){
			g[i].push_back(str[j]-'0');
			mn[i]+=str[j]-'0';
		}
	}
}
void tarjan(int x){
	dfn[x]=low[x]=++tim;
	sta.push(x),vis[x]=1;
	for (int i=0,sz=G[x].size();i<sz;++i){
		int y=G[x][i];
		if (!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}else if (vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if (low[x]==dfn[x]){
		int now=0;++tot;
		do{
			now=sta.top(),sta.pop(),vis[now]=0;
			b[now]=tot,bg[tot]=gcd(bg[tot],s[now]);
		}while (now!=x);
	}
}
namespace sub1{
	inline void build(){
		for (int i=1;i<=n;++i)
			if (!dfn[i]) tarjan(i);
		for (int i=1;i<=tot;++i)
			f[i].resize(bg[i]+1);
		for (int i=1;i<=n;++i)
			for (int j=0;j<s[i];++j)
				f[b[i]][j%bg[b[i]]]|=g[i][j];
	}
	inline void solve(){
		build();
		for (int i=tot;i>1;--i){
			int now=gcd(bg[i],bg[i-1]);
			for (int j=0;j<bg[i];++j){
				apr[j%now]|=f[i][j];
				cnt[i]+=f[i][j];
			}
			for (int j=0;j<bg[i-1];++j) f[i-1][j]|=apr[j%now];
			for (int j=0;j<bg[i];++j) apr[j%now]=0;
		}
		for (int i=0;i<bg[1];++i) cnt[1]+=f[1][i];
		for (int i=1;i<=n;++i)
			mx[i]=1ll*cnt[b[i]]*s[i]/bg[b[i]];
	}
}
namespace sub2{
	inline void solve(){
		for (int i=1;i<=n;++i){
			int cnt1=0,cnt2=0;
			for (int j=1;j<=n;++j){
				if (i==j) continue;
				if (mn[j]>mx[i]) ++cnt1;
				else if (mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) ++cnt2;
			}
			if (cnt1>k1-1) continue;
			for (int j=min(k2,min(k1-1-cnt1,cnt2));j+cnt1+1>=k2;--j)
				ad(ans,1ll*C(cnt2,j)*C(cnt1,k2-j-1)%Mod);
		}
		printf("%d\n",ans);
	}
}
int main(){
//	freopen("fake.in","r",stdin);
//	freopen("fake.out","w",stdout);
	math_init(M-5),input();
	sub1::solve(),sub2::solve();
	return 0;
}

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
#define N 5005
using namespace std;
int n,a,b,s[N],sz[N],C[N][N],Ans;char c[2000005];
short to[N*N],fr[N*N];int nxt[N*N],fst[N],l;
int st[N],top,bl[N],cnt,dfn[N],low[N],clk;
vector<short>p[N],v[N],e[N];
struct T
{
	int x,y;
}d[N];
int cmp(T a,T b)
{
	return a.y==b.y?a.x>b.x:a.y>b.y;
}

void link(int x,int y)
{
	to[++l]=y;fr[l]=x;nxt[l]=fst[x];fst[x]=l;
}
void dfs(int x)
{
	low[x]=dfn[x]=++clk;
	st[++top]=x;
	for (int i=fst[x];i;i=nxt[i])
		if (!dfn[to[i]])
		{
			dfs(to[i]);
			low[x]=min(low[x],low[to[i]]);
		}
		else if (!bl[to[i]])
			low[x]=min(low[x],low[to[i]]);

	if (low[x]==dfn[x])
	{
		cnt++;
		while(st[top]!=x)
		{
			//p[cnt].push_back(st[top]);
			bl[st[top--]]=cnt;
		}
		//p[cnt].push_back(st[top]);
		bl[st[top--]]=cnt;
	}
}
short _to[N*N];int _nxt[N*N],_fst[N],_l,rd[N];
void lk(int x,int y)
{
	_to[++_l]=y;_nxt[_l]=_fst[x];_fst[x]=_l;rd[y]++;
}
vector<short>tp;
int tmp;
void work(int x)
{
	//cout<<x<<endl;
	rd[x]=-1;tmp=x;
	for (int i=_fst[x];i;i=_nxt[i])
	{
		rd[_to[i]]--;
		if (rd[_to[i]]==0)
		{
			//tmp=__gcd(tmp,sz[_to[i]]);
			int g=__gcd(sz[tmp],sz[_to[i]]);/*
			for (int j=0;j<=sz[x];j++)
				e[_to[i]][j%sz[_to[i]]]|=e[x][j];*/

			tp.clear();
			for (int j=0;j<g;j++)tp.push_back(0);
			for (int j=0;j<sz[tmp];j++)
				if (e[tmp][j]) tp[j%g]=1;
			for (int j=0;j<sz[_to[i]];j++)
				if (tp[j%g]) e[_to[i]][j]=1;

			work(_to[i]);
		}
	}
}
int bit[2000005];
void add(int x)
{
	x++;
	for (;x<=2000002;x+=x&-x)
		bit[x]++;
}
int qry(int x)
{
	x++;
	int ans=0;
	for (;x;x-=x&-x)
		ans+=bit[x];
	return ans;
}
int main()
{

	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		for (int j=1;j<=n;j++)
		{
			if (c[j]=='1')
				link(i,j);
		}
	}

	for (int i=1;i<=n;i++)
		if (!dfn[i])
			dfs(i);

	int Mx=0;
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);Mx=max(Mx,s[i]);
		sz[bl[i]]=__gcd(sz[bl[i]],s[i]);
		p[bl[i]].push_back(i);
		scanf("%s",c+1);
		for (int j=1;j<=s[i];j++)
		{
			v[i].push_back(c[j]=='1');
			d[i].x+=c[j]=='1';
		}
	}
	for (int i=1;i<=cnt;i++)
	{
		for (int j=0;j<sz[i];j++)
			e[i].push_back(0);
		for (int j=0;j<p[i].size();j++)
		{
			for (int k=0;k<v[p[i][j]].size();k++)
			if (v[p[i][j]][k])
				e[i][k%sz[i]]=1;
		}
	}
	for (int i=1;i<=l;i++)
		if (bl[fr[i]]!=bl[to[i]])
			lk(bl[fr[i]],bl[to[i]]);

	for (int i=1;i<=cnt;i++)
		if (rd[i]==0)
		{
			work(i);
		}

	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<s[i];j++)
			if (v[i][j]||e[bl[i]][j%sz[bl[i]]]) d[i].y++;
	}
	sort(d+1,d+n+1,cmp);

	C[0][0]=1;
	for (int i=1;i<=n;i++)
	{
		C[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
		}
	}
	for (int i=1;i<=n;i++)
	{
		if (i>=b)
		{
			if (i<=a) Ans=(Ans+C[i-1][b-1])%P;
			else
			{
				int u=qry(d[i].y),v=i-1-u;
				for (int j=0;j<=u&&j<b;j++)
				{
					if (v+j+1<=a)
						Ans=(Ans+(ll)C[u][j]*C[v][b-j-1])%P;
				}
			}
		}
		add(d[i].x);
	}
	/*
	cerr<<Ans<<endl;
	cerr<<Mx<<' '<<d[1].x<<' '<<d[1].y<<' '<<cnt<<endl;
	*/
	printf("%d\n",Ans);

}

#include <bits/stdc++.h>
using namespace std;
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define MK make_pair
#define PB push_back
#define fi first
#define se second
#define RG register
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int N= 5e3 +10;
const LL MOD = 1e9+7;
vector<int> can[N], mem[N], con[N], g[N];

int ge[N], sz[N], dfn[N], n, m, mn[N], mx[N],low[N], dfs_clock=0, belong[N], tot=0;
LL C[N][N];
int gcd(int a, int b){ return b==0 ? a : gcd( b, a%b);}
int get01(){
	char c ; for (c=getchar(); c<'0' || c>'1'; c=getchar());
	return c^48;
}
stack<int> sk;
void dfs(int u){
	dfn[u] = low[u]= ++dfs_clock;
	sk.push(u);
	for (auto v: g[u])
		if ( !dfn[v]){dfs(v); low[u] = min(low[u], low[v]);}	else
		if( !belong[v])  low[u] = min(low[u] , dfn[v]);
	if ( dfn[u] == low[u]){
		RG int x;
		++tot; sz[tot] = 0;
		do{
			x= sk.top(); sk.pop();
			sz[tot] = gcd(sz[tot] , ge[x]); belong[x] = tot;
			con[tot].PB(x);
		}while ( x!=u);
		can[tot].resize(sz[tot]);
		for (auto i:con[tot]) for( auto j: mem[i])
			can[tot][j%sz[tot]]=1;
	}
}
int main(){
	#ifdef che
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
	#endif
	RG int i, j,n,a, b,x;
	scanf("%d%d%d", &n, &a, &b);
	for (i=1; i<=n; ++i)	for (j=1; j<=n; ++j)
		if ( get01()) g[i].PB(j);
	for (i=1; i<=n; ++i){
		scanf("%d", &ge[i]);
		for (j=0; j<ge[i]; ++j)	if( get01()) mem[i].PB(j);
		mn[i] = mem[i].size();
	}
	for (i=1; i<=n; ++i)if ( !dfn[i]) dfs(i);
//-------------------------------------
	for (i=tot; i>1; --i){
		for ( sz[i-1] = gcd(sz[i], sz[i-1]) , j=0; j<sz[i]; ++j)
			if ( can[i][j] ) can[i-1][j%sz[i-1]] = 1;
	}
	for (i=1; i<=n; ++i)
		for (x=belong[i], j=0; j<ge[i]; ++j)
			if ( can[x][ j%sz[x]]) ++mx[i];
	#ifdef che
	for (i=1; i<=n; ++i) debug("[%d]  mn[]= %d,  mx[] = %d\n", i, mn[i], mx[i]);
	#endif
//-------------------------------------
	for (i=0; i<=n; ++i){
		C[i][0] = 1;
		for (j=1; j<=i; ++j) C[i][j]= (C[i-1][j] + C[i-1][j-1])%MOD;
	}

	LL ans= 0, cnt1, cnt2;
	for (i=1; i<=n; ++i){
		cnt1=cnt2= 0;
		for (j=1; j<=n; ++j) if ( mn[j] > mx[i] ) ++cnt1;

		for (j=1; j<=n; ++j)
			if ( mn[j] <= mx[i] && (mx[j]>mx[i] || (mx[j]==mx[i] && j >i))) ++cnt2;

		for (j= min( 1ll*b-1, min(cnt2, a-1-cnt1)); j>=0; --j)
			 ans =(ans + C[cnt2][j] *C[cnt1][b-1-j])%MOD;
	}
	cout<<ans<<endl;
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n,a,b,c;
char str[MAXL+5];
vector<int> G[MAXN+5];
vector<int> per[MAXN+5];
int siz[MAXN+5],dfn[MAXN+5],low[MAXN+5],dcnt;
int blo[MAXN+5],bgcd[MAXN+5],blocnt;
int stk[MAXN+5],t;
int num[MAXN+5],mx[MAXN+5],mn[MAXN+5];
bool instk[MAXN+5];
int fact[MAXN+5],inv[MAXN+5];
int PowMod(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret=1LL*ret*x%MO;
		x=1LL*x*x%MO;
		y>>=1;
	}
	return ret;
}
int gcd(int x,int y)
{
	if(y==0)
		return x;
	return gcd(y,x%y);
}
void InPut()
{
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				G[i].push_back(j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		per[i].resize(siz[i]+1);
		scanf("%s",str);
		for(int j=0;j<siz[i];j++)
			if(str[j]=='1')
				per[i][j]=1;
			else if(str[j]=='0')
				per[i][j]=0;
	}
}
void Tarjan(int u,int fa)
{
	dfn[u]=low[u]=++dcnt;
	instk[u]=true;stk[t++]=u;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(dfn[v]==0)
		{
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]==true)
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int fro=0;blocnt++;
		do
		{
			fro=stk[--t];instk[fro]=false;
			blo[fro]=blocnt;
			bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
		}while(fro!=u);
	}
}
void Part1()
{
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			Tarjan(i,-1);
	for(int i=1;i<=blocnt;i++)
		per[i+n].resize(bgcd[i]+1);//预先设定大小
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];//存到虚拟黑帮中
	int nw;
	for(int i=blocnt;i>1;i--)//自然形成了哈密顿路径
	{
		nw=gcd(bgcd[i],bgcd[i-1]);//当前的剩余系
		for(int j=0;j<bgcd[i];j++)
			if(per[i+n][j])
			{
				per[i-1+n][j%nw]|=1;//对下一个点进行更新
				num[i]++;//num就是总的金条数
			}
	}
	for(int j=0;j<bgcd[1];j++)
		num[1]+=per[1+n][j];//记得一定要统计block1的值
	for(int i=1;i<=n;i++)
	{
		mx[i]=mn[i]=0;
		mx[i]=1LL*num[blo[i]]*siz[i]/bgcd[blo[i]];//根据性质三进行还原
		for(int j=0;j<siz[i];j++)
			mn[i]+=per[i][j];//直接利用初始信息算
	}
}
void Prepare()
{
	fact[0]=1;
	for(int i=1;i<=MAXN;i++)
		fact[i]=1LL*fact[i-1]*i%MO;
	inv[MAXN]=PowMod(fact[MAXN],MO-2);
	for(int i=MAXN-1;i>=0;i--)
		inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%MO;
}
inline int C(int x,int y)
{
	return 1LL*fact[x]*inv[y]%MO*inv[x-y]%MO;
}
int Part2()
{
	Prepare();
	int cnt1=0,cnt2=0,ret=0;
	for(int i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i!=j&&mn[j]>mx[i])
				cnt1++;
			if(i!=j&&mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)))//避免重复
				cnt2++;
		}
		if(cnt1>a-1)
			continue;
		for(int j=min(b,min(a-1-cnt1,cnt2));j>=0&&j+1+cnt1>=b;j--)//一堆限制
			ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%MO)%MO;
	}
	return ret;
}
int main()
{
	InPut();
	Part1();
	int ans=Part2();
	printf("%d\n",ans);
	return 0;
}//hello//hellobig_tq

//   Author:Arturia
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<ctime>
#include<cstdlib>
#include<string>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];~x;x=nx[x])
#define ll long long
#define inf (1<<29)
#define pii pair<int,int>
#define pdd pair<double,double>
#define mk(a,b) make_pair(a,b)
#define fs first
#define sc second
#define pb push_back
#define VI vector<int>
#define VS vector<string>
using namespace std;
inline ll rd(){
	ll x=0;int ch=getchar(),f=1;
	while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
	if (ch=='-'){f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
inline void rt(ll x){
	if (x<0) putchar('-'),x=-x;
	if (x>=10) rt(x/10),putchar(x%10+'0');
		else putchar(x+'0');
}
const int maxn=5005,maxs=2000005,p=1000000007;
char mp[maxn][maxn],ch[maxs];
int n,vb[maxs],*b[maxn],vc[maxs],*c[maxn];
int sb[maxn],sc[maxn];
int gcd(int a,int b){return !b?a:gcd(b,a%b);}

namespace Graph{
	int dfn[maxn],low[maxn],tim;
	int ins[maxn],stk[maxn],top;
	int lst[maxn],lc,ks;
	int blt[maxn],topo[maxn];
	void dfs(int u){
	//	printf("u=%d\n",u);
		dfn[u]=low[u]=++tim;stk[++top]=u,ins[u]=1;
		rep(v,1,n){
			if (mp[u][v]=='0') continue;
			if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
			else if (ins[v]) low[u]=min(low[u],dfn[v]);
		}
		if (low[u]==dfn[u]){
			++ks;lc=0;
			int g=0;
			while (stk[top+1]!=u){
				int t=stk[top];
				lst[++lc]=t,blt[t]=ks,ins[t]=0,top--;
				g=gcd(g,sb[t]);
			}
			c[ks]=c[ks-1]+sc[ks-1];
			sc[ks]=g;
			for (int _=1,i=lst[_];_<=lc;_++,i=lst[_])
				rep(j,0,sb[i]-1) c[ks][j%g]|=b[i][j];
		}
	}
	int tmp[maxs];
	void walk(){
		drp(i,ks-1,1){
			int g=gcd(sc[i],sc[i+1]);
			rep(j,0,g-1) tmp[j]=0;
			rep(j,0,sc[i+1]-1) tmp[j%g]|=c[i+1][j];
			rep(j,0,sc[i]-1) c[i][j]|=tmp[j%g];
		}
		rep(i,1,n){
			int x=blt[i];
			rep(j,0,sb[i]-1) b[i][j]|=c[x][j%sc[x]];
		}
	}
}
using namespace Graph;
int mn[maxn],mx[maxn];
int fac[maxn],inv[maxn],cnt;
int qpow(int a,int b){
	int ret=1;
	for (;b;b>>=1,a=(ll)a*a%p) if (b&1) ret=(ll)ret*a%p;
	return ret;
}
int prepare(){
	fac[0]=1;rep(i,1,n) fac[i]=(ll)fac[i-1]*i%p;
	inv[n]=qpow(fac[n],p-2);
	drp(i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%p;
}
int A,B;
bool cmp(const int &a,const int &b){return a>b;}
int C(int n,int m){return (ll)fac[n]*inv[m]%p*inv[n-m]%p;}
int main(){
	n=rd(),A=rd(),B=rd();
	rep(i,1,n) scanf("%s",mp[i]+1);
	b[0]=vb;c[0]=vc;
	rep(i,1,n){
		sb[i]=rd();
		scanf("%s",ch);
		b[i]=b[i-1]+sb[i-1];
		rep(j,0,sb[i]-1) b[i][j]=ch[j]-'0',mn[i]+=b[i][j];
	}
	rep(i,1,n) if (!dfn[i]) dfs(i);
	walk();
	rep(i,1,n) rep(j,0,sb[i]-1) mx[i]+=b[i][j];
	prepare();
	int ans=0;
	rep(i,1,n){
		int must=0,might=0;
		rep(j,1,n){
			if (mn[j]>mx[i]) must++;
			else if (mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)) might++;
		}
		for (int j=max(0,B-must-1);j+must+1<=A&&j<=min(might,B-1);j++)
			ans=((ll)C(might,j)*C(must,B-j-1)+ans)%p;
	}
	rt(ans),putchar('\n');
}

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<map>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef long long LL;
typedef double db;

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;
	fo(y,1,n)
	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;
	fo(i,1,top){
		if (i>1&&st[i].len==st[u_].len){
			fo(x,0,st[i].len-1)tv[st[u_].st+x]|=tv[st[i].st+x];
			continue;
		}
		u_++;
		st[u_].len=st[i].len;
		st[u_].st=tot+1;
		fo(x,0,st[i].len-1)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;}

LL js[N],inv[N];

LL 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();
	fo(i,1,n){
		scanf("%s",str+1);
		fo(j,1,n)mp[i][j]=(str[j]=='1');
	}
	fo(i,1,n){
		siz[i]=get();
		St[i]=Len+1;
		fo(j,1,siz[i]){
			char ch;
			while(ch=getchar(),ch<'0'||ch>'9');
			Real[++Len]=ch-'0';
		}
		Ed[i]=Len;
	}
	fo(i,1,n)
	if (!dfn[i])tarjan(i);
	fo(i,1,n)
		fo(j,1,n)
		if (mp[i][j]&&be[i]!=be[j]&&!ins[be[j]][be[i]]){
			ins[be[j]][be[i]]=1;
			d[be[j]]++;
		}
	fo(i,1,m)num[i]=i;
	sort(num+1,num+1+m,cmp);
	fo(i,1,m)tr[num[i]]=i;
	fo(i,1,n)be[i]=tr[be[i]];
	top=0;
	fo(id,1,m){
		k=0;
		fo(i,1,n)
		if (be[i]==id)key[++k]=i;
		sz[id]=siz[key[1]];
		fo(i,1,k)sz[id]=gcd(sz[id],siz[key[i]]);

		st[++top].st=tot+1;
		st[top].len=sz[id];
		fo(i,tot+1,tot+sz[id])tv[i]=0;
		fo(i,1,k)
			fo(j,St[key[i]],Ed[key[i]])
			tv[tot+1+(j-St[key[i]])%sz[id]]|=Real[j];
		tot+=sz[id];

		fo(u,1,top-1){
			int d=gcd(st[u].len,sz[id]);
			fo(x,0,d-1){
				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;
		}

		fo(i,1,k)
			fo(j,St[key[i]],Ed[key[i]])
			Fake[j]=tv[st[top].st+(j-St[key[i]])%sz[id]]^Real[j];

		merge();
	}
	fo(i,1,n){
		a[i].real=a[i].fake=0;
		fo(j,St[i],Ed[i])
		if (Real[j])a[i].real++;
		else if (Fake[j])a[i].fake++;
	}
	LL ans=0;
	sort(a+1,a+1+n,cmp1);
	js[0]=js[1]=1;
	fo(i,2,n)js[i]=js[i-1]*i%mo;
	inv[0]=inv[1]=1;
	fo(i,2,n)inv[i]=1ll*(mo-mo/i)*inv[mo%i]%mo;
	fo(i,2,n)inv[i]=inv[i]*inv[i-1]%mo;
	fo(i,1,n){
		int p=0,q=0;
		fo(j,i+1,n)
		if (a[j].real>a[i].real+a[i].fake)p++;else q++;
		fo(x,max(0,p+B-A),min(p,B-1))ans=(ans+calc(q,B-1-x)*calc(p,x)%mo)%mo;
	}
	cout<<ans<<endl;
	return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <ctype.h>
#include <deque>
#include <queue>
#include <cstring>
#include <set>
#include <list>
#include <map>
#include <random>
#include <unordered_map>
#include <stdio.h>

using namespace std;

typedef long long ll;
typedef std::vector<int> vi;
typedef std::vector<bool> vb;
typedef std::vector<string> vs;
typedef std::vector<double> vd;
typedef std::vector<long long> vll;
typedef std::vector<std::vector<int> > vvi;
typedef vector<vvi> vvvi;
typedef vector<vll> vvll;
typedef std::vector<std::pair<int, int> > vpi;
typedef vector<vpi> vvpi;
typedef std::pair<int, int> pi;
typedef std::pair<ll, ll> pll;
typedef std::vector<pll> vpll;

const long long mod = 1000000007;

#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define forn(i, a, b) for(int i = a; i < b; i++)

#define pb push_back
#define mp make_pair

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);
}

vvll cnk(5001, vll(5001, 0));
//vvi g,gr;
//vpi e;

char g[5000][5000];
char reach[5000][5000];
//char has[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;
    forn(u,0,n) 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 (size_t i=0; i<gr[v].size(); ++i)
    forn(u,0,n) if(g[u][v])
        if (!used[ u ])
            dfs2 (u);
}

vi ss;
vs 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);
            forn(j,0,component.size() - 1) {
                int a = component[j];
                int b = component[j+1];
                union_sets(a, b);
            }
            component.clear();
        }
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif
    forn(i,0,5001) cnk[i][0] = 1;
    forn(i,1,5001) {
        forn(j,1,min(i+1,5001)) {
            cnk[i][j] = (cnk[i-1][j] + cnk[i-1][j-1])%mod;
        }
    }

    scanf("%d %d %d\n", &n, &a, &b);
//    g.resize(n);
//    gr.resize(n);
    forn(i,0,n) make_set(i);
    forn(i,0,n) {
//        string s;
        char c[5001];
        scanf("%s", c);
        string s(c);
//        getline(cin, s);
        forn(j,0,n) {
            if(s[j] == '1') {
                g[i][j] = 1;
//                g[i].pb(j);
//                gr[j].pb(i);
//                e.pb(mp(i,j));
            }
        }
    }
    cond();
    vi grp;
    ss.resize(n);
    s.resize(n);
    char c[2000001];
    forn(i,0,n) {
//        scanf("%d ", &ss[i]);
//        getline(cin, s[i]);
        scanf("%d %s", &ss[i], c);
        s[i] = string(c);
//        char c;

        for(auto & c : s[i]) if(c=='0') c= '1'; else c='0';
//        cout<<s[i]<<'|'<<endl;
    }
//    if(n==5000) {
//        cout<<"GG";
//        return 0;
//    }
    vvi ns(n);
    forn(i,0,n) {
        if(lst[i].size() > 0) {
            grp.pb(i);
            int d = 0;
            for(auto v : lst[i]) {
                d = gcd(d, ss[v]);
            }
            ns[i] = vi(d,0);
            for(auto v : lst[i]) {
                forn(j, 0, ss[v]) {
                    if (s[v][j] == '0') ns[i][j%d] = 1;
                }
            }
        }
    }
//    set<pi> ced;
//    vvi has(n, vi(n,0));
    vvi dout(n);
    vi din(n,0);
//    for(auto x : e) {
    forn(i,0,n) forn(j,0,n) {
        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].pb(b);
//            has[a][b] = 1;
            forn(k,0,n) {
                reach[a][k] |= reach[b][k];
            }
            reach[a][b] = 1;
        }
    }
    vi done(n,0);
    int did = 0;
    while(did < n) {
        forn(i,0,n) {
            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);
                    forn(res,0,d) {
                        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++;
            }
        }
    }
    forn(i,0,n) {
        int host = find_set(i);
        int d = ns[host].size();
        forn(j,0,ss[i]) {
            if(s[i][j] == '1' && ns[host][j%d] == 1) s[i][j] = '2';
        }
    }
    vi amx, amn;
    forn(i,0,n) {
        int mn = 0;
        int mx = 0;
        for(auto c : s[i]) {
            if(c == '0') mn++;
            else if(c=='2') mx++;
        }
        mx += mn;
        amx.pb(mx);
        amn.pb(mn);
//        cout<<s[i]<<' '<<mn<<' '<<mx<<endl;
    }
    sort(all(amx));
    sort(all(amn));
    reverse(all(amx));
    reverse(all(amn));
    ll ans = 0;
    int pt = 0;
    forn(i,0,n) {
        int cur = amx[i];
        while(amn[pt] > cur) pt++;
//        cout << pt <<' '<<i-pt << endl;
        forn(x, max(pt+b-a, 0), min(b,pt+1)) {
            ans = (ans + cnk[pt][x] * cnk[i-pt][b-1-x]) % mod;
        }
    }
    cout<<ans;

}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 4e6 + 5, MAXE = 5005 * 5005 >> 1;

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], mn[MAXN], mx[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
		GBeg[tot] = siz;
		siz += 2 * G[tot];
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	scanf( "%d %d %d", &N, &A, &B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		scanf( "%d", &s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, mn[i] += d;
	}
	init( siz + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		mx[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( mn[j] > mx[i] ) cnt1 ++;
				else if( mx[j] > mx[i] || ( mx[j] == mx[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = MIN( B, MIN( A - 1 - cnt1, cnt2 ) ) ; j + cnt1 + 1 >= B ; -- j )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	printf( "%d\n", ans );
	return 0;
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 5005 + 5, MAXE = 5005 * 5005 >> 1;

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], mn[MAXN], mx[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
		GBeg[tot] = siz;
		siz += 2 * G[tot];
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	scanf( "%d %d %d", &N, &A, &B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		scanf( "%d", &s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, mn[i] += d;
	}
	init( N + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		mx[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( mn[j] > mx[i] ) cnt1 ++;
				else if( mx[j] > mx[i] || ( mx[j] == mx[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = MIN( B, MIN( A - 1 - cnt1, cnt2 ) ) ; j + cnt1 + 1 >= B ; -- j )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	printf( "%d\n", ans );
	return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <list>
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll 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;
	REP(to,n) 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];
		}
	}
	//printf("%d: lid=%d id=%d\n",at,lid[at],id[at]);
	if(lid[at]>=id[at]) {
		//REP(i,nstck) printf(" %d",stck[i]); puts("");
		compnodes[ncomp].clear();
		while(comp[at]==-1) comp[stck[--nstck]]=ncomp,compnodes[ncomp].PB(stck[nstck]); ++ncomp;
	}
}
void dfstop(int c) {
	done[c]=true;
	REPSZ(i,compnodes[c]) {
		int at=compnodes[c][i];
		REP(to,n) if(g[at][to]=='1'&&!done[comp[to]]) dfstop(comp[to]);
	}
	top[ntop++]=c;
}

void run() {
	scanf("%d%d%d",&n,&A,&B);
	REP(i,n) scanf("%s",g[i]);
	off[0]=0; REP(i,n) { scanf("%d%s",&cnt[i],s+off[i]); off[i+1]=off[i]+cnt[i]; }

	REP(i,n) comp[i]=id[i]=-1; nid=nstck=ncomp=0;
	REP(i,n) if(comp[i]==-1) tarjan(i);
	ntop=0; REP(i,ncomp) done[i]=false; REP(i,ncomp) if(!done[i]) dfstop(i); assert(ntop==ncomp); reverse(top,top+ntop);
	//REP(i,ncomp) { int c=top[i]; printf("%d:",c); REPSZ(j,compnodes[c]) printf(" %d",compnodes[c][j]+1); puts(""); }

	REP(i,ncomp) { int c=top[i]; int g=0; REPSZ(j,compnodes[c]) { int at=compnodes[c][j]; g=gcd(g,cnt[at]); } gcomp[c]=g; }
	REP(i,ncomp) {
		int c=top[i];
		{
			int g=gcomp[c];
			REP(i,g) have[i]=false; REPSZ(j,compnodes[c]) { int at=compnodes[c][j]; REP(k,cnt[at]) if(s[off[at]+k]!='0') have[k%g]=true; }
			REPSZ(j,compnodes[c]) { int at=compnodes[c][j]; REP(k,cnt[at]) 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]);
			REP(i,g) have[i]=false; REPSZ(j,compnodes[c]) { int at=compnodes[c][j]; REP(k,cnt[at]) if(s[off[at]+k]!='0') have[k%g]=true; }
			REPSZ(j,compnodes[nc]) { int at=compnodes[nc][j]; REP(k,cnt[at]) if(s[off[at]+k]=='0'&&have[k%g]) s[off[at]+k]='F'; }
		}
	}
	//REP(i,n) { if(i!=0) printf("|"); REP(j,cnt[i]) printf("%c",s[off[i]+j]); } puts("");

	REPE(i,n) { C[i][0]=C[i][i]=1; FOR(j,1,i) if((C[i][j]=C[i-1][j-1]+C[i-1][j])>=MOD) C[i][j]-=MOD; }
	REP(i,n) { mn[i]=mx[i]=0; REP(j,cnt[i]) if(s[off[i]+j]=='1') ++mn[i],++mx[i]; else if(s[off[i]+j]=='F') ++mx[i]; }
	REP(i,n) o[i]=MP(-mx[i],i); sort(o,o+n); REP(i,n) o[i].first=-o[i].first;
	q=priority_queue<int>(); int nopt=0,nalways=0;
	int ret=0;
	REP(i,n) {
		int at=o[i].second;
		while(SZ(q)>0&&q.top()>mx[at]) --nopt,++nalways,q.pop();
		if(nalways<A&&nalways+nopt>=B-1) {
			FORE(j,max(0,B-1-nalways),min(min(B-1,nopt),A-1-nalways)) ret=(ret+(ll)C[nopt][j]*C[nalways][B-1-j])%MOD;
		}
		++nopt; q.push(mn[at]);
	}
	printf("%d\n",ret);
}

int main() {
	run();
	return 0;
}

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define pb push_back
#define SZ(x) ((int)x.size())
using namespace std;

const int maxn = 5100;
const int maxc = 2100000;

int n,A,B;
int s[maxn],Real[maxn],mx[maxn],mn[maxn];
vector<int>c[maxn];

namespace Task1
{
	inline void down(int &a,const int &b){if(a>b)a=b;}
	inline int gcd(int a,int b){return !a?b:gcd(b%a,a);}

	struct edge{int y,nex;}a[maxn*maxn]; int len,fir[maxn];
	inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;}

	int dfn[maxn],low[maxn],id;
	int bel[maxn],g[maxn],cnt;
	vector<int>V[maxn];
	int t[maxc],insta[maxn],tp;
	void tarjan(const int x)
	{
		dfn[x]=low[x]=++id; insta[t[++tp]=x]=1;
		for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y)
		{
			if(!dfn[y]) tarjan(y),down(low[x],low[y]);
			else if(insta[y]) down(low[x],dfn[y]);
		}
		if(dfn[x]==low[x])
		{
			g[++cnt]=0;
			int la=0;
			while(la!=x)
			{
				insta[la=t[tp--]]=0;
				V[bel[la]=cnt].pb(la);
				g[cnt]=gcd(g[cnt],s[la]);
			}
		}
	}
	vector<int>scc[maxn];
	vector<int>E[maxn];
	queue<int>q; int ind[maxn];
	void Solve()
	{
		for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
		for(int i=1;i<=cnt;i++)
		{
			for(int j=0;j<g[i];j++) t[j]=0;
			for(int j=0;j<SZ(V[i]);j++)
			{
				int x=V[i][j];
				for(int k=0;k<s[x];k++) t[k%g[i]]|=c[x][k];
			}
			for(int j=0;j<g[i];j++) scc[i].pb(t[j]);
		}

		for(int x=1;x<=n;x++)
		{
			for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(bel[y]!=bel[x])
				ind[bel[y]]++,E[bel[x]].pb(bel[y]);
		}
		for(int i=1;i<=cnt;i++) if(!ind[i]) q.push(i);
		int las=0;
		while(!q.empty())
		{
			int x=q.front(); q.pop();
			for(int j=0;j<SZ(E[x]);j++)
			{
				int y=E[x][j];
				ind[y]--; if(!ind[y]) q.push(y);
			}
			if(las)
			{
				int tmp=gcd(g[las],g[x]);
				for(int j=0;j<tmp;j++) t[j]=0;
				for(int j=0;j<g[las];j++) t[j%tmp]|=scc[las][j];
				for(int j=0;j<g[x];j++) scc[x][j]|=t[j%tmp];
			}
			las=x;
		}

		for(int i=1;i<=n;i++)
		{
			mx[i]=mn[i]=Real[i];
			for(int j=0;j<s[i];j++) if(!c[i][j]&&scc[bel[i]][j%g[bel[i]]])
				mx[i]++;
		}
	}
}
namespace Task2
{
	const int mod = 1e9+7;
	inline void add(int &a,const int &b){a+=b;if(a>=mod)a-=mod;}

	int C[maxn][maxn],use[maxc];

	void Cal()
	{
		C[0][0]=1;
		for(int i=1;i<=n;i++)
		{
			C[i][0]=1;
			for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
		}

		int ans=0;
		for(int i=1;i<=n;i++) if(!use[mx[i]])
		{
			use[mx[i]]=1;
			int sx=0,sn=0,sa=0;
			for(int j=1;j<=n;j++)
			{
				if(mn[j]>mx[i]) sn++;
				else if(mx[j]>mx[i]) sx++;
				else if(mx[j]==mx[i]) sa++;
			}
			for(int j=0;j<=sn;j++)
			{
				if(sn+B-j>A) continue;
				for(int k=1;k<=sa&&j+k<=B;k++)
				{
					int oth=B-j-k;
					add(ans,(ll)C[sn][j]*C[sx][oth]%mod*C[sa][k]%mod);
				}
			}
		}
		printf("%d\n",ans);
		return;
	}
}
char str[maxc];

int main()
{
	//freopen("tmp.in","r",stdin);
	//freopen("tmp.out","w",stdout);

	scanf("%d%d%d",&n,&A,&B);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str);
		for(int j=1;j<=n;j++) if(str[j-1]=='1') Task1::ins(i,j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
		scanf("%s",str);
		for(int j=0;j<s[i];j++)
		{
			int tc=str[j]-'0';
			Real[i]+=tc,c[i].pb(tc);
		}
	}

	Task1::Solve();

	Task2::Cal();

	return 0;
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) ((a)=(a)|(b))
#define cs const int &
const int N=5e3+10,M=2e6+10,MOD=1e9+7;

inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}

bool debug;
int n,A,B,ndfn,nscc;
char str[M];
bool instk[N];
vector<bool> bag[N],fbag[N];
stack<int> stk;
int fac[N],ifac[N],siz[N],fsiz[N],dfn[N],low[N],scc[N],mn[N],mx[N],tbag[M],fcnt[N];

struct GRPAH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

inline int Comb(cs a,cs b){return (a<0 || b<0 || a>b)? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<N;i++) fac[i]=Mul(fac[i-1],i);
	ifac[N-1]=Pow(fac[N-1],MOD-2);for(int i=N-2;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
void Input(){
	scanf("%d%d%d",&n,&A,&B);
	for(int i=1;i<=n;i++){
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		scanf("%d%s",&siz[i],str);
		if(siz[1]==831484) debug=true;
		for(int j=0;j<siz[i];j++){
			bag[i].push_back(str[j]-'0');
			mn[i]+=str[j]-'0';
		}
	}
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true,stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		int tmp=0;nscc++;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]);
	}
}
void PartGraph(){
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int tsiz=GCD(fsiz[i],fsiz[i-1]);
		int u=i,v=i-1;
		for(int j=0;j<tsiz;j++) tbag[j]=0;
		for(int j=0;j<fsiz[u];j++) upd(tbag[j%tsiz],fbag[u][j]);
		for(int j=0;j<fsiz[v];j++) upd(fbag[v][j],tbag[j%tsiz]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=siz[i]/fsiz[scc[i]]*fcnt[scc[i]];
}
int PartMath(){
	int ans=0;
	for(int i=1;i<=n;i++){
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mx[i]<mn[j]) mus++;
			else if(mx[i]<mx[j] || (mx[i]==mx[j] && i<j)) may++;
		}
		if(mus>=A) continue;
		for(int j=min(B,min(A-1-mus,may));j+mus+1>=B;j--)
			ans=Add(ans,Mul(Comb(j,may),Comb(B-1-j,mus)));
	}
	return ans;
}
int main(){
	Init();
	Input();
	PartGraph();
	printf("%d\n",PartMath());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2e6+10;
const int mod=1e9+7;
typedef pair<int,int> pii;
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define real xzzakhnoi2020

int n,a,b,C[N][N],deg[N],id[N],vis[M],tim,real[N],all[N];
string s[N];
pii p[N];
char E[N];
bool new_scc[N];

int main() {
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>a>>b;
	for(int i=0;i<N;i++) {
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
	}
	for(int i=1,len;i<=n;i++) {
		cin>>(E+1);
		for(int j=1;j<=n;j++) deg[i]+=(E[j]=='1');
	}
	for(int i=1,len;i<=n;i++) {
		cin>>len>>s[i],id[i]=i;
		for(auto c:s[i]) if(c=='1') ++real[i];
	}
	sort(id+1,id+n+1,[&](int a,int b) { return deg[a]>deg[b]; });
	for(int i=n,sdeg=0;i;i--) {
		sdeg+=deg[id[i]];
		if(sdeg==(n-i+1)*(n-i)/2) new_scc[i]=1;
	}
	for(int i=1,j;i<=n;i=j+1) {
		j=i;while(j<n&&!new_scc[j+1]) ++j;
		int gg=0;
		for(int k=i;k<=j;k++) gg=__gcd(gg,sz(s[id[k]]));
		++tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(s[id[k]][l]=='1') vis[l%gg]=tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(vis[l%gg]==tim) s[id[k]][l]='1';
		if(j<n) {
			gg=__gcd(sz(s[id[j]]),sz(s[id[j+1]]));
			++tim;
			for(int l=0;l<sz(s[id[j]]);l++) if(s[id[j]][l]=='1') vis[l%gg]=tim;
			for(int l=0;l<sz(s[id[j+1]]);l++) if(vis[l%gg]) s[id[j+1]][l]='1';
		}
	}
	for(int i=1;i<=n;i++) {
		for(auto c:s[i]) if(c=='1') ++all[i];
		p[i]=mp(real[i],all[i]);
		//cerr<<p[i].fi<<' '<<p[i].se<<endl;
	}
	sort(p+1,p+n+1,[&](pii a,pii b) { return a.se<b.se; });
	int ans=0;
	for(int i=1;i<=n;i++) {
		int cntl=0,cntr=0;
		for(int j=1;j<i;j++) if(p[j].fi>p[i].se) ++cntl;
		for(int j=i+1;j<=n;j++) if(p[j].fi>p[i].se) ++cntr;
		//cerr<<i<<' '<<cntl<<' '<<cntr<<endl;
		if(cntl>a-b) continue;
		for(int j=max(0,cntr-a+b+cntl);j<=cntr&&j<b;j++)
			ans=(ans+1ll*C[cntr][j]*C[n-i-cntr][b-1-j])%mod;
		//cerr<<i<<' '<<ans<<endl;
	}
	cout<<ans;
	return 0;
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <queue>
using namespace std;
#define mod 1000000007

struct Edge
{
       long long to,next;
}      e[13000050];

long long now,tp,times,tot,alls,sk[100050],first[100050],dfs[100050],dfn[100050],low[100050],size[100050];
long long c[5050][5050],s[100050],mini[100050],maxi[100050];
long long belong[100050],d[100050],g[100050],all[100050],sum[2000050];
bool vis[10050];
char st[2000050];
pair <long long,long long> pa[100050];
vector <long long> scc[100050],vec[100050],f[100050];

long long  Gcd(long long a,long long b)
{
     if  (a%b==0) return b;
     return Gcd(b,a%b);
}

void Add(long long x,long long y)
{
     e[++now].to=y;
     e[now].next=first[x];
     first[x]=now;
}

void DFS(long long x)
{
long long  pt,next;
     sk[++tp]=x;
     dfs[x]=1;
     dfn[x]=low[x]=++times;
     for (pt=first[x];pt;pt=e[pt].next)
     {
         next=e[pt].to;
         if  (dfs[next]==2) continue;
         if  (dfs[next]==0) DFS(next);
         low[x]=min(low[x],low[next]);
     }
     dfs[x]=2;
     if  (dfn[x]==low[x])
     {
         tot++;
         for (;tp&&sk[tp]!=x;tp--) scc[tot].push_back(sk[tp]);
         if  (tp) tp--;
         scc[tot].push_back(x);
         size[tot]=scc[tot].size();
     }
}

long long  C(long long x,long long y)
{
     if  (x<0||y<0||x<y) return 0;
     return c[x][y];
}

int  main()
{
long long  n,a,b,i,j,k,pt,next,cur,gcd,mins,maxs,ans,sc,sn,p,q,t;
vector <long long> temp;

     //freopen("f.in", "r", stdin);
     //freopen("f.out", "w", stdout);

     scanf("%lld%lld%lld",&n,&a,&b);
     for (i=1;i<=n;i++)
     {
         scanf("%s",st+1);
         for (j=1;j<=n;j++)
         if  (st[j]=='1') Add(i,j);
     }
     for (i=1;i<=n;i++)
     {
         scanf("%lld%s",&s[i],st+1);
         for (j=1;j<=s[i];j++)
         {
             vec[i].push_back(st[j]-'0');
             mini[i]+=st[j]-'0';
         }
     }
     for (i=1;i<=n;i++)
     if  (!dfs[i]) DFS(i);
     for (i=1;i<=tot;i++)
     {
         gcd=-1;
         for (j=0;j<size[i];j++)
         if  (gcd==-1) gcd=s[scc[i][j]]; else gcd=Gcd(gcd,s[scc[i][j]]);
         for (j=0;j<gcd;j++) f[i].push_back(0);
         for (j=0;j<size[i];j++)
         {
             for (k=0;k<s[scc[i][j]];k++)
             if  (f[i][k%gcd]==0&&vec[scc[i][j]][k]==1) f[i][k%gcd]=1;
         }
         g[i]=gcd;
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++) belong[scc[i][j]]=i;
     for (i=1;i<=n;i++)
         for (pt=first[i];pt;pt=e[pt].next)
         {
             next=e[pt].to;
             if  (belong[i]==belong[next]) continue;
             d[belong[next]]++;
         }
     for (i=1;i<=tot;i++)
     {
         for (j=1;j<=tot;j++)
         if  (!vis[j]&&d[j]==0)
         {
             vis[j]=true;
             break;
         }
         all[++alls]=j;
         for (k=0;k<size[j];k++)
             for (pt=first[scc[j][k]];pt;pt=e[pt].next)
             {
                 next=e[pt].to;
                 if  (belong[next]==j) continue;
                 d[belong[next]]--;
             }
     }
     for (i=1;i<alls;i++)
     {
         cur=all[i];
         next=all[i+1];
         sc=f[cur].size();
         sn=f[next].size();
         gcd=Gcd(sc,sn);
         temp.clear();
         for (j=0;j<gcd;j++) temp.push_back(0);
         for (j=0;j<sc;j++)
         if  (f[cur][j]==1&&temp[j%gcd]==0) temp[j%gcd]=1;
         for (j=0;j<sn;j++) f[next][j]|=temp[j%gcd];
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++)
             for (k=0;k<s[scc[i][j]];k++) maxi[scc[i][j]]+=f[i][k%g[i]];
     c[0][0]=1;
     for (i=1;i<=n;i++)
     {
         c[i][0]=c[i][i]=1;
         c[i][1]=i;
     }
     for (i=3;i<=n;i++)
         for (j=2;j<n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
     for (i=1;i<=n;i++)
     {
         pa[2*i-1]=make_pair(mini[i],0);
         pa[2*i]=make_pair(maxi[i],1);
     }
     sort(pa+1,pa+2*n+1);
     mins=maxs=ans=0;
     for (i=2*n;i>=1;i--)
     if  (pa[i].second==1)
     {
         t=mins;
         p=maxs-sum[pa[i].first]-t;
         q=sum[pa[i].first];
         for (j=0;j<=p+q&&j+t<a;j++) ans=(ans+1ll*C(p+q,j)*C(t,b-j-1)%mod)%mod;
         maxs++;
         sum[pa[i].first]++;
     }   else mins++;
     printf("%lld\n",ans);

     return 0;
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <queue>
using namespace std;
#define mod 1000000007

struct Edge
{
       long long to,next;
}      e[13000050];

long long now,tp,times,tot,alls,sk[100050],first[100050],dfs[100050],dfn[100050],low[100050],size[100050];
long long c[5050][5050],s[100050],mini[100050],maxi[100050];
long long belong[100050],d[100050],g[100050],all[100050],sum[2000050];
bool vis[10050];
char st[2000050];
pair <long long,long long> pa[100050];
vector <long long> scc[100050],vec[100050],f[100050];

long long  Gcd(long long a,long long b)
{
     if  (a%b==0) return b;
     return Gcd(b,a%b);
}

void Add(long long x,long long y)
{
     e[++now].to=y;
     e[now].next=first[x];
     first[x]=now;
}

void DFS(long long x)
{
long long  pt,next;
     sk[++tp]=x;
     dfs[x]=1;
     dfn[x]=low[x]=++times;
     for (pt=first[x];pt;pt=e[pt].next)
     {
         next=e[pt].to;
         if  (dfs[next]==2) continue;
         if  (dfs[next]==0) DFS(next);
         low[x]=min(low[x],low[next]);
     }
     dfs[x]=2;
     if  (dfn[x]==low[x])
     {
         tot++;
         for (;tp&&sk[tp]!=x;tp--) scc[tot].push_back(sk[tp]);
         if  (tp) tp--;
         scc[tot].push_back(x);
         size[tot]=scc[tot].size();
     }
}

long long  C(long long x,long long y)
{
     if  (x<0||y<0||x<y) return 0;
     return c[x][y];
}

int  main()
{
long long  n,a,b,i,j,k,pt,next,cur,gcd,mins,maxs,ans,sc,sn,p,q,t;
vector <long long> temp;

     //freopen("f.in", "r", stdin);
     //freopen("f.out", "w", stdout);
     int ttt=1234;

     scanf("%lld%lld%lld",&n,&a,&b);
     for (i=1;i<=n;i++)
     {
         scanf("%s",st+1);
         for (j=1;j<=n;j++)
         if  (st[j]=='1') Add(i,j);
     }
     for (i=1;i<=n;i++)
     {
         scanf("%lld%s",&s[i],st+1);
         for (j=1;j<=s[i];j++)
         {
             vec[i].push_back(st[j]-'0');
             mini[i]+=st[j]-'0';
         }
     }
     for (i=1;i<=n;i++)
     if  (!dfs[i]) DFS(i);
     for (i=1;i<=tot;i++)
     {
         gcd=-1;
         for (j=0;j<size[i];j++)
         if  (gcd==-1) gcd=s[scc[i][j]]; else gcd=Gcd(gcd,s[scc[i][j]]);
         for (j=0;j<gcd;j++) f[i].push_back(0);
         for (j=0;j<size[i];j++)
         {
             for (k=0;k<s[scc[i][j]];k++)
             if  (f[i][k%gcd]==0&&vec[scc[i][j]][k]==1) f[i][k%gcd]=1;
         }
         g[i]=gcd;
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++) belong[scc[i][j]]=i;
     for (i=1;i<=n;i++)
         for (pt=first[i];pt;pt=e[pt].next)
         {
             next=e[pt].to;
             if  (belong[i]==belong[next]) continue;
             d[belong[next]]++;
         }
     for (i=1;i<=tot;i++)
     {
         for (j=1;j<=tot;j++)
         if  (!vis[j]&&d[j]==0)
         {
             vis[j]=true;
             break;
         }
         all[++alls]=j;
         for (k=0;k<size[j];k++)
             for (pt=first[scc[j][k]];pt;pt=e[pt].next)
             {
                 next=e[pt].to;
                 if  (belong[next]==j) continue;
                 d[belong[next]]--;
             }
     }
     for (i=1;i<alls;i++)
     {
         cur=all[i];
         next=all[i+1];
         sc=f[cur].size();
         sn=f[next].size();
         gcd=Gcd(sc,sn);
         temp.clear();
         for (j=0;j<gcd;j++) temp.push_back(0);
         for (j=0;j<sc;j++)
         if  (f[cur][j]==1&&temp[j%gcd]==0) temp[j%gcd]=1;
         for (j=0;j<sn;j++) f[next][j]|=temp[j%gcd];
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++)
             for (k=0;k<s[scc[i][j]];k++) maxi[scc[i][j]]+=f[i][k%g[i]];
     c[0][0]=1;
     for (i=1;i<=n;i++)
     {
         c[i][0]=c[i][i]=1;
         c[i][1]=i;
     }
     for (i=3;i<=n;i++)
         for (j=2;j<n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
     for (i=1;i<=n;i++)
     {
         pa[2*i-1]=make_pair(mini[i],0);
         pa[2*i]=make_pair(maxi[i],1);
     }
     sort(pa+1,pa+2*n+1);
     mins=maxs=ans=0;
     for (i=2*n;i>=1;i--)
     if  (pa[i].second==1)
     {
         t=mins;
         p=maxs-sum[pa[i].first]-t;
         q=sum[pa[i].first];
         for (j=0;j<=p+q&&j+t<a;j++) ans=(ans+1ll*C(p+q,j)*C(t,b-j-1)%mod)%mod;
         maxs++;
         sum[pa[i].first]++;
     }   else mins++;
     printf("%lld\n",ans);

     return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n,a,b,c;
char str[MAXL+5];
vector<int> G[MAXN+5];
vector<int> per[MAXN+5];
int siz[MAXN+5],dfn[MAXN+5],low[MAXN+5],dcnt;
int blo[MAXN+5],bgcd[MAXN+5],blocnt;
int stk[MAXN+5],t;
int num[MAXN+5],mx[MAXN+5],mn[MAXN+5];
bool instk[MAXN+5];
int fact[MAXN+5],inv[MAXN+5];
int PowMod(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret=1LL*ret*x%MO;
		x=1LL*x*x%MO;
		y>>=1;
	}
	return ret;
}
int gcd(int x,int y)
{
	if(y==0)
		return x;
	return gcd(y,x%y);
}
void InPut()
{
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				G[i].push_back(j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		per[i].resize(siz[i]+1);
		scanf("%s",str);
		for(int j=0;j<siz[i];j++)
			if(str[j]=='1')
				per[i][j]=1;
			else if(str[j]=='0')
				per[i][j]=0;
	}
}
void Tarjan(int u,int fa)
{
	dfn[u]=low[u]=++dcnt;
	instk[u]=true;stk[t++]=u;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(dfn[v]==0)
		{
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]==true)
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int fro=0;blocnt++;
		do
		{
			fro=stk[--t];instk[fro]=false;
			blo[fro]=blocnt;
			bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
		}while(fro!=u);
	}
}
void Part1()
{
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			Tarjan(i,-1);
	for(int i=1;i<=blocnt;i++)
		per[i+n].resize(bgcd[i]+1);//预先设定大小
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];//存到虚拟黑帮中
	int nw;
	for(int i=blocnt;i>1;i--)//自然形成了哈密顿路径
	{
		nw=gcd(bgcd[i],bgcd[i-1]);//当前的剩余系
		for(int j=0;j<bgcd[i];j++)
			if(per[i+n][j])
			{
				per[i-1+n][j%nw]|=1;//对下一个点进行更新
				num[i]++;//num就是总的金条数
			}
	}
	for(int j=0;j<bgcd[1];j++)
		num[1]+=per[1+n][j];//记得一定要统计block1的值
	for(int i=1;i<=n;i++)
	{
		mx[i]=mn[i]=0;
		mx[i]=1LL*num[blo[i]]*siz[i]/bgcd[blo[i]];//根据性质三进行还原
		for(int j=0;j<siz[i];j++)
			mn[i]+=per[i][j];//直接利用初始信息算
	}
}
void Prepare()
{
	fact[0]=1;
	for(int i=1;i<=MAXN;i++)
		fact[i]=1LL*fact[i-1]*i%MO;
	inv[MAXN]=PowMod(fact[MAXN],MO-2);
	for(int i=MAXN-1;i>=0;i--)
		inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%MO;
}
inline int C(int x,int y)
{
	return 1LL*fact[x]*inv[y]%MO*inv[x-y]%MO;
}
int Part2()
{
	Prepare();
	int cnt1=0,cnt2=0,ret=0;
	for(int i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i!=j&&mn[j]>mx[i])
				cnt1++;
			if(i!=j&&mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)))//避免重复
				cnt2++;
		}
		if(cnt1>a-1)
			continue;
		for(int j=min(b,min(a-1-cnt1,cnt2));j>=0&&j+1+cnt1>=b;j--)//一堆限制
			ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%MO)%MO;
	}
	return ret;
}
int main()
{
	InPut();
	Part1();
	int ans=Part2();
	printf("%d\n",ans);
	return 0;
}//hello

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		   inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
	}
	return printf( "%d\n", ans ), 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define forn(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
typedef pair<int,int> pii;
typedef vector<pii> vpi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;

int n, A, B;
vi s;
vvb adj,g,f;

int cnt;
vi post;
vb vis;
vector<vi> scc;
vi prz;
vi nwd;
vvb ad;

vi sum;
vpi wid;

void read()
{
	scanf("%d %d %d", &n, &A, &B);
	adj.resize(n);
	char c[5001];
	rep(i,n)
	{
		scanf("%s", c);
		string ss(c);
		adj[i].resize(n,0);
		rep(j,n)
		{
			adj[i][j] = (ss[j] == '1');
		}
	}
	s.resize(n);
	g.resize(n);
	wid.resize(n);
	char cc[2000001];
	rep(i,n)
	{
		wid[i].st = 0;
		scanf("%d", &s[i]);
		scanf("%s", cc);
		string ss(cc);
		g[i].resize(s[i],0);
		rep(j,s[i])
		{
			g[i][j]=(ss[j] == '1');
			wid[i].st += g[i][j];
		}
	}
}

void write()
{
	/*
	cout<<n<<" "<<A<<" "<<B<<"\n";
	rep(i,n)
	{
		rep(j,n) cout<<adj[i][j];
		cout<<"\n";
	}
	rep(i,n)
	{
		cout<<s[i]<<" ";
		rep(j,s[i]) cout<<g[i][j];
		cout<<"\n";
	}
	*/
}

void dfs(int u)
{
	vis[u] = 1;
	rep(i,n) if(!vis[i] && adj[u][i]) dfs(i);
	post.pb(u);
}

void dfsutil(int u)
{
	vis[u] = 1;
	scc[cnt].pb(u);
	prz[u] = cnt;
	rep(i,n) if(!vis[i] && adj[i][u]) dfsutil(i);
}

void scc_topsort()
{
	prz.resize(n);
	vis.resize(n,0);
	rep(i,n) if(!vis[i]) dfs(i);
	vis.clear();
	vis.resize(n,0);
	ford(i,n-1,0) if(!vis[post[i]])
	{
		vi new_scc;
		scc.pb(new_scc);
		dfsutil(post[i]);
		++cnt;
	}
}

int gcd(int a, int b){return b ? gcd(b,a%b) : a;}

void propagate(int a, int b)
{
	//cout<<a<<" "<<b<<" <- prop\n";
	int gc = gcd(nwd[a],nwd[b]);
	vb nw(gc,0);
	rep(i,nwd[a]) if(f[a][i]) nw[i%gc] = 1;
	//rep(i,gc) cout<<i<<": "<<nw[i]<<"\t";
	//cout<<"\n";
	rep(i,gc) if(nw[i]) rep(j,nwd[b]/gc) f[b][j*gc+i] = 1;
}

void gcds()
{
	nwd.resize(cnt);
	rep(i,cnt)
	{
		nwd[i] = s[scc[i][0]];
		forn(j,1,scc[i].size()-1) nwd[i] = gcd(nwd[i], s[scc[i][j]]);
	}
	f.resize(cnt);
	//ad.resize(cnt);
	rep(i,cnt)
	{
		f[i].resize(nwd[i], 0);
		//ad[i].resize(cnt,0);
		rep(j,scc[i].size())
		{
			int v = scc[i][j];
			//rep(k,n) if(adj[v][k]) ad[i][prz[k]] = 1;
			rep(k,s[v]) if(g[v][k]) f[i][k%nwd[i]] = 1;
		}
	}
	forn(i,0,cnt-2) propagate(i,i+1);
}

vi tt0, tt1, counter1, counter2;
const ll maxval = 2e6;
const ll mod = 1e9+7;
vector<vector<ll> > binnom;

void pascal()
{
	binnom.resize(n+1);
	rep(i,n+1) binnom[i].resize(n+1,0);
	binnom[0][0] = 1;
	forn(i,1,n)
	{
		binnom[i][0]=1;
		binnom[i][i]=1;
		forn(j,1,i-1)
		{
			binnom[i][j] = (binnom[i-1][j-1] + binnom[i-1][j]) % mod;
		}
	}
}
vi counter0;
void tops()
{
	rep(i,n)
	{
		wid[i].nd = 0;
		rep(j,nwd[prz[i]]) wid[i].nd += f[prz[i]][j];
		wid[i].nd *= (s[i] / nwd[prz[i]]);
	}

	pascal();
}

void final_answer()
{
	long long res = 0;
	//rep(i,maxval) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";
	/*
	vi mn(n), mx(n);
	rep(i,n)
	{
		mn[i] = wid[i].st;
		mx[i] = wid[i].nd;
	}
	sort(mn.begin(), mn.end());
	sort(mx.begin(), mx.end());
	reverse(mn.begin(), mn.end());
	reverse(mx.begin(), mx.end());
	int nc = 0;
	for(int i=0; i<n; ++i)
	{
		int value = mx[i];
		while(mn[nc] > value) nc++;
		forn(j, max(nc+B-A,0), min(B-1, nc))
		{
			res = (res + binnom[nc][j] * binnom[i-nc][B-1-j]) % mod;
		}
	}
	*/

	counter0.resize(maxval+2,0);
	counter1.resize(maxval+2,0);

	rep(i,n)
	{
		counter0[wid[i].nd]++;
		counter1[wid[i].st]++;
		counter1[wid[i].nd]--;
	}
	int curr_cnt = 0;
	forn(i,0,maxval)
	{
		curr_cnt += counter1[i];
		counter1[i] = curr_cnt;
	}
	counter2.resize(maxval+2,0);
	cnt = 0;
	sort(wid.begin(),wid.end());
	ford(i,n-1,0)
	{
		cnt++;
		if(wid[i].st == 0) break;
		counter2[wid[i].st-1] = cnt;
	}
	ford(i,maxval,0) if(counter2[i] < counter2[i+1]) counter2[i] = counter2[i+1];

	//rep(i,7) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";

	forn(i,0,maxval)
	{
		if(counter2[i]>=A) continue;
		int dif = A-counter2[i];
		forn(j,1,min(B,min(dif,counter0[i])))
		{
			//cout<<" hehe "<<i<<" "<<j<<"\n";
			//cout<<"add to res:\tbinnom["<<counter0[i]<<"]["<<j<<"]\tbinnom["<<counter2[i]+counter1[i]<<"]["<<dif-j<<"]\n";
			ll sadd = 0;
			for(int k=max(0,B-j-counter2[i]); k<=min(counter1[i],B-j); ++k) if(j+k+counter2[i]<=A)
			{
				sadd = (sadd + binnom[counter1[i]][k] * binnom[counter2[i]][B-j-k]) % mod;
				//cout<<i<<" "<<j<<" "<<k<<" "<<binnom[counter1[i]][k] * binnom[counter2[i]][B-j-k]<<"\n";
			}
			ll add = sadd * binnom[counter0[i]][j];
			res = (res + add) % mod;
			//cout<<i<<" "<<j<<":\t"<<add<<"\n";
			//res = (res + add) % mod;
		}
	}

	printf("%Ld\n", res);
}

int main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(0);
	read();
	//write();
	scc_topsort();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<":";
		rep(j,scc[i].size()) cout<<" "<<scc[i][j];
		cout<<"\n";
	}
	return 0;
	*/
	gcds();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<": "<<nwd[i]<<"\n";
	}
	//return 0;
	*/
	tops();
	//cout<<"Widelki:\n";
	//rep(i,n) cout<<i<<": <"<<wid[i].st<<", "<<wid[i].nd<<">\n";
	final_answer();
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define forn(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
typedef pair<int,int> pii;
typedef vector<pii> vpi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;

int n, A, B;
vi s;
vvb adj,g,f;

int cnt;
vi post;
vb vis;
vector<vi> scc;
vi prz;
vi nwd;
vvb ad;

vi sum;
vpi wid;

void read()
{
	scanf("%d %d %d", &n, &A, &B);
	adj.resize(n);
	char c[5001];
	rep(i,n)
	{
		scanf("%s", c);
		string ss(c);
		adj[i].resize(n,0);
		rep(j,n)
		{
			adj[i][j] = (ss[j] == '1');
		}
	}
	s.resize(n);
	g.resize(n);
	wid.resize(n);
	char cc[2000001];
	rep(i,n)
	{
		wid[i].st = 0;
		scanf("%d", &s[i]);
		scanf("%s", cc);
		string ss(cc);
		g[i].resize(s[i],0);
		rep(j,s[i])
		{
			g[i][j]=(ss[j] == '1');
			wid[i].st += g[i][j];
		}
	}
}

void write()
{
	/*
	cout<<n<<" "<<A<<" "<<B<<"\n";
	rep(i,n)
	{
		rep(j,n) cout<<adj[i][j];
		cout<<"\n";
	}
	rep(i,n)
	{
		cout<<s[i]<<" ";
		rep(j,s[i]) cout<<g[i][j];
		cout<<"\n";
	}
	*/
}

void dfs(int u)
{
	vis[u] = 1;
	rep(i,n) if(!vis[i] && adj[u][i]) dfs(i);
	post.pb(u);
}

void dfsutil(int u)
{
	vis[u] = 1;
	scc[cnt].pb(u);
	prz[u] = cnt;
	rep(i,n) if(!vis[i] && adj[i][u]) dfsutil(i);
}

void scc_topsort()
{
	prz.resize(n);
	vis.resize(n,0);
	rep(i,n) if(!vis[i]) dfs(i);
	vis.clear();
	vis.resize(n,0);
	ford(i,n-1,0) if(!vis[post[i]])
	{
		vi new_scc;
		scc.pb(new_scc);
		dfsutil(post[i]);
		++cnt;
	}
}

int gcd(int a, int b){return b ? gcd(b,a%b) : a;}

void propagate(int a, int b)
{
	//cout<<a<<" "<<b<<" <- prop\n";
	int gc = gcd(nwd[a],nwd[b]);
	vb nw(gc,0);
	rep(i,nwd[a]) if(f[a][i]) nw[i%gc] = 1;
	//rep(i,gc) cout<<i<<": "<<nw[i]<<"\t";
	//cout<<"\n";
	rep(i,gc) if(nw[i]) rep(j,nwd[b]/gc) f[b][j*gc+i] = 1;
}

void gcds()
{
	nwd.resize(cnt);
	rep(i,cnt)
	{
		nwd[i] = s[scc[i][0]];
		forn(j,1,scc[i].size()-1) nwd[i] = gcd(nwd[i], s[scc[i][j]]);
	}
	f.resize(cnt);
	//ad.resize(cnt);
	rep(i,cnt)
	{
		f[i].resize(nwd[i], 0);
		//ad[i].resize(cnt,0);
		rep(j,scc[i].size())
		{
			int v = scc[i][j];
			//rep(k,n) if(adj[v][k]) ad[i][prz[k]] = 1;
			rep(k,s[v]) if(g[v][k]) f[i][k%nwd[i]] = 1;
		}
	}
	forn(i,0,cnt-2) propagate(i,i+1);
}

vi tt0, tt1, counter1, counter2;
const ll maxval = 2e6;
const ll mod = 1e9+7;
vector<vector<ll> > binnom;

void pascal()
{
	binnom.resize(n+1);
	rep(i,n+1) binnom[i].resize(n+1,0);
	binnom[0][0] = 1;
	forn(i,1,n)
	{
		binnom[i][0]=1;
		binnom[i][i]=1;
		forn(j,1,i-1)
		{
			binnom[i][j] = (binnom[i-1][j-1] + binnom[i-1][j]) % mod;
		}
	}
}
vi counter0;
void tops()
{
	rep(i,n)
	{
		wid[i].nd = 0;
		rep(j,nwd[prz[i]]) wid[i].nd += f[prz[i]][j];
		wid[i].nd *= (s[i] / nwd[prz[i]]);
	}
	/*
	counter0.resize(maxval+2,0);
	counter1.resize(maxval+2,0);

	rep(i,n)
	{
		counter0[wid[i].nd]++;
		counter1[wid[i].st]++;
		counter1[wid[i].nd]--;
	}
	int curr_cnt = 0;
	forn(i,0,maxval)
	{
		curr_cnt += counter1[i];
		counter1[i] = curr_cnt;
	}
	counter2.resize(maxval+2,0);
	cnt = 0;
	sort(wid.begin(),wid.end());
	ford(i,n-1,0)
	{
		cnt++;
		if(wid[i].st == 0) break;
		counter2[wid[i].st-1] = cnt;
	}
	ford(i,maxval,0) if(counter2[i] < counter2[i+1]) counter2[i] = counter2[i+1];
	*/
	pascal();
}

void final_answer()
{
	long long res = 0;
	//rep(i,maxval) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";
	vi mn(n), mx(n);
	rep(i,n)
	{
		mn[i] = wid[i].st;
		mx[i] = wid[i].nd;
	}
	sort(mn.begin(), mn.end());
	sort(mx.begin(), mx.end());
	reverse(mn.begin(), mn.end());
	reverse(mx.begin(), mx.end());
	int nc = 0;
	for(int i=0; i<n; ++i)
	{
		int value = mx[i];
		while(mn[nc] > value) nc++;
		forn(j, max(nc+B-A,0), min(B-1, nc))
		{
			res = (res + binnom[nc][j] * binnom[i-nc][B-1-j]) % mod;
		}
	}
	/*
	forn(i,0,maxval)
	{
		if(counter2[i]>=A) continue;
		int dif = A-counter2[i];
		forn(j,1,min(B,min(dif,counter0[i])))
		{
			//cout<<" hehe "<<i<<" "<<j<<"\n";
			//cout<<"add to res:\tbinnom["<<counter0[i]<<"]["<<j<<"]\tbinnom["<<counter2[i]+counter1[i]<<"]["<<dif-j<<"]\n";
			res = (res + binnom[counter0[i]][j] * binnom[counter2[i]+counter1[i]][B-j]) % mod;
		}
	}
	*/
	printf("%Ld\n", res);
}

int main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(0);
	read();
	//write();
	scc_topsort();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<":";
		rep(j,scc[i].size()) cout<<" "<<scc[i][j];
		cout<<"\n";
	}
	return 0;
	*/
	gcds();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<": "<<nwd[i]<<"\n";
	}
	//return 0;
	*/
	tops();
	//cout<<"Widelki:\n";
	//rep(i,n) cout<<i<<": <"<<wid[i].st<<", "<<wid[i].nd<<">\n";
	final_answer();
	return 0;
}

#include<iostream>
#include<cstdio>
#include<vector>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=5050,M=2000200,P=1e9+7;
int n,m,u,v,ti,tp,D,A,B,X,Y,ans;
int df[N],lo[N],s[N],l[N],in[N],c[N],d[N],a[N];
int f[N][N],g[N][N],mi[N],mx[N],su[N],iv[N],fc[N],vf[N];
char S[M];
bool T[M];
vector<bool>b[N],t[N];
vector<int>ve[N];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int C(int x,int y){return x<0||y<0||x<y?0:1ll*fc[x]*vf[x-y]%P*vf[y]%P;}
void tarjan(int u){
	df[u]=lo[u]=++ti;in[s[++tp]=u]=1;
	FOR(v,1,n)if(g[u][v]){
		if(!df[v]) tarjan(v);
		if( in[v]) lo[u]=min(lo[u],lo[v]);
	}
	if(df[u]==lo[u]){
		++m;
		for(int x=0,v;v=s[tp],x!=u;x=s[tp--])
			c[v]=m,in[v]=0,d[m]=gcd(d[m],l[v]),ve[m].push_back(v);
		FOR(i,1,d[m]) t[m].push_back(0);
		for(int v:ve[m])FOR(i,0,l[v]-1) t[m][i%d[m]]=t[m][i%d[m]]|b[v][i];
	}
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&A,&B);
	iv[1]=fc[0]=vf[0]=1;
	FOR(i,2,n) iv[i]=1ll*iv[P%i]*(P-P/i)%P;
	FOR(i,1,n) fc[i]=1ll*fc[i-1]*i%P,vf[i]=1ll*vf[i-1]*iv[i]%P;
	FOR(i,1,n){
		scanf("%s",S+1);
		FOR(j,1,n) g[i][j]=S[j]=='1';
	}
	FOR(i,1,n){
		scanf("%d%s",&l[i],S+1);
		FOR(j,1,l[i]) b[i].push_back(S[j]^48),mi[i]+=S[j]^48;
	}
	FOR(i,1,n)if(!df[i]) tarjan(i);
	ROF(i,m,2){
		u=i,v=i-1;D=gcd(d[u],d[v]);
		FOR(j,0,D-1) T[j]=0;
		FOR(j,0,d[u]-1) T[j%D]|=t[u][j];
		FOR(j,0,d[v]-1) t[v][j]=t[v][j]|T[j%D];
	}
	FOR(i,1,m)for(int x:t[i]) su[i]+=x;
	FOR(i,1,n) mx[i]=l[i]/d[c[i]]*su[c[i]];
	FOR(i,1,n){
		X=Y=0;
		FOR(j,1,n)if(i!=j){
			if(mi[j]>mx[i]) X++;
			else if(mx[i]<mx[j] || (mx[i]==mx[j] && i>j)) Y++;
		}
		if(X>=A) continue;
		FOR(j,0,min(A-X-1,Y)) (ans+=1ll*C(Y,j)*C(X,B-1-j)%P)%=P;
	}
	cout<<ans<<'\n';
}

#include<bits/stdc++.h>
using namespace std;
inline int gcd(int a,int b)
{
	while(a&&b) if(a>b) a%=b;else b%=a;
	return a?a:b;
}
const int maxn=5010,mod=1000000007;
inline int ksm(int a,int b)
{
	int res=1;
	for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) res=1ll*res*a%mod;
	return res;
}
int head[maxn],nxt[maxn*maxn],ver[maxn*maxn],tot;
inline void addedge(int a,int b){nxt[++tot]=head[a];ver[tot]=b;head[a]=tot;}
int s[maxn];string str[maxn];int n,a,b;
int sccid[maxn],dfn[maxn],low[maxn],dfn_cnt,scc_cnt;
int stk[maxn],top;bool instk[maxn];vector<int> scc[maxn];
int S[maxn];string Str[maxn];
inline void tarjan(int x)
{
	dfn[x]=low[x]=++dfn_cnt;stk[++top]=x;instk[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(instk[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		scc_cnt++;int y;
		do
		{
			y=stk[top--];instk[y]=0;scc[scc_cnt].push_back(y);
			sccid[y]=scc_cnt;S[scc_cnt]=gcd(S[scc_cnt],s[y]);
		}
		while(x!=y);
	}
}
inline void init()
{
	scanf("%d%d%d",&n,&a,&b);char tmp[maxn];
	for(int i=1;i<=n;i++)
	{
		scanf("%s",tmp+1);
		for(int j=1;j<=n;j++) if(tmp[j]=='1') addedge(i,j);
	}
	for(int i=1;i<=n;i++) scanf("%d",s+i),cin>>str[i];
}
int Head[maxn],Nxt[maxn*maxn],Ver[maxn*maxn],Tot,ind[maxn];
inline void Addedge(int a,int b){Nxt[++Tot]=Head[a];Ver[Tot]=b;Head[a]=Tot;ind[b]++;}
queue<int> q;int now[maxn];int tmp[1001000];
int mx[maxn],mn[maxn];
inline void Toposort()
{
	for(int i=1;i<=scc_cnt;i++) if(ind[i]==0) q.push(i),now[i]=S[i];
	while(q.size())
	{
		int x=q.front();q.pop();
		for(int I=Head[x];I;I=Nxt[I])
		{
			int y=Ver[I];if(--ind[y]) continue;
			q.push(y);now[y]=gcd(S[y],now[x]);
			for(int i=0;i<(int)Str[x].size();i++) if(Str[x][i]=='1') tmp[i%now[y]]=1;
			for(int i=0;i<(int)Str[y].size();i++) if(tmp[i%now[y]]) Str[y][i]='1';
			for(int i=0;i<now[y];i++) tmp[i]=0;
		}
	}
	for(int i=1;i<=n;i++) for(int j=0;j<(int)str[i].size();j++) if(str[i][j]=='1') mn[i]++;
	for(int i=1;i<=scc_cnt;i++) for(int j=0;j<(int)Str[i].size();j++) if(Str[i][j]=='1') tmp[i]++;
	for(int i=1;i<=n;i++) mx[i]=1ll*tmp[sccid[i]]*s[i]/S[sccid[i]];
}
int fac[maxn],invfac[maxn];
inline int C(int n,int m){if(m<0||n<m) return 0;return 1ll*fac[n]*invfac[m]%mod*invfac[n-m]%mod;}
inline int getans()
{
	fac[0]=1;for(int i=1;i<maxn;i++) fac[i]=1ll*fac[i-1]*i%mod;
	invfac[maxn-1]=ksm(fac[maxn-1],mod-2);
	for(int i=maxn-2;i>=0;i--) invfac[i]=1ll*invfac[i+1]*(i+1)%mod;
	int ans=0;
    for(int i=1;i<=n;i++)
	{
        int c1=0,c2=0;
        for(int j=1;j<=n;j++) c1+=(mn[j]>mx[i]);
        for(int j=1;j<=n;j++) c2+=(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)));
        if(c1>=a) continue;
        for(int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&j>=0;--j) (ans+=1ll*C(c2,j)*C(c1,b-j-1)%mod)%=mod;
    }
    return ans;
}
int main()
{
	init();
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++) for(int j=head[i];j;j=nxt[j]) if(sccid[i]!=sccid[ver[j]]) Addedge(sccid[i],sccid[ver[j]]);
	for(int i=1;i<=scc_cnt;i++)
	{
		for(int j=0;j<S[i];j++) Str[i]+='0';
		for(int j=0;j<(int)scc[i].size();j++) for(int k=0;k<(int)str[scc[i][j]].length();k++) if(str[scc[i][j]][k]=='1') Str[i][k%S[i]]='1';
	}
	Toposort();
	printf("%d",getans());
}

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], fac[maxn], ifac[maxn];
void input() {
char str[(int)(2e6) + 2];
scanf("%d %d %d", &n, &A, &B);
for (int i = 1; i <= n; ++i) {
scanf("%s", str + 1);
for (int j = 1; j <= n; ++j)
if (str[j] == '1')
g[i].push_back(j);}
for (int i = 1; i <= n; ++i) {
scanf("%d %s", &s[i], str);
city[i].resize(s[i]);
for (int j = 0; j < s[i]; ++j)
city[i][j] = str[j] - '0';}}
LL qpow(LL a, LL b) {
LL res(1);
while (b) {
if (b & 1)res = res * a % MOD;
a = a * a % MOD;
b >>= 1;}
return res;}
void init() {
fac[0] = 1;
int N = maxn - 3;
for (int i = 1; i <= N; ++i)  fac[i] = 1ll * fac[i - 1] * i % MOD;
ifac[N] = qpow(fac[N], MOD - 2);
for (int i = N - 1; i >= 0; --i)  ifac[i] = 1ll * ifac[i + 1] * (i + 1) % MOD;}
vector<bool> colbull[maxn];
int Gcdcol[maxn], cntbull[maxn], maxbull[maxn], minbull[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], colcnt, stk[maxn], top;
void tarjan(int u) {
dfn[u] = low[u] = ++dfst;
stk[++top] = u;
for (int i = 0; i < (int)g[u].size(); ++i) {
int v= g[u][i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (!col[v])
low[u] = min(low[u], dfn[v]);}
if (low[u] == dfn[u]) {++colcnt;int v;do {
v = stk[top--];
col[v] = colcnt;
} while (u != v);
Gcdcol[colcnt] = s[u];}}
void solve1() {
for (int i = 1; i <= n; ++i) if (!dfn[i])tarjan(i);
for (int i = 1; i <= n; ++i)Gcdcol[col[i]] = __gcd(Gcdcol[col[i]], s[i]);
for (int i = 1; i <= n; ++i)  {
colbull[col[i]].resize(Gcdcol[col[i]]);
for (int j = 0; j < s[i]; ++j)
if (city[i][j] == 1)
colbull[col[i]][j % Gcdcol[col[i]]] = 1;}
vector<bool> tmp;
for (int i = colcnt; i >= 2; --i) {
int g = __gcd(Gcdcol[i], Gcdcol[i - 1]);
tmp.clear();
tmp.resize(g);
for (int j = 0; j < Gcdcol[i]; ++j)
tmp[j % g] = tmp[j % g] | colbull[i][j];
for (int j = 0; j < Gcdcol[i - 1]; ++j)
colbull[i - 1][j] = colbull[i - 1][j] | tmp[j % g];}
for (int i = 1; i <= colcnt; ++i)
for (int j = 0; j < Gcdcol[i]; ++j)
cntbull[i] += colbull[i][j];
for (int i = 1; i <= n; ++i)
maxbull[i] = s[i] / Gcdcol[col[i]] * cntbull[col[i]];
for (int i = 1; i <= n; ++i)
for (int j = 0; j < s[i]; ++j)
minbull[i] += city[i][j];}
LL ans;
LL combine(int n, int m) {
if (m < 0 || n < 0 || m > n) return 0;
return 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;}
void solve2() {
for (int i = 1; i <= n; ++i) {
int cnt1 = 0, cnt2 = 0;
for (int j = 1; j <= n; ++j) {
if (i == j) continue;
if (minbull[j] > maxbull[i]) ++cnt1;
else if (maxbull[j] > maxbull[i] || (maxbull[j] == maxbull[i] and j < i)) ++cnt2;}
if (cnt1 >= A) continue;
for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) {
ans = (1ll * ans + 1ll * combine(cnt1, B - j - 1) * combine(cnt2, j) % MOD) % MOD;}}
cout << ans << endl;}
int main() {
input();
init();
solve1();
solve1();
solve2();}

#include <bits/stdc++.h>
#define ll long long
#define maxn 5005 /*rem*/
#define mod 1000000007
#define db double
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define pi pair<int, int>
#define fi first
#define se second
using namespace std;
ll ksm(ll a, ll b) {
   if (!b) return 1;
   ll ns = ksm(a, b >> 1);
   ns = ns * ns % mod;
   if (b & 1) ns = ns * a % mod;
   return ns;
}
stack<int> s;
int low[10005],dfn[10005],k[10005];
bool vis[100005];
int idcnt = 0;
vi cur[maxn];
vi eg[maxn];
int dfcnt = 0;
void dfs(int u){
	dfn[u]=low[u]=++dfcnt;
//	cout << "DFS" << u << endl;
	s.push(u); vis[u]=true;
	for(auto v : eg[u]){
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u]){
		idcnt++;
		while(int t=s.top()){
			vis[t]=false; s.pop();
			k[t]=idcnt;
			cur[idcnt].pb(t);
			if(t==u)
				break;
		}
	}
}
ll jc[maxn], bjc[maxn];
vi fl[maxn];
int n, a, b;
int gcd(int a, int b) {
	if (!b) return a;
	return gcd(b, a % b);
}
char inp[1000005];
int dd[maxn];
vi cfl[maxn];
int cnt[maxn][2];
ll c(int a, int b) {
	if (b < 0 || b > a) return 0;
	return jc[a] * bjc[b] % mod * bjc[a - b] % mod;
}
bool cmp(int a, int b) {
	return cnt[a][0] + cnt[a][1] < cnt[b][0] + cnt[b][1];
}
int main() {
	jc[0] = bjc[0] = 1;
	for (int i = 1; i < maxn; i++)
		jc[i] = jc[i - 1] * i % mod;
	for (int i = 1; i < maxn; i++)
		bjc[i] = ksm(jc[i], mod - 2);
	cin >> n >> a >> b;
	for (int i = 1; i <= n; i++) {
		scanf("%s", inp + 1);
		for (int j = 1; j <= n; j++)
			if (inp[j] == '1') eg[i].pb(j);//, cout << "EG" << i << ' '  << j << endl;
	}
	for (int i = 1; i <= n; i++) {
		int sz;
		scanf("%d", &sz);
		fl[i].resize(sz);
		scanf("%s", inp);
		for (int j = 0; j < sz; j++)
			fl[i][j] = inp[j] - '0'; // gangs
 	}
 	for (int i = 1; i <= n; i++)
		if (!dfn[i]) dfs(i);
//	cout << "AF" << ' ' << idcnt << endl;
 	for (int i = idcnt; i >= 1; i--) {
		int g = 0;
		for (auto v : cur[i])
	//		cout << "BL" << i << ' ' << v << endl,
			g = gcd(g, fl[v].size());
		dd[i] = g;
		cfl[i].resize(dd[i]); // 一块
		for (auto v : cur[i])
			for (int j = 0; j < fl[v].size(); j++)
				if (fl[v][j]) cfl[i][j % g] = 1;
	}
	for (int i = idcnt; i >= 2; i--) {
		int ns = gcd(dd[i], dd[i - 1]);
		vi dfl(ns);
		for (int j = 0; j < dd[i]; j++)
			if (cfl[i][j])
				dfl[j % ns] = 1;
		for (int j = 0; j < dd[i - 1]; j++)
			if (dfl[j % ns])
				cfl[i - 1][j] = 1;
	}

	for (int i = 1; i <= idcnt; i++)
		for (auto v : cur[i]) {
			for (int j = 0; j < fl[v].size(); j++)
				if (fl[v][j] == 0 && cfl[i][j % dd[i]] == 1) fl[v][j] = -1;
		}
	for (int i = 1; i <= n; i++) {
	//	cout << i << ' ' << fl[i].size() << endl;
		for (auto x : fl[i]) {
		//	cout << x << ' ';
			if (x == 1) cnt[i][0]++;
			else if (x == -1) cnt[i][1]++;
		}
	//	cout << endl;
	}
	vi id;
	for (int i = 1; i <= n; i++) id.pb(i);
	sort(id.begin(), id.end(), cmp);
	ll ans = 0;
//	cout << "AF" << endl;
	for (int i = n - 1; i >= 0; i--) {
		int u = 0, v = 0;
		int x = id[i];
		for (int j = i + 1; j < n; j++) {
			int y = id[j];
			if (cnt[y][0] > cnt[x][0] + cnt[x][1]) u++;
			else v++;
		}
		int nu = max(0, u - (a - b));
		for (int s = nu; s <= u; s++)
			ans += c(u, s) * c(v, b - 1 - s),
			ans %= mod;
	}
	cout << ans << endl;
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>

int n,a,b,s[5001],R[5001],F[5001];
int low[5001],dfn[5001],stk[5010],top,now,S,Ans[5001],g[5001][5001];
int cnt1[2000010],cnt2[2000010],C[5010][5010];
int gcd(int a,int b){return (!b)?a:gcd(b,a%b);}
bool instack[5001],vis[2000001],A[5001][5001];
std::vector<int>ans[5001],vec[5001];
std::pair<int,int>in[5010];
void tarjan(int x){
	low[x]=dfn[x]=++now;
	instack[x]=1;
	stk[++top]=x;
	for(int i=1;i<=n;i++)
		if(A[x][i]){
			if(!dfn[i])tarjan(i),low[x]=std::min(low[x],low[i]);
			else if(instack[i])low[x]=std::min(low[x],dfn[i]);
		}
	if(low[x]==dfn[x]){
		++S;
		while(stk[top+1]!=x){
			Ans[stk[top]]=S;
			g[S][S]=gcd(g[S][S],s[stk[top]]);
			vec[S].push_back(stk[top]);
			instack[stk[top]]=0;
			--top;
		}
	}
}
int qsm(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%1000000007;
		a=1ll*a*a%1000000007;
		b>>=1;
	}
	return ans;
}
int read(){
	char ch=getchar();
	while(ch!='0'&&ch!='1')ch=getchar();
	return ch=='1';
}
int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			A[i][j]=read();
	for(int i=1;i<=n;i++){
		scanf("%d",s+i);
		ans[i].resize(s[i]);
		for(int j=0;j<s[i];j++)
			R[i]+=ans[i][j]=read();
	}
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
//	for(int i=1;i<=n;i++)printf("*%d %d\n",i,Ans[i]);
	for(int i=S;i;i--){
		for(int j=i;j>=1&&j>=i-1;j--){
			if(j<i)g[i][j]=gcd(g[i][j+1],g[j][j]);
//			printf("%d %d %d\n",i,j,g[i][j]);
			if(j==i||g[i][j]!=g[i][j+1]){
				memset(vis,0,(g[i][j]+1));
				for(int k=0;k<vec[i].size();k++){
					for(int l=0;l<s[vec[i][k]];l++)
						if(ans[vec[i][k]][l])vis[l%g[i][j]]=1;//,printf("%d\n",l%g[i][j]);
				}
			}
			for(int k=0;k<vec[j].size();k++){
//				printf("-%d %d %d\n",j,vec[j][k],g[i][j]);
				for(int l=0;l<s[vec[j][k]];l++)
					if(vis[l%g[i][j]])ans[vec[j][k]][l]=1;//,printf("%d %d\n",l,l);
			}
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=0;j<s[i];j++)
			F[i]+=ans[i][j];//,printf("%d %d %d\n",i,j,ans[i][j]);
	for(int i=1;i<=n;i++)++cnt1[R[i]],++cnt2[F[i]];
	for(int i=1;i<=2000000;i++)cnt2[i]+=cnt2[i-1];
	for(int i=1999999;~i;i--)cnt1[i]+=cnt1[i+1];
	for(int i=0;i<=n;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%1000000007;
	}
	int ans=0;
//	for(int i=1;i<=n;i++)printf("%d %d\n",F[i],R[i]);
	for(int i=1;i<=n;i++)in[i]=std::make_pair(R[i],F[i]);
	std::sort(in+1,in+n+1);
	std::reverse(in+1,in+n+1);
	for(int i=1;i<=n;i++){
		int c1=0,c2=0;
		for(int j=1;j<=n;j++){
			if(in[j].first>in[i].second)++c1;
			else if(in[j].second>in[i].second)++c2;
			else if(in[j].second==in[i].second&&j<i)++c2;
		}
		if(c1>=a)continue;
		for(int j=std::min(b,std::min(a-1-c1,c2));j>=0&&b-1-j<=c1;--j)
			ans=(1ll*ans+1ll*C[c2][j]*C[c1][b-1-j])%1000000007;
	}
	printf("%d\n",ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[M+5],inv[M+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<M;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<M;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<M;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[M];
char truegold[M];
int gold[M];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    sum1[n+1]=sum1[n]+sz[n];
    for(int i=0;i<sum1[n+1];i++)
        truegold[i]-='0';
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=scnt;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        //for(int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&j>=0;j--){
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
inline int add(int a,int b)
{
	a+=b;
	if(a>=mod)a-=mod;
	return a;
}
inline int mult(int a,int b)
{
	long long t=1ll*a*b;
	if(t>=mod)t%=mod;
	return t;
}
inline int dec(int a,int b)
{
	a-=b;
	if(a<0)a+=mod;
	return a;
}
int n,a,b,tim,dfn[5010],low[5010],stk[5010],L[5010],R[5010],top,num,scc[5010],w[5010],len[5010];
bool vis[5010],able[2000010];
vector<int> g[5010],scc_bit[5010],v[5010],id[5010];
void dfs(int np)
{
	dfn[np]=low[np]=++tim;
	stk[++top]=np;
	vis[np]=1;
	for(int i=0;i<g[np].size();i++)
	{
		if(!dfn[g[np][i]])
		{
			dfs(g[np][i]);
			low[np]=min(low[np],low[g[np][i]]);
		}
		else if(vis[g[np][i]])
		{
			low[np]=min(low[np],dfn[g[np][i]]);
		}
	}
	if(low[np]==dfn[np])
	{
		int tmp;
		++num;
		while((tmp=stk[top--]))
		{
			scc[tmp]=num;
			w[num]=__gcd(w[num],len[tmp]);
			v[num].push_back(tmp);
			vis[tmp]=0;
			if(tmp==np)break;
		}
		scc_bit[num].resize(w[num]);
		for(int i=0;i<v[num].size();i++)
		{
			for(int j=0;j<len[v[num][i]];j++)
			{
				if(able[id[v[num][i]][j]])scc_bit[num][j%w[num]]=1;
			}
		}
	}
}
char s[1000010];
int C[5010][5010],idcnt=0;
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++)if(s[j]=='1')g[i].push_back(j);
	}
	for(int i=0;i<=n;i++)
	{
		C[i][0]=1;
		for(int j=1;j<=i;j++)C[i][j]=add(C[i-1][j-1],C[i-1][j]);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d%s",&len[i],s);
		for(int j=0;j<len[i];j++)
		{
			id[i].push_back(++idcnt);
			if(s[j]=='1')able[idcnt]=1,L[i]++;
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])dfs(i);
	}
	for(int i=num;i>1;i--)
	{
		int g=__gcd(w[i],w[i-1]);
		w[i-1]=g;
		for(int j=0;j<w[i];j++)scc_bit[i-1][j%g]|=scc_bit[i][j%g];
	}
	for(int i=1;i<=n;i++)
	{
		int x=scc[i];
		for(int j=0;j<len[i];j++)R[i]+=scc_bit[x][j%w[x]];
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		int t1=0,t2=0;
		for(int j=1;j<=n;j++)if(L[j]>R[i])t1++;
		if(t1>=a)continue;
		for(int j=1;j<=n;j++)if(L[j]<=R[i]&&make_pair(R[j],j)>make_pair(R[i],i))t2++;
		for(int j=0;j<b&&j<=t2&&j+t1<a;j++)ans=add(ans,mult(C[t2][j],C[t1][b-j-1]));
	}
	printf("%d\n",ans);
	return 0;
}

#include<bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define sz(s) (int(s.size()))
#define bit(n,k) (((n)>>(k))&1)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

template<typename A, typename B> ostream& operator << (ostream &out, pair<A, B> x){
    out << "{ "<< x.F << ", " << x.S << "}";
    return out;
}
template<typename A, typename B> istream& operator >> (istream &in, pair<A, B> &x){
    in >> x.F >> x.S;
    return in;
}
template<typename A> ostream& operator << (ostream &out, vector<A> v){
    out << "[ ";
    for(int i = 0; i < sz(v); i++){
	out << v[i];
	if(i != sz(v)-1)
	    out<< ", ";
    }
    return out << " ]";
}

const int maxn = 5010, Max = 2e6 + 10, mod = 1e9 + 7;

vector<int> v[maxn], rv[maxn];
int arr[maxn];
bool mark[maxn];

vector<bool> vg;
vector<bool> str[maxn];
vector<bool> varr[maxn];
vector<int> inside[maxn];

void dfs(int u, int src){
    mark[u] = 1;
    int g = __gcd( sz(vg), sz(str[u]) );
    for(int i = 0; i < sz(vg); i++)
	vg[i %g]= vg[i] | vg[i % g];
    vg.resize(g);
    for(int i = 0; i < sz(str[u]); i++)
	vg[i %g]= str[u][i] | vg[i %g];
    inside[src].PB(u);
    for(int y : rv[u])
	if(mark[y] == 0)
	    dfs(y, src);
}

pii p[maxn];
int START[Max], END[Max];
int C[maxn][maxn];

int main(){
    ios_base::sync_with_stdio(0), cin.tie(), cout.tie();

    for(int i = 0; i < maxn; i++){
	C[i][0] = 1;
	for(int j = 1; j <= i; j++)
	    C[i][j] = (C[i-1][j-1] + C[i-1][j]) %mod;
    }

    int n, a, b;
    cin >> n >> a >> b;
    for(int i = 0; i < n; i++){
	string s;
	cin >> s;
	for(int j = 0; j < n; j++)
	    if(s[j] == '1')
		v[i].PB(j), rv[j].PB(i);
    }
    for(int i = 0; i < n; i++){
	int x;
	cin >> x;
	string s;
	cin >> s;
	for(int j = 0; j < sz(s); j++)
	    str[i].PB(s[j] == '1');
    }
    iota(arr, arr+n, 0);
    sort(arr, arr+n, [&](int i, int j){ return sz(v[i]) > sz(v[j]); } );
    int N = 0;
    for(int i = 0; i < n; i++){
	if(mark[arr[i]])
	    continue;
	vg = str[ arr[i] ];
	dfs(arr[i], N);
	varr[N] = vg;
	N++;
    }
    for(int i = 0; i < N-1; i++){
	int g = __gcd( sz(varr[i]), sz(varr[i+1]) );
	vector<bool> vv(g);
	for(int j = 0; j < sz(varr[i]); j++)
	    vv[j % g] = vv[j % g] | varr[i][j];
	for(int j = 0; j < sz(varr[i+1]); j++)
	    varr[i+1][j] = varr[i+1][j] | vv[j % g];
    }
    for(int i = 0; i < n; i++){
	for(int j = 0; j < sz(str[i]); j++)
	    p[i].F += str[i][j];
    }
    for(int i = 0; i < N; i++){
	int num = 0;
	for(int x : varr[i])
	    num+= x;
	for(int u : inside[i])
	    p[u].S = num * (sz(str[u]) / sz(varr[i]));
    }
    for(int i = 0; i < n; i++){
	START[ p[i].F ]++;
	END[ p[i].S ]++;
    }
    int A = 0, B = 0, ans = 0;
    for(int i = Max-3; i >= 0; i--){
	if(START[i] == 0 && END[i] == 0)
	    continue;
	B+= END[i];
	for(int j = max(int(0), A - (a-b)); j <= min(A, b); j++){
	    ans = ( 1ll * ans + 1ll * C[A][j] * (C[B][b-j] - C[B - END[i]][b-j]) ) %mod;
	}
	A+= START[i];
	B-= START[i];
    }
    if(ans < 0)
	ans+= mod;
    return cout << ans << endl, 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 5010
#define MAXM 1000010
#define MOD 1000000007
using namespace std;
typedef long long ll;
vector<int> a[MAXN];
int n,A,B,cnt;
char s[MAXM];
int num[MAXN];
vector<int>gold[MAXN],tgold[MAXN];
int gcdv[MAXN];
int dfn[MAXN],low[MAXN],st[MAXN],top,nq[MAXN];
int gcd(int x,int y){
	if(y==0)
		return x;
	return gcd(y,x%y);
}
char w[MAXN][MAXN];
int tot;
void tar(int x){
	dfn[x]=low[x]=++cnt;
	st[++top]=x;
	for(int u=0;u<n;u++){
		if(w[x][u]=='0')
			continue;
//		PF("<%d -> %d>\n",x,u);
		if(dfn[u]==0){
			tar(u);
			low[x]=min(low[x],low[u]);
		}
		else if(nq[u]==0)
			low[x]=min(low[x],dfn[u]);
	}
	if(dfn[x]==low[x]){
		nq[x]=++tot;
		gcdv[tot]=num[x];
		while(st[top]!=x){
			nq[st[top]]=tot;
			gcdv[tot]=gcd(gcdv[tot],num[st[top]]);
			top--;
		}
		tgold[tot].resize(gcdv[tot]);
		top--;
	}
}
int totg[MAXN],mx[MAXN],mn[MAXN],fac[MAXN],inv[MAXN];
ll C(int x,int y){
	return (ll)fac[x]*inv[y]%MOD*inv[x-y]%MOD;
}
int main(){
	SF("%d%d%d",&n,&A,&B);
	for(int i=0;i<n;i++)
		SF("%s",w[i]);
	for(int i=0;i<n;i++){
		SF("%d",&num[i]);
		SF("%s",s);
		for(int j=0;j<num[i];j++)
			gold[i].push_back(s[j]-'0');
	}
	for(int i=0;i<n;i++)
		if(dfn[i]==0)
			tar(i);
	for(int i=0;i<n;i++)
		for(int j=0;j<num[i];j++)
			tgold[nq[i]][j%gcdv[nq[i]]]|=gold[i][j];
	for(int i=tot;i>1;i--){
		int now=gcd(gcdv[i],gcdv[i-1]);
		for(int j=0;j<gcdv[i];j++)
			tgold[i-1][j%now]|=tgold[i][j];
	}
	for(int i=1;i<=tot;i++)
		for(int j=0;j<gcdv[i];j++)
			if(tgold[i][j])
				totg[i]++;
	for(int i=0;i<n;i++){
		mx[i]=(ll)totg[nq[i]]*num[i]/gcdv[nq[i]];
		for(int j=0;j<num[i];j++)
			if(gold[i][j])
				mn[i]++;
	}
	fac[0]=1;
//	for(int i=1;i<=tot;i++){
//		for(int j=0;j<gcdv[i];j++)
//			PF("%d",tgold[i][j]);
//		PF("\n");
//	}
	for(int i=1;i<=n;i++)
		fac[i]=(ll)fac[i-1]*i%MOD;
	inv[0]=inv[1]=1;
	for(int i=2;i<=n;i++)
		inv[i]=(ll)inv[MOD%i]*(MOD-MOD/i)%MOD;
	for(int i=2;i<=n;i++)
		inv[i]=(ll)inv[i-1]*inv[i]%MOD;
	int ans=0;
//	for(int i=0;i<n;i++)
//		PF("[%d %d]\n",mx[i],mn[i]);
	for(int i=0;i<n;i++){
		int c1=0,c2=0;
		for(int j=0;j<n;j++)
			if(mn[j]>mx[i])
				c1++;
		if(c1>=A)
			continue;
		for(int j=0;j<n;j++)
			if(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)))
				c2++;
		for(int j=min(B-1,min(c2,A-1-c1));B-j-1<=c1&&j>=0;j--)
			ans=(ans+(ll)C(c2,j)*C(c1,B-j-1)%MOD)%MOD;
	}
	PF("%d\n",ans);
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n,a,b,c;
char str[MAXL+5];
vector<int> G[MAXN+5];
vector<int> per[MAXN+5];
int siz[MAXN+5],dfn[MAXN+5],low[MAXN+5],dcnt;
int blo[MAXN+5],bgcd[MAXN+5],blocnt;
int stk[MAXN+5],t;
int num[MAXN+5],mx[MAXN+5],mn[MAXN+5];
bool instk[MAXN+5];
int fact[MAXN+5],inv[MAXN+5];
int PowMod(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret=1LL*ret*x%MO;
		x=1LL*x*x%MO;
		y>>=1;
	}
	return ret;
}
int gcd(int x,int y)
{
	if(y==0)
		return x;
	return gcd(y,x%y);
}
void InPut()
{
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				G[i].push_back(j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		per[i].resize(siz[i]+1);
		scanf("%s",str);
		for(int j=0;j<siz[i];j++)
			if(str[j]=='1')
				per[i][j]=1;
			else if(str[j]=='0')
				per[i][j]=0;
	}
}
void Tarjan(int u,int fa)
{
	dfn[u]=low[u]=++dcnt;
	instk[u]=true;stk[t++]=u;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(dfn[v]==0)
		{
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]==true)
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int fro=0;blocnt++;
		do
		{
			fro=stk[--t];instk[fro]=false;
			blo[fro]=blocnt;
			bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
		}while(fro!=u);
	}
}
void Part1()
{
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			Tarjan(i,-1);
	for(int i=1;i<=blocnt;i++)
		per[i+n].resize(bgcd[i]+1);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];
	int nw;
	for(int i=blocnt;i>1;i--)
	{
		nw=gcd(bgcd[i],bgcd[i-1]);
		for(int j=0;j<bgcd[i];j++)
			if(per[i+n][j])
			{
				per[i-1+n][j%nw]|=1;
				num[i]++;
			}
	}
	for(int j=0;j<bgcd[1];j++)
		num[1]+=per[1+n][j];
	for(int i=1;i<=n;i++)
	{
		mx[i]=mn[i]=0;
		mx[i]=1LL*num[blo[i]]*siz[i]/bgcd[blo[i]];
		for(int j=0;j<siz[i];j++)
			mn[i]+=per[i][j];
	}
}
void Prepare()
{
	fact[0]=1;
	for(int i=1;i<=MAXN;i++)
		fact[i]=1LL*fact[i-1]*i%MO;
	inv[MAXN]=PowMod(fact[MAXN],MO-2);
	for(int i=MAXN-1;i>=0;i--)
		inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%MO;
}
inline int C(int x,int y)
{
	return 1LL*fact[x]*inv[y]%MO*inv[x-y]%MO;
}
int Part2()
{
	Prepare();
	int cnt1=0,cnt2=0,ret=0;
	for(int i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i!=j&&mn[j]>mx[i])
				cnt1++;
			if(i!=j&&mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)))
				cnt2++;
		}
		if(cnt1>a-1)
			continue;
		for(int j=min(b,min(a-1-cnt1,cnt2));j>=0&&j+1+cnt1>=b;j--)
			ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%MO)%MO;
	}
	return ret;
}
int main()
{
	InPut();
	Part1();
	int ans=Part2();
	printf("%d\n",ans);
	return 0;
}

#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
const int N = 5001;
int n, a, b;
namespace hamilton_path_for_competition_map{
    vector<vector<bool> > edge;
    vector<int> d;
    bool expand(int x, int n) {
        d.resize(0);
        d.push_back(x);
        for (int i = 0; i < n; i ++)
            if (i != x) {
                if (edge[d[d.size() - 1]][i]) d.push_back(i);
                else {
                    int x = 0;
                    while (edge[d[x]][i])
                        x ++;
                    d.push_back(i);
                    rotate(d.begin() + x, d.end() - 1, d.end());
                }
            }
        if (d.size() == n) return 1;
        return 0;
    }
    vector<int> construct(vector<vector<bool> >_edge, int n) {
        edge = _edge;
        for (int i = 0; i < n; i ++)
            if (expand(i, n)) {
                return d;
            }
        d.resize(0);
        return d;
    }
}
typedef long long ll;
const int mod = 1e9 + 7;
ll calc(ll x, ll y){
    ll z = 1;
    while (y) {
        if (y & 1) z = z * x % mod;
        x = x * x % mod, y /= 2;
    }
    return z;
}
namespace C{
    const int mod = 1e9+7;
    vector<int>a, nia;
    void pre(int n){
        a = vector<int>(n + 1, 1);
        nia = vector<int>(n + 1, 1);
        for (int i = 2; i <= n; i ++)
            a[i] = 1ll * a[i - 1] * i % mod;
        nia[n] = calc(a[n], mod - 2);
        for (int i = n - 1; i >= 2; i --)
            nia[i] = 1ll * nia[i + 1] * (i + 1) % mod;
    }
    ll C(ll x, ll y) {
        if (x < y || y < 0 || x < 0) return 0;
        return 1ll * a[x] * nia[y] % mod * nia[x - y] % mod;
    }
}
namespace count{//�������li��ri��Χ����ǰa������ѡb���Ĳ�ͬ�ļ�����
    const int mod = 1e9+7;
    int gao(vector<pair<int, int> > d, int a, int b) {
        C::pre(d.size());
        /*sort(d.begin(), d.end(), [](pair<int, int> a, pair<int, int>b) {
            return a.second > b.second;
        });*/
        int ans = 0;
        for (int i = 0; i < d.size(); i ++) {
            int sumequal = 0, sumbigger = 0, sumsmaller = 0;
            for (int j = 0; j < d.size(); j ++)
                if (j != i) {
                    if (d[j].first <= d[i].second && d[j].second >= d[i].second) {
                        if (d[j].second == d[i].second && j > i) {
                            sumsmaller ++;
                        } else sumequal++;
                    }else {
                        if (d[j].second < d[i].second)
                            sumsmaller ++;
                        else
                            sumbigger ++;
                    }
                }
            for (int j = 0; j <= sumequal; j ++) {
                int x = b - j - 1;
                if (sumbigger + j + 1 > a || x > sumbigger || x < 0) continue;
                ans = (ans + 1ll * C::C(sumbigger, x) * C::C(sumequal, j)) % mod;
            }
        }
        return ans;
    }
}
int id[N];
int fa[N], c[2000001];
vector<int>w[N];
int getfa(int x) {
    return fa[x] == x? x : fa[x] = getfa(fa[x]);
}
int main() {
    scanf("%d %d %d", &n, &a, &b);
    vector<vector<bool> > edge(n, vector<bool>(n));
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < n ; j ++) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            if (c =='1') edge[i][j] = 1;
        }
    }
    vector<int>d = hamilton_path_for_competition_map::construct(edge, n);
    for (int i = 0; i < d.size();  i ++)
        id[d[i]] = i, fa[i] = i;
    for (int u = 0; u < n ; u ++) {
        int tmp = u;
        for (int v = 0; v < n; v++)
            if (edge[d[u]][v]) {
                tmp = min(tmp, id[v]);
            }
        for (int i = tmp; i < u; i ++)
            if (getfa(d[i]) != d[u]) {
                fa[getfa(d[i])] = d[u];
            }
    }
    vector<vector<int> > g(n, vector<int>(0));
    for (int i = 0; i < n; i ++)
        g[getfa(i)].push_back(i);
    for (int i = 0; i < n; i ++) {
        int x;
        scanf("%d", &x);
        while (x --) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            w[i].push_back(c - '0');
        }
    }
    vector<int> dd(0);
    for (auto u:d)
        if (getfa(u) == u)
            dd.push_back(u);
    for (int i = 0; i < dd.size(); i ++) {
        int u = dd[i];
        int gcd = 0;
        for (auto v:g[u]) {
            int tmp = w[v].size();
            gcd = __gcd(tmp, gcd);
        }
        for (int i = 0; i < gcd; i++)
            c[i] = 0;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (w[v][i])
                    c[i % gcd] = 1;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (!w[v][i] && c[i % gcd])
                    w[v][i] = 2;
        if (i != (int)dd.size() - 1) {
            int v = dd[i + 1];
            int tmp = w[v].size();
            int gcd1 = __gcd(tmp, gcd);
            for (int i = 0; i < gcd1; i ++)
                for (int j = 0; j * gcd1 + i < gcd; j ++)
                    c[i] |= c[i + j * gcd1];
            for (int i = 0; i < w[v].size(); i ++)
                if (!w[v][i] && c[i % gcd1])
                    w[v][i] = 2;
        }
    }
    vector<pair<int, int> > f;
    for (int i = 0; i < n; i ++) {
        int l = 0, r = 0;
        for (auto u:w[i])
            if (u == 1) l ++, r ++;
            else
                if (u == 2) r ++;
        f.push_back(make_pair(l, r));
    }
    printf("%d\n",count::gao(f, a, b));
    return 0;
}

#pragma GCC optimize( 2 )

#include <cstdio>
#include <vector>

const int MAXN = 5e3, MAXL = 2e6, MOD = 1e9 + 7;
int n, s[MAXN + 5], A, B, mng[MAXN + 5], mxg[MAXN + 5];
int fac[MAXN + 5], ifac[MAXN + 5];
std::vector<int> adj[MAXN + 5];
std::vector<bool> gold[MAXN + 5];
int dfc, top, dfn[MAXN + 5], low[MAXN + 5], stk[MAXN + 5];
bool instk[MAXN + 5];
int scc, bel[MAXN + 5], siz[MAXN + 5], cnt[MAXN + 5];
std::vector<bool> apr[MAXN + 5];
int ans;

inline void chkmin ( int& a, const int b ) { if ( b < a ) a = b; }

inline int rint () {
	int x = 0; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () );
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
	return x;
}

inline int gcd ( const int a, const int b ) { return b ? gcd ( b, a % b ) : a; }

inline int qkpow ( int a, int b, const int p = MOD ) {
	int ret = 1;
	for ( ; b; a = 1ll * a * a % p, b >>= 1 ) ret = 1ll * ret * ( b & 1 ? a : 1 ) % p;
	return ret;
}

inline void Tarjan ( const int u ) {
	dfn[u] = low[u] = ++ dfc, instk[stk[++ top] = u] = true;
	for ( int v: adj[u] ) {
		if ( ! dfn[v] ) {
			Tarjan ( v );
			chkmin ( low[u], low[v] );
		} else if ( instk[v] ) {
			chkmin ( low[u], dfn[v] );
		}
	}
	if ( dfn[u] == low[u] ) {
		int v; ++ scc;
		do {
			instk[v = stk[top --]] = false;
			bel[v] = scc;
		} while ( v ^ u );
	}
}

inline void input () {
	n = rint (), A = rint (), B = rint ();
	char tmp[MAXL + 5];
	for ( int i = 1; i <= n; ++ i ) {
		scanf ( "%s", tmp + 1 );
		for ( int j = 1; j <= n; ++ j ) {
			if ( tmp[j] ^ '0' ) {
				adj[i].push_back ( j );
			}
		}
	}
	for ( int i = 1; i <= n; ++ i ) {
		gold[i].resize ( s[i] = rint () );
		scanf ( "%s", tmp );
		for ( int j = 0; j < s[i]; ++ j ) {
			mng[i] += gold[i][j] = tmp[j] ^ '0';
		}
	}
}

inline void init () {
	fac[0] = 1;
	for ( int i = 1; i <= n; ++ i ) fac[i] = 1ll * i * fac[i - 1] % MOD;
	ifac[n] = qkpow ( fac[n], MOD - 2 );
	for ( int i = n - 1; ~ i; -- i ) ifac[i] = ( i + 1ll ) * ifac[i + 1] % MOD;
}

inline int comb ( const int n, const int m ) {
	return n < m ? 0 : 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}

inline void calcBound () {
	for ( int i = 1; i <= n; ++ i ) {
		if ( ! dfn[i] ) {
			Tarjan ( i );
		}
	}
	for ( int i = 1; i <= n; ++ i ) siz[bel[i]] = gcd ( s[i], siz[bel[i]] );
	for ( int i = 1; i <= scc; ++ i ) apr[i].resize ( siz[i] );
	for ( int i = 1; i <= n; ++ i ) {
		for ( int j = 0; j < s[i]; ++ j ) {
			if ( gold[i][j] ) {
				apr[bel[i]][j % siz[bel[i]]] = true;
			}
		}
	}
	std::vector<bool> tmp;
	for ( int i = scc; i > 1; -- i ) {
		int d = gcd ( siz[i], siz[i - 1] );
		tmp.clear (), tmp.resize ( d );
		for ( int j = 0; j < siz[i]; ++ j ) tmp[j % d] = tmp[j % d] | apr[i][j];
		for ( int j = 0; j < siz[i - 1]; ++ j ) apr[i - 1][j] = apr[i - 1][j] | tmp[j % d];
	}
	for ( int i = 1; i <= scc; ++ i ) for ( bool g: apr[i] ) cnt[i] += g;
	for ( int i = 1; i <= n; ++ i ) mxg[i] = s[i] / siz[bel[i]] * cnt[bel[i]];
}

inline void solve () {
	for ( int i = 1; i <= n; ++ i ) {
		int big = 0, crs = 0;
		for ( int j = 1; j <= n; ++ j ) {
			if ( i == j ) continue;
			if ( mxg[i] < mng[j] ) ++ big;
			else if ( mxg[i] <= mxg[j] - ( j < i ) ) ++ crs;
		}
		int l = std::max ( B - big - 1, 0 );
		int r = std::min ( crs, std::min ( B - 1, A - big - 1 ) );
		for ( int j = l; j <= r; ++ j ) {
			ans = ( ans + 1ll * comb ( crs, j ) * comb ( big, B - j - 1 ) ) % MOD;
		}
	}
}

int main () {
	input (), init ();
	calcBound ();
	solve ();
	printf ( "%d\n", ans );
	return 0;
}

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
#define N 5005
using namespace std;
int n,a,b,s[N],sz[N],C[N][N],Ans;char c[N];
short to[N*N],fr[N*N];int nxt[N*N],fst[N],l;
int st[N],top,bl[N],cnt,dfn[N],low[N],clk;
vector<short>p[N],v[N],e[N];
struct T
{
	int x,y;
}d[N];
int cmp(T a,T b)
{
	return a.x<b.x;
}

void link(int x,int y)
{
	to[++l]=y;fr[l]=x;nxt[l]=fst[x];fst[x]=l;
}
void dfs(int x)
{
	low[x]=dfn[x]=++clk;
	st[++top]=x;
	for (int i=fst[x];i;i=nxt[i])
		if (!dfn[to[i]])
		{
			dfs(to[i]);
			low[i]=min(low[i],low[to[i]]);
		}
		else if (!bl[to[i]])
			low[i]=min(low[i],low[to[i]]);
	if (low[x]==dfn[x])
	{
		cnt++;
		while(st[top]!=x)
		{
			p[cnt].push_back(st[top]);
			bl[st[top--]]=cnt;
		}
		p[cnt].push_back(st[top]);
		bl[st[top--]]=cnt;
	}
}
int _to[N*N],_nxt[N*N],_fst[N],_l,rd[N];
void lk(int x,int y)
{
	_to[++_l]=y;_nxt[_l]=_fst[x];_fst[x]=_l;rd[y]++;
}
void work(int x)
{
	rd[x]=-1;
	for (int i=_fst[x];i;i=_nxt[i])
	{
		rd[_to[i]]--;
		if (rd[_to[i]]==0)
		{
			int tmp=__gcd(sz[x],sz[_to[i]]);
			vector<int>tp;tp.clear();
			for (int j=0;j<tmp;j++)tp.push_back(0);
			for (int j=0;j<sz[x];j++)
				if (e[x][j]) tp[j%tmp]=1;
			for (int j=0;j<sz[_to[i]];j++)
				if (tp[j%tmp]) e[_to[i]][j]=1;
			work(_to[i]);
		}
	}
}
int bit[1000005];
void add(int x)
{
	x++;
	for (;x<=1000000;x+=x&-x)
		bit[x]++;
}
int qry(int x)
{
	x++;
	int ans=0;
	for (;x;x-=x&-x)
		ans+=bit[x];
	return ans;
}
int main()
{
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		for (int j=1;j<=n;j++)
		{
			if (c[j]=='1')
				link(i,j);
		}
	}
	for (int i=1;i<=n;i++)
		if (!dfn[i])
			dfs(i);
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
		sz[bl[i]]=__gcd(sz[bl[i]],s[i]);
		scanf("%s",c+1);
		for (int j=1;j<=s[i];j++)
		{
			v[i].push_back(c[j]=='1');
			d[i].x+=c[j]=='1';
		}
	}
	for (int i=1;i<=cnt;i++)
	{
		for (int j=0;j<sz[i];j++)
			e[i].push_back(0);
		for (int j=0;j<p[i].size();j++)
		{
			for (int k=0;k<v[p[i][j]].size();k++)
			if (v[p[i][j]][k])
				e[i][k%sz[i]]=1;
		}
	}
	for (int i=1;i<=l;i++)
	{
		if (bl[fr[i]]!=bl[to[i]])
			lk(bl[fr[i]],bl[to[i]]);
	}
	for (int i=1;i<=cnt;i++)
		if (rd[i]==0) work(i);

	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<s[i];j++)
			if (v[i][j]||e[bl[i]][j%sz[bl[i]]]) d[i].y++;
	}
	sort(d+1,d+n+1,cmp);
	C[0][0]=1;
	for (int i=1;i<=n;i++)
	{
		C[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
		}
	}
	/*
	for (int i=1;i<=n;i++)
	{
		printf("%d %d\n",d[i].x,d[i].y);
	}
	*/
	for (int i=1;i<=n;i++)
	{
		//cout<<i<<endl;
		if (i>=b)
		{
			if (i<=a)Ans+=C[i-1][b-1];
			else
			{
				int u=qry(d[i].y),v=i-1-u;
				//cout<<u<<' '<<v<<endl;
				for (int j=0;j<=u&&j<b;j++)
				{
					if (v+j+1<=a)
						Ans=(Ans+(ll)C[u][j]*C[v][b-j-1])%P;
				}
			}
		}
		add(d[i].x);
	//printf("%d\n",Ans);
	}
	printf("%d\n",Ans);
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) (a=(a)|(b))
#define cs const int &
const int N=5e3+10,MOD=1e9+7,M=2e6+10;
inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}
inline int Rc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

int n,A,B,ndfn,nscc;
int fac[N],ifac[N];
int siz[N],mn[N],mx[N],fsiz[N],fcnt[N];
int dfn[N],low[N],scc[N];
bool instk[N],tmp[M];
vector<bool> bag[N],fbag[N];
stack<int> stk;

inline int Comb(cs a,cs b){return (a>b || a<0 || b<0)? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true;
	stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		nscc++;
		int tmp=0;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]+1);
	}
}
int main(){
	//freopen("input.txt","r",stdin);
	n=Read(),A=Read(),B=Read();
	//scanf("%d%d%d",&n,&A,&B);
	Init();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			if(Rc())
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		for(int j=0;j<siz[i];j++){
			int thi=Rc();
			bag[i].push_back(thi);
			mn[i]+=thi;
		}
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int now=GCD(fsiz[i],fsiz[i-1]);
		for(int j=0;j<now;j++) tmp[j]=false;
		for(int j=0;j<fsiz[i];j++) upd(tmp[j%now],fbag[i][j]);
		for(int j=0;j<fsiz[i-1];j++) upd(fbag[i-1][j],tmp[j%now]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=fcnt[scc[i]]*siz[i]/fsiz[scc[i]];
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("%d: %d %d\n",i,mn[i],mx[i]);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mn[j]>mx[i]) mus++;
			else if(mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) may++;
		}
		if(mus>=A) continue;
		for(int j=min(B,min(A-1-mus,may));j+mus+1>=B;j--)
			ans=Add(ans,Mul(Comb(j,may),Comb(B-1-j,mus)));
	}
	printf("%d\n",ans);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2e6+10;
const int mod=1e9+7;
typedef pair<int,int> pii;
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define real xzzakhnoi2020

int n,a,b,C[N][N],deg[N],id[N],vis[M],tim,real[N],all[N];
string s[N];
pii p[N];
char E[N];
bool new_scc[N];

int main() {
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>a>>b;
	for(int i=0;i<N;i++) {
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
	}
	for(int i=1,len;i<=n;i++) {
		cin>>(E+1);
		for(int j=1;j<=n;j++) deg[i]+=(E[j]=='1');
	}
	for(int i=1,len;i<=n;i++) {
		cin>>len>>s[i],id[i]=i;
		for(auto c:s[i]) if(c=='1') ++real[i];
	}
	sort(id+1,id+n+1,[&](int a,int b) { return deg[a]>deg[b]; });
	for(int i=n,sdeg=0;i;i--) {
		sdeg+=deg[id[i]];
		if(sdeg==(n-i+1)*(n-i)/2) new_scc[i]=1;
	}
	for(int i=1,j;i<=n;i=j+1) {
		j=i;while(j<n&&!new_scc[j+1]) ++j;
		int gg=0;
		for(int k=i;k<=j;k++) gg=__gcd(gg,sz(s[id[k]]));
		++tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(s[id[k]][l]=='1') vis[l%gg]=tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(vis[l%gg]==tim) s[id[k]][l]='1';
		if(j<n) {
			gg=__gcd(sz(s[id[j]]),sz(s[id[j+1]]));
			++tim;
			for(int l=0;l<sz(s[id[j]]);l++) if(s[id[j]][l]=='1') vis[l%gg]=tim;
			for(int l=0;l<sz(s[id[j+1]]);l++) if(vis[l%gg]) s[id[j+1]][l]='1';
		}
	}
	for(int i=1;i<=n;i++) {
		for(auto c:s[i]) if(c=='1') ++all[i];
		p[i]=mp(real[i],all[i]);
		//cerr<<p[i].fi<<' '<<p[i].se<<endl;
	}
	sort(p+1,p+n+1,[&](pii a,pii b) { return a.se<b.se; });
	int ans=0;
	for(int i=1;i<=n;i++) {
		int cntl=0,cntr=0;
		for(int j=1;j<i;j++) if(p[j].fi>p[i].se) ++cntl;
		for(int j=i+1;j<=n;j++) if(p[j].fi>p[i].se) ++cntr;
		//cerr<<i<<' '<<cntl<<' '<<cntr<<endl;
		if(cntl>a-b) continue;
		for(int j=max(0,cntr-a-b+cntl);j<=cntr&&j<b;j++)
			ans=(ans+1ll*C[cntr][j]*C[n-i-cntr][b-1-j])%mod;
		//cerr<<i<<' '<<ans<<endl;
	}
	cout<<ans;
	return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b){
	int ret=1;
	while (b) {
		if(b&1) ret=(ll)ret*a%mod;
		a=(ll)a*a%mod;
		b>>=1;
	}return ret;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

 main(){
	//freopen("1.in","r",stdin);
	//freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        //printf ("bcc[%d]=%d\n",i,bccno[i]);
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<bgcd[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<bgcd[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
	 	printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
       //
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;//,inv[i]=powmod(fac[i],mod-2);
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
    	//printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        //printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&(~j);--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 1e9 + 7;

int n, a, b, s[5005];
string sta[5005], sta2[5005];
char adj[5005][5005];
int cnt;
vector<int> hv[5005];
int hdr = -1, nxt[25];
string cur[25];
PII dat[5005];

vector<int> ps;
bool vis[5005];
void dfs0(int v)
{
	vis[v] = true;
	rep(i, n) if(adj[v][i] == '1' && !vis[i]) dfs0(i);
	ps.push_back(v);
}
void dfs1(int v, vector<int>& chv)
{
	vis[v] = true;
	chv.push_back(v);
	rep(i, n) if(adj[i][v] == '1' && !vis[i]) dfs1(i, chv);
}

void gen_scc()
{
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[i]) dfs0(i);
	reverse(ps.begin(), ps.end());
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[ps[i]]) dfs1(ps[i], hv[cnt ++]);
}

int comb[5005][5005];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> a >> b;
	rep(i, n) cin >> adj[i];
	rep(i, n) {
		cin >> s[i] >> sta[i];
		sta2[i].resize(s[i], '0');
	}
	gen_scc();

	memset(nxt, -1, sizeof(nxt));
	rep(i, cnt) {
		rep(j, 25) if(cur[j].empty()) {
			nxt[j] = hdr;
			hdr = j;
			break;
		}
		int cg = 0;
		rep(j, hv[i].size()) cg = __gcd(cg, s[hv[i][j]]);
		cur[hdr].resize(cg, '0');
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) cur[hdr][k % cg] |= sta[gan][k];
		}
		for(int j = hdr; j != -1; j = nxt[j]) {
			int nsiz = __gcd(cg, (int)cur[j].length());
			if(nsiz == cur[j].length()) continue;
			for(int k = nsiz; k < cur[j].length(); k ++) cur[j][k % nsiz] |= cur[j][k];
			cur[j].resize(nsiz);
		}
		for(int j = hdr; j != -1; j = nxt[j])
		while(nxt[j] != -1 && cur[nxt[j]].length() == cur[j].length()) {
			int nj = nxt[j];
			rep(k, cur[j].length()) cur[j][k] |= cur[nj][k];
			cur[nj].clear();
			nxt[j] = nxt[nj];
			nxt[nj] = -1;
		}
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) for(int l = hdr; l != -1; l = nxt[l]) sta2[gan][k] |= cur[l][k % cur[l].length()];
		}
	}

	rep(i, n) rep(j, s[i]) {
		if(sta[i][j] == '1') dat[i].second ++;
		if(sta2[i][j] == '1') dat[i].first ++;
	}

	comb[0][0] = 1;
	rep1(i, n) {
		comb[i][0] = 1;
		rep1(j, n) comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
	}

	sort(dat, dat + n);
	int ans = 0;
	for(int i = n - 1; i >= 0; i --) {
		int cnt0 = a - b, cnt1 = 0;
		rep(j, i) if(dat[j].second > dat[i].first) cnt0 --;
		for(int j = i + 1; j < n; j ++) if(dat[j].second > dat[i].first) cnt1 ++;
		for(int j = max(cnt1 - cnt0, 0); j <= min(cnt1, b - 1); j ++)
		ans = (ans + 1LL * comb[cnt1][j] * comb[n - 1 - cnt1][b - 1 - j]) % MOD;
	}
	cout << ans << endl;
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[M];
char truegold[M];
int gold[M];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=0;i<sum1[n]+sz[n];i++)
        truegold[i]-='0';
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=scnt;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i<j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
inline int read()
{
    int x=0; char ch=getchar(); bool f=0;
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
    return f?-x:x;
}
#define CASET fo(___,1,read())
const int N=5005;
int n;

namespace Part1{
    string s[N]; char t[N];
    int m[N];
    int st[N],dfn[N],low[N],top,cnt,belong[N],tim,in[N],g[N],now[N];
    bool instack[N],vis[N][N],vi[N];
    vector<int> adj[N],vec[N],p[N];
    inline void add(int x,int y)
    {
        adj[x].pb(y);
    }
    inline void dfs(int u,int pre)
    {
        instack[u]=1;
        st[++top]=u;
        dfn[u]=low[u]=++tim;
        for(auto v:adj[u])
            if(!dfn[v]) dfs(v,u),low[u]=min(low[u],low[v]);
            else if(instack[v]) low[u]=min(low[u],dfn[v]);
        if(low[u]==dfn[u])
        {
            cnt++;
            int d=0,v;
            do
            {
                v=st[top--];
                instack[v]=0;
                d=__gcd(d,m[v]);
                belong[v]=cnt;
                p[cnt].pb(v);
            }while(u!=v);
            g[cnt]=d;
        }
    }
    inline void work()
    {
        fo(i,1,n) if(!dfn[i]) dfs(i,0);
        fo(i,1,n)
            for(auto v:adj[i])
                if(belong[v]!=belong[i])
                    vec[belong[i]].pb(belong[v]);
        fo(i,1,cnt) sort(all(vec[i])),vec[i].resize(unique(all(vec[i]))-vec[i].begin());
        fo(u,1,cnt) for(auto v:vec[u]) in[v]++;
    }
    queue<int> q;
    inline void solve(int *mn,int *mx)
    {
        fo(i,1,n)
        {
            scanf("%s",t+1);
            fo(j,1,n) if(t[j]=='1') add(i,j);
        }
        fo(i,1,n)
        {
            m[i]=read();
            cin>>s[i];
            fo(j,0,m[i]-1) mn[i]+=(s[i][j]=='1');
        }
        work();
        fo(u,1,cnt) if(!in[u]) q.push(u);
        fo(u,1,cnt) now[u]=g[u];
        for(int u;!q.empty();)
        {
            u=q.front(); q.pop();
            for(auto i:p[u])
            {
                fo(j,0,m[i]-1)
                    if(s[i][j]=='1')
                        vis[u][j%g[u]]=1;
            }
            for(auto v:vec[u])
            {
                --in[v];
                if(!in[v])
                {
                    q.push(v);
                    now[v]=__gcd(now[u],now[v]);
                    fo(i,0,g[u]-1)
                        if(vis[u][i])
                            vi[i%now[v]]=1;
                    fo(i,0,now[v]-1)
                        if(vi[i])
                            for(int j=i;j<g[v];j+=now[v])
                                vis[v][j]=1;
                    fo(i,0,now[v]-1) vi[i]=0;
                }
            }
        }

        fo(i,1,cnt)
        {
            int sum=0;
            fo(j,0,g[i]-1) if(vis[i][j]) sum++;
            for(auto v:p[i]) mx[v]=(1ll*m[v]*sum)/g[i];
        }
    }
}
const ll mod=1e9+7;
inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;}
inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;}
inline ll Mul(ll x,ll y){return x*y%mod;}
inline ll Pow(ll x,ll y){y%=(mod-1);ll ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1) ans=ans*x%mod;return ans;}
namespace Part2{
    ll fac[N],inv[N];
    inline void init(int n)
    {
        fac[0]=1;
        fo(i,1,n) fac[i]=fac[i-1]*i%mod;
        inv[n]=Pow(fac[n],mod-2);
        fd(i,n,1) inv[i-1]=inv[i]*i%mod;
    }
    inline ll C(int n,int m)
    {
        return fac[n]*inv[m]%mod*inv[n-m]%mod;
    }
    inline ll solve(int *l,int *r,int A,int B)
    {
        A=min(A,n);
        init(n);
        ll x,y,ans=0;
        fo(i,1,n)
        {
            x=y=0;
            fo(j,1,n)
            {
                if(l[j]>r[i]) x++;
                if(l[j]<=r[i]&&((r[i]<r[j])||(r[i]<=r[j]&&i>j))) y++;//???
            }
            if(x>=A) continue;
            int tmp=min(y,A-1-x);
            tmp=min(B-1,tmp);
            fo(j,0,tmp)
                if(B-j-1<=x)
                    ans=Add(ans,Mul(C(y,j),C(x,B-j-1)));
        }
        return ans;
    }
}
int A,B;
int mi[N],mx[N];
int main()
{
    n=read(); A=read(); B=read();
    Part1::solve(mi,mx);
    printf("%lld",Part2::solve(mi,mx,A,B));
    return 0;
}

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
#define MX 2000005
#define SIZE 5005
#define MOD 1000000007

using namespace std;
typedef long long int ll;
typedef pair <int,int> P;

char mp[SIZE][SIZE];
ll C[SIZE][SIZE];
vector <int> nd[SIZE];
vector <int> vs;
int cmb[SIZE];
bool use[SIZE];
char str[MX];
string A[SIZE];
string B[SIZE];
P pos[SIZE];
int n;

void init()
{
	for(int i=0;i<SIZE;i++)
	{
		C[i][0]=C[i][i]=1;
		for(int j=1;j<i;j++)
		{
			C[i][j]=C[i-1][j-1]+C[i-1][j];
			if(C[i][j]>=MOD) C[i][j]%=MOD;
		}
	}
}
int gcd(int x,int y)
{
	if(x==0) return y;
	return gcd(y%x,x);
}
void dfs(int v)
{
	use[v]=true;
	for(int i=0;i<n;i++) if(!use[i]&&mp[v][i]=='1') dfs(i);
	vs.push_back(v);
}
void rdfs(int v,int k)
{
	use[v]=true;
	cmb[v]=k;
	nd[k].push_back(v);
	for(int i=0;i<n;i++) if(!use[i]&&mp[i][v]=='1') rdfs(i,k);
}
int scc()
{
	memset(use,false,sizeof(use));
	for(int i=0;i<n;i++) if(!use[i]) dfs(i);
	memset(use,false,sizeof(use));
	int k=0;
	for(int i=n-1;i>=0;i--) if(!use[vs[i]]) rdfs(vs[i],k++);
	return k;
}
int main()
{
	init();
	int a,b;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=0;i<n;i++) scanf("%s",&mp[i]);
	for(int i=0;i<n;i++)
	{
		int DM;
		scanf("%d %s",&DM,&str);
		A[i]=str;
	}
	int sz=scc();
	int nm=0;
	for(int i=0;i<sz;i++)
	{
		//for(int j=0;j<nd[i].size();j++) printf("%d ",nd[i][j]);puts("");
		int g=i>0?B[i-1].size():0;
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			g=gcd(g,A[v].size());
		}
		for(int j=0;j<g;j++) B[i]+="0";
		if(i>0)
		{
			for(int j=0;j<B[i-1].size();j++)
			{
				if(B[i-1][j]=='1')
				{
					B[i][j%g]='1';
				}
			}
		}
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			for(int k=0;k<A[v].size();k++)
			{
				if(A[v][k]=='1')
				{
					B[i][k%g]='1';
				}
			}
		}
		for(int j=0;j<nd[i].size();j++)
		{
			int v=nd[i][j];
			int a=0,b=0;
			for(int k=0;k<A[v].size();k++)
			{
				if(A[v][k]=='1') a++;
				if(B[v][k%g]=='1') b++;
			}
			pos[nm++]=P(b,a);
		}
		//printf("%s\n",B[i].c_str());
	}
	sort(pos,pos+n);
	priority_queue <int> que;
	ll ret=0;
	int cnt=0;
	b--;
	for(int i=n-1;i>=0;i--)
	{
		P p=pos[i];
		while(!que.empty()&&que.top()>p.first)
		{
			cnt++;
			que.pop();
		}
		//printf("%d %d\n",i,cnt);
		for(int j=0;j<=min(b,cnt);j++)
		{
			int zb=b-j;
			if(zb<=que.size()&&b+(cnt-j)<=a)
			{
				ll way=C[que.size()][zb]*C[cnt][j]%MOD;
				ret+=way;
				if(ret>=MOD) ret-=MOD;
			}
		}
		que.push(p.second);
	}
	printf("%lld\n",ret);
	return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int n, a, b, s[5005];
string sta[5005], sta2[5005];
char adj[5005][5005];
int cnt;
vector<int> hv[5005];
int hdr = -1, nxt[25];
string cur[25];
PII dat[5005];

vector<int> ps;
bool vis[5005];
void dfs0(int v)
{
	vis[v] = true;
	rep(i, n) if(adj[v][i] == '1' && !vis[i]) dfs0(i);
	ps.push_back(v);
}
void dfs1(int v, vector<int>& chv)
{
	vis[v] = true;
	chv.push_back(v);
	rep(i, n) if(adj[i][v] == '1' && !vis[i]) dfs1(i, chv);
}

void gen_scc()
{
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[i]) dfs0(i);
	reverse(ps.begin(), ps.end());
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[ps[i]]) dfs1(ps[i], hv[cnt ++]);
}

int comb[5005][5005];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> a >> b;
	rep(i, n) cin >> adj[i];
	rep(i, n) {
		cin >> s[i] >> sta[i];
		sta2[i].resize(s[i], '0');
	}
	gen_scc();

	memset(nxt, -1, sizeof(nxt));
	rep(i, cnt) {
		rep(j, 25) if(cur[j].empty()) {
			nxt[j] = hdr;
			hdr = j;
			break;
		}
		int cg = 0;
		rep(j, hv[i].size()) cg = __gcd(cg, s[hv[i][j]]);
		cur[hdr].resize(cg, '0');
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) cur[hdr][k % cg] |= sta[gan][k];
		}
		for(int j = hdr; j != -1; j = nxt[j]) {
			int nsiz = __gcd(cg, (int)cur[j].length());
			if(nsiz == cur[j].length()) continue;
			for(int k = nsiz; k < cur[j].length(); k ++) cur[j][k % nsiz] |= cur[j][k];
			cur[j].resize(nsiz);
		}
		for(int j = hdr; j != -1; j = nxt[j])
		while(nxt[j] != -1 && cur[nxt[j]].length() == cur[j].length()) {
			int nj = nxt[j];
			rep(k, cur[j].length()) cur[j][k] |= cur[nj][k];
			cur[nj].clear();
			nxt[j] = nxt[nj];
			nxt[nj] = -1;
		}
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) for(int l = hdr; l != -1; l = nxt[l]) sta2[gan][k] |= cur[l][k % cur[l].length()];
		}
	}

	rep(i, n) rep(j, s[i]) {
		if(sta[i][j] == '1') dat[i].second ++;
		if(sta2[i][j] == '1') dat[i].first ++;
	}

	comb[0][0] = 1;
	rep1(i, n) {
		comb[i][0] = 1;
		rep1(j, n) comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
	}

	sort(dat, dat + n);
	int ans = 0;
	for(int i = n - 1; i >= 0; i --) {
		int cnt0 = a - b, cnt1 = 0;
		rep(j, i) if(dat[j].second > dat[i].first) cnt0 --;
		for(int j = i + 1; j < n; j ++) if(dat[j].second > dat[i].first) cnt1 ++;
		for(int j = cnt1 - cnt0; j <= min(cnt1, b - 1); j ++)
		ans = (ans + 1LL * comb[cnt1][j] * comb[n - 1 - cnt1][b - 1 - j]) % MOD;
	}
	printf("%d\n", ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=2e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[N];
char truegold[N];
int gold[N];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]=='1'){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j]=='1';
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
#define N 5005
using namespace std;
int n,a,b,s[N],sz[N],C[N][N],Ans;char c[2000005];
short to[N*N],fr[N*N];int nxt[N*N],fst[N],l;
int st[N],top,bl[N],cnt,dfn[N],low[N],clk;
vector<short>p[N],v[N],e[N];
struct T
{
	int x,y;
}d[N];
int cmp(T a,T b)
{
	return a.y==b.y?a.x>b.x:a.y>b.y;
}

void link(int x,int y)
{
	to[++l]=y;fr[l]=x;nxt[l]=fst[x];fst[x]=l;
}
void dfs(int x)
{
	low[x]=dfn[x]=++clk;
	st[++top]=x;
	for (int i=fst[x];i;i=nxt[i])
		if (!dfn[to[i]])
		{
			dfs(to[i]);
			low[x]=min(low[x],low[to[i]]);
		}
		else if (!bl[to[i]])
			low[x]=min(low[x],low[to[i]]);

	if (low[x]==dfn[x])
	{
		cnt++;
		while(st[top]!=x)
		{
			//p[cnt].push_back(st[top]);
			bl[st[top--]]=cnt;
		}
		//p[cnt].push_back(st[top]);
		bl[st[top--]]=cnt;
	}
}
short _to[N*N];int _nxt[N*N],_fst[N],_l,rd[N];
void lk(int x,int y)
{
	_to[++_l]=y;_nxt[_l]=_fst[x];_fst[x]=_l;rd[y]++;
}
vector<short>tp;
void work(int x)
{
	rd[x]=-1;
	for (int i=_fst[x];i;i=_nxt[i])
	{
		rd[_to[i]]--;
		if (rd[_to[i]]==0)
		{
			int tmp=__gcd(sz[x],sz[_to[i]]);
			tp.clear();
			for (int j=0;j<tmp;j++)tp.push_back(0);
			for (int j=0;j<sz[x];j++)
				if (e[x][j]) tp[j%tmp]=1;
			for (int j=0;j<sz[_to[i]];j++)
				if (tp[j%tmp]) e[_to[i]][j]=1;
			work(_to[i]);
		}
	}
}
int bit[2000005];
void add(int x)
{
	x++;
	for (;x<=2000002;x+=x&-x)
		bit[x]++;
}
int qry(int x)
{
	x++;
	int ans=0;
	for (;x;x-=x&-x)
		ans+=bit[x];
	return ans;
}
int main()
{

	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		for (int j=1;j<=n;j++)
		{
			if (c[j]=='1')
				link(i,j);
		}
	}
	for (int i=1;i<=n;i++)
		if (!dfn[i])
			dfs(i);

	int Mx=0;
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);Mx=max(Mx,s[i]);
		sz[bl[i]]=__gcd(sz[bl[i]],s[i]);
		p[bl[i]].push_back(i);
		scanf("%s",c+1);
		for (int j=1;j<=s[i];j++)
		{
			v[i].push_back(c[j]=='1');
			d[i].x+=c[j]=='1';
		}
	}
	for (int i=1;i<=cnt;i++)
	{
		for (int j=0;j<sz[i];j++)
			e[i].push_back(0);
		for (int j=0;j<p[i].size();j++)
		{
			for (int k=0;k<v[p[i][j]].size();k++)
			if (v[p[i][j]][k])
				e[i][k%sz[i]]=1;
		}
	}
	for (int i=1;i<=l;i++)
		if (bl[fr[i]]!=bl[to[i]])
			lk(bl[fr[i]],bl[to[i]]);

	for (int i=1;i<=cnt;i++)
		if (rd[i]==0) work(i);

	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<s[i];j++)
			if (v[i][j]||e[bl[i]][j%sz[bl[i]]]) d[i].y++;
	}
	sort(d+1,d+n+1,cmp);

	C[0][0]=1;
	for (int i=1;i<=n;i++)
	{
		C[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
		}
	}
	for (int i=1;i<=n;i++)
	{
		if (i>=b)
		{
			if (i<=a) Ans=(Ans+C[i-1][b-1])%P;
			else
			{
				int u=qry(d[i].y),v=i-1-u;
				for (int j=0;j<=u&&j<b;j++)
				{
					if (v+j+1<=a)
						Ans=(Ans+(ll)C[u][j]*C[v][b-j-1])%P;
				}
			}
		}
		add(d[i].x);
	}/*
	cerr<<Ans<<endl;
	cerr<<Mx<<' '<<d[1].x<<' '<<d[1].y<<' '<<cnt<<endl;
	*/
	printf("%d\n",Ans);

}

#include <cstdio>
#include <vector>

const int MAXN = 5e3, MOD = 1e9 + 7;
int n, s[MAXN + 5], A, B, mng[MAXN + 5], mxg[MAXN + 5];
int fac[MAXN + 5], ifac[MAXN + 5];
std::vector<int> adj[MAXN + 5];
std::vector<bool> gold[MAXN + 5];
int dfc, top, dfn[MAXN + 5], low[MAXN + 5], stk[MAXN + 5];
bool instk[MAXN + 5];
int scc, bel[MAXN + 5], siz[MAXN + 5], cnt[MAXN + 5];
std::vector<bool> apr[MAXN + 5];
int ans;

inline void chkmin ( int& a, const int b ) { if ( b < a ) a = b; }

inline int rint () {
	int x = 0; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () );
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
	return x;
}

inline int gcd ( const int a, const int b ) { return b ? gcd ( b, a % b ) : a; }

inline int qkpow ( int a, int b, const int p = MOD ) {
	int ret = 1;
	for ( ; b; a = 1ll * a * a % p, b >>= 1 ) ret = 1ll * ret * ( b & 1 ? a : 1 ) % p;
	return ret;
}

inline void Tarjan ( const int u ) {
	dfn[u] = low[u] = ++ dfc, instk[stk[++ top] = u] = true;
	for ( int v: adj[u] ) {
		if ( ! dfn[v] ) {
			Tarjan ( v );
			chkmin ( low[u], low[v] );
		} else if ( instk[v] ) {
			chkmin ( low[u], dfn[v] );
		}
	}
	if ( dfn[u] == low[u] ) {
		int v; ++ scc;
		do {
			instk[v = stk[top --]] = false;
			bel[v] = scc;
		} while ( v ^ u );
	}
}

inline void input () {
	n = rint (), A = rint (), B = rint ();
	char tmp[MAXN + 5];
	for ( int i = 1; i <= n; ++ i ) {
		scanf ( "%s", tmp + 1 );
		for ( int j = 1; j <= n; ++ j ) {
			if ( tmp[j] ^ '0' ) {
				adj[i].push_back ( j );
			}
		}
	}
	for ( int i = 1; i <= n; ++ i ) {
		gold[i].resize ( s[i] = rint () );
		scanf ( "%s", tmp );
		for ( int j = 0; j < s[i]; ++ j ) {
			mng[i] += gold[i][j] = tmp[j] ^ '0';
		}
	}
}

inline void init () {
	fac[0] = 1;
	for ( int i = 1; i <= n; ++ i ) fac[i] = 1ll * i * fac[i - 1] % MOD;
	ifac[n] = qkpow ( fac[n], MOD - 2 );
	for ( int i = n - 1; ~ i; -- i ) ifac[i] = ( i + 1ll ) * ifac[i + 1] % MOD;
}

inline int comb ( const int n, const int m ) {
	return n < 0 || m < 0 || n < m ?
		0 : 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}

inline void calcBound () {
	for ( int i = 1; i <= n; ++ i ) {
		if ( ! dfn[i] ) {
			Tarjan ( i );
		}
	}
	for ( int i = 1; i <= n; ++ i ) siz[bel[i]] = gcd ( s[i], siz[bel[i]] );
	for ( int i = 1; i <= scc; ++ i ) apr[i].resize ( siz[i] );
	for ( int i = 1; i <= n; ++ i ) {
		for ( int j = 0; j < s[i]; ++ j ) {
			if ( gold[i][j] ) {
				apr[bel[i]][j % siz[bel[i]]] = true;
			}
		}
	}
	std::vector<bool> tmp;
	for ( int i = scc; i > 1; -- i ) {
		int d = gcd ( siz[i], siz[i - 1] );
		tmp.clear (), tmp.resize ( d );
		for ( int j = 0; j < siz[i]; ++ j ) tmp[j % d] = tmp[j % d] | apr[i][j];
		for ( int j = 0; j < siz[i - 1]; ++ j ) apr[i - 1][j] = apr[i - 1][j] | tmp[j % d];
	}
	for ( int i = 1; i <= scc; ++ i ) for ( bool g: apr[i] ) cnt[i] += g;
	for ( int i = 1; i <= n; ++ i ) mxg[i] = s[i] / siz[bel[i]] * cnt[bel[i]];
}

inline void solve () {
	for ( int i = 1; i <= n; ++ i ) {
		int big = 0, crs = 0;
		for ( int j = 1; j <= n; ++ j ) {
			if ( i == j ) continue;
			if ( mxg[i] < mng[j] ) ++ big;
			if ( mng[j] <= mxg[i] && mxg[i] <= mxg[j] ) ++ crs;
		}
		for ( int j = B - big - 1 > 0 ? B - big - 1 : 0;
			j <= crs && j <= B - 1 && j <= A - big - 1; ++ j ) {
			ans = ( ans + 1ll * comb ( crs, j ) * comb ( big, B - j - 1 ) ) % MOD;
		}
	}
}

int main () {
	input (), init ();
	calcBound ();
	solve ();
	printf ( "%d\n", ans );
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXN 5005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}

stack <int> S;
vector <int> g[MAXN],f[MAXN];
int top = 1,to[MAXN << 1],nxt[MAXN << 1],head[MAXN];
int n,k1,k2,cnt,Index,s[MAXN],mn[MAXN],mx[MAXN],bg[MAXN],dfn[MAXN],low[MAXN],bel[MAXN],vis[MAXN],tot[MAXN];

int gcd (int a,int b){return !b ? a : gcd (b,a % b);}
void Add_Edge (int u,int v){to[++ top] = v,nxt[top] = head[u],head[u] = top;}
void Tarjan (int u){
	S.push (u),dfn[u] = low[u] = ++ Index,vis[u] = 1;
	for (Int i = head[u],v;i;i = nxt[i]){
		v = to[i];
		if (!dfn[v]){
			Tarjan (v);
			low[u] = min (low[u],low[v]);
		}
		else if (vis[v]) low[u] = min (low[u],dfn[v]);
	}
	if (dfn[u] == low[u]){
		++ cnt;
		while (1){
			int now = S.top();S.pop ();
			vis[now] = 0,bel[now] = cnt,bg[cnt] = gcd (bg[cnt],s[now]);
			if (u == now) break;
		}
	}
}

char str[MAXN];

void Putin (){
	read (n,k1,k2);
	for (Int i = 1;i <= n;++ i){
		scanf ("%s",str + 1);
		for (Int j = 1;j <= n;++ j) if (str[j] == '1') Add_Edge (i,j);
	}
	for (Int i = 1;i <= n;++ i){
		read (s[i]),scanf ("%s",str + 1);
		for (Int j = 1;j <= s[i];++ j) g[i].push_back (str[j] - '0'),mn[i] += str[j] - '0';
	}
}

namespace Part1{
	void Solve (){
		for (Int i = 1;i <= n;++ i) if (!dfn[i]) Tarjan (i);
		for (Int i = 1;i <= cnt;++ i) f[i].resize (bg[i] + 1);
		for (Int i = 1;i <= n;++ i) for (Int j = 0;j < s[i];++ j) f[bel[i]][j % bg[bel[i]]] |= g[i][j];
		for (Int i = cnt;i > 1;-- i){
			int now = gcd (bg[i],bg[i - 1]);
			for (Int j = 0;j < bg[i];++ j) f[i - 1][j % now] |= f[i][j],tot[i] += f[i][j];
		}
		for (Int i = 0;i < bg[1];++ i) tot[1] += f[1][i];
		for (Int i = 1;i <= n;++ i) mx[i] = 1ll * tot[bel[i]] * s[i] / bg[bel[i]];
	}
}

namespace Part2{
#define mod 1000000007
	int fac[MAXN],ifac[MAXN];
	int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
	int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
	int qkpow (int a,int b){int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;return res;}
	int binom (int a,int b){return a < b ? 0 : 1ll * fac[a] * ifac[b] % mod * ifac[a - b] % mod;}
	void Solve (){
		fac[0] = 1;for (Int i = 1;i <= n;++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
		ifac[n] = qkpow (fac[n],mod - 2);for (Int i = n;i;-- i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
		int ans = 0;
		for (Int i = 1;i <= n;++ i){
			int cnt1 = 0,cnt2 = 0;
			for (Int j = 1;j <= n;++ j){
				if (i == j) continue;
				else if (mx[i] < mn[j]) cnt1 ++;
				else if (mx[i] < mx[j] || (mx[i] == mx[j] && i < j)) cnt2 ++;
			}
			if (cnt1 >= k1) continue;
			for (Int j = min (k2,min (k1 - 1 - cnt1,cnt2));j + cnt1 + 1 >= cnt2;-- j) ans = add (ans,1ll * binom (cnt1,k2 - j - 1) * binom (cnt2,j) % mod);
		}
		write (ans),putchar ('\n');
	}
#undef mod
}

signed main(){
	Putin (),Part1::Solve (),Part2::Solve ();
	return 0;
}

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

#define DB double
#define LL long long
#define MAXN 5000
#define MOD 998244353
#define Pr pair<int,int>
#define X first
#define Y second
#define INF 1000000001
#define mem(x,v) memset(x,v,sizeof(x))

LL read(){
	LL x=0,F=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')F=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*F;
}

int add(int a,int b){return (a+b>=MOD)?a+b-MOD:a+b;}
int dec(int a,int b){return (a-b<0)?a-b+MOD:a-b;}
int mul(int a,int b){return (1LL*a*b)%MOD;}
int fst_pow(int a,int b){
	int res=1;
	while(b){
		if(b&1)res=mul(res,a);
		a=mul(a,a),b>>=1;
	}
	return res;
}

int n,a,b;
vector<int> G[MAXN+5],P[MAXN+5],T[MAXN+5],tmp;
char s[MAXN+5];
int stk[MAXN+5],low[MAXN+5],dfn[MAXN+5],tp;
int bel[MAXN+5],gval[MAXN+5],bcnt,ct;
int num[MAXN+5],cnt[MAXN+5],L[MAXN+5],R[MAXN+5];
int fac[MAXN+5],ifac[MAXN+5],ans;

int gcd(int a,int b){return (!b)?a:gcd(b,a%b);}

void tarjan(int x){
	stk[++tp]=x,dfn[x]=low[x]=++ct;
	for(int i=0;i<G[x].size();i++){
		int v=G[x][i];
		if(!dfn[v]){
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else if(!bel[v])low[x]=min(low[x],dfn[v]);
	}
	if(low[x]==dfn[x]){
		int v;bcnt++;
		do{
			v=stk[tp],bel[v]=bcnt,tp--;
			gval[bcnt]=gcd(gval[bcnt],num[v]);
		}while(v!=x);
		T[bcnt].resize(gval[bcnt]);
	}
}

void prepare(){
	fac[0]=1;
	for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
	ifac[n]=fst_pow(fac[n],MOD-2);
	for(int i=n;i>=1;i--)ifac[i-1]=mul(ifac[i],i);
}
int Comb(int a,int b){
	if(b>a||a<0||b<0)return 0;
	return mul(fac[a],mul(ifac[b],ifac[a-b]));
}

int main(){
	n=read(),a=read(),b=read();
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		for(int j=1;j<=n;j++)
		if(s[j]=='1')G[i].push_back(j);
	}
	for(int i=1;i<=n;i++){
		num[i]=read();
		scanf("%s",s);
		for(int j=0;j<num[i];j++)
		P[i].push_back(s[j]-'0');
	}

	for(int i=1;i<=n;i++)
	if(!dfn[i])tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<num[i];j++)
		T[bel[i]][j%gval[bel[i]]]|=P[i][j];
	for(int i=bcnt;i>1;i--){
		int tg=gcd(gval[i],gval[i-1]);
		tmp.clear(),tmp.resize(tg);
		for(int j=0;j<gval[i];j++)tmp[j%tg]|=T[i][j];
		for(int j=0;j<gval[i-1];j++)T[i-1][j]|=tmp[j%tg];
	}
	for(int i=1;i<=bcnt;i++)
		for(int j=0;j<gval[i];j++)cnt[i]+=T[i][j];
	for(int i=1;i<=n;i++){
		R[i]=cnt[bel[i]]*(num[i]/gval[bel[i]]);
		for(int j=0;j<num[i];j++)L[i]+=P[i][j];
		//printf("%d %d\n",L[i],R[i]);
	}

	prepare();
	for(int i=1;i<=n;i++){
		int A=0,B=0;
		for(int j=1;j<=n;j++)
		if(L[j]>R[i])A++;
		else if(R[j]>R[i]||(R[i]==R[j]&&j>i))B++;//***
		if(A>=a)continue;
		for(int j=0;j<=B;j++)
		ans=add(ans,mul(Comb(B,j),Comb(A,b-j-1)));
	}

	printf("%d\n",ans);
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 10005, MAXE = 5005 * 5005 >> 1;

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	scanf( "%d %d %d", &N, &A, &B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		scanf( "%d", &s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}
	init( siz + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		rig[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) cnt1 ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = MIN( B, MIN( A - 1 - cnt1, cnt2 ) ) ; j + cnt1 + 1 >= B ; -- j )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	printf( "%d\n", ans );
	return 0;
}

/*Lucky_Glass*/
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

inline int Getc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}

#define cs const int &
const int N=5e3+10,MOD=1e9+7;

inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],du[N],ncnt;
	void AddEdge(cs u,cs v){
		//printf("%d -> %d\n",u,v);
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
		du[v]++;
	}
	inline int operator [](cs u){return head[u];}
}Gr,Fr;

int n,A,B,ndfn,nstk,nscc;
int siz[N],tmp[N];
int dfn[N],low[N],stk[N],scc[N],exsiz[N];bool ins[N];
bool ban[N];
int fac[N],ifac[N];
bool edg[N][N];
vector<int> hav[N],bel[N],exhav[N];
queue<int> que;
pair<int,int> res[N];

int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
bool cmp(cs a,cs b){
	if(res[a].second!=res[b].second) return res[a].second>res[b].second;
	return a>b;
}
inline int C(cs a,cs b){return a>b? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Tarjan(int u){
	low[u]=dfn[u]=++ndfn;
	stk[++nstk]=u;ins[u]=true;
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(ins[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		exsiz[++nscc]=-1;
		int tmp=0;
		do{
			tmp=stk[nstk--];
			scc[tmp]=nscc,bel[nscc].push_back(tmp);
			if(~exsiz[nscc]) exsiz[nscc]=GCD(exsiz[nscc],siz[tmp]);
			else exsiz[nscc]=siz[tmp];
			ins[tmp]=false;
		}while(tmp!=u);
	}
}
int main(){
	n=Read(),A=Read(),B=Read();
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(Getc())
				Gr.AddEdge(i,j);
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		int cnt=0;
		for(int j=1;j<=siz[i];j++)
			if(Getc())
				hav[i].push_back(j),cnt++;
		res[i].first=res[i].second=cnt;
	}
	for(int i=1;i<=n;i++)
		if(!scc[i])
			Tarjan(i);
	for(int u=1;u<=n;u++)
		for(int it=Gr[u];it;it=Gr.nxt[it]){
			int v=Gr.to[it];
			if(scc[u]!=scc[v] && !edg[scc[u]][scc[v]]){
				edg[scc[u]][scc[v]]=true;
				Fr.AddEdge(scc[u],scc[v]);
			}
		}
	for(int i=1;i<=nscc;i++){
		for(int j=bel[i].size()-1;j>=0;j--){
			int u=bel[i][j];
			for(int k=hav[u].size()-1;k>=0;k--)
				ban[hav[u][k]%exsiz[i]]=true;
		}
		for(int j=0;j<exsiz[i];j++)
			if(ban[j]){
				exhav[i].push_back(j);
				ban[j]=false;
			}
	}
	for(int i=1;i<=nscc;i++)
		if(!Fr.du[i]){
			que.push(i);
			break;
		}
	while(!que.empty()){
		int u=que.front(),tu=-1;que.pop();
		for(int i=0;i<exsiz[u];i++) tmp[i]=0;
		for(int i=exhav[u].size()-1;i>=0;i--) tmp[exhav[u][i]]=1;
		for(int i=bel[u].size()-1;i>=0;i--){
			int it=bel[u][i],cnt=0;
			for(int j=1;j<=siz[it];j++)
				cnt+=tmp[j%exsiz[u]];
			res[it].second=cnt;
		}
		for(int it=Fr[u];it;it=Fr.nxt[it]){
			int v=Fr.to[it];
			if((--Fr.du[v])==0)
				que.push(v),tu=v;
		}
		if(tu==-1) continue;
		int tsiz=GCD(exsiz[u],exsiz[tu]);
		for(int i=0;i<tsiz;i++) tmp[i]=0;
		for(int i=0,li=exhav[u].size();i<li;i++)
			tmp[exhav[u][i]%tsiz]=1;
		for(int i=exhav[tu].size()-1;i>=0;i--)
			ban[exhav[tu][i]]=true;
		int extr=0;
		for(int i=0;i<exsiz[tu];i++){
			if(ban[i]){ban[i]=false;continue;}
			if(tmp[i%tsiz]) exhav[tu].push_back(i);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("? %d %d\n",res[i].first,res[i].second);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(res[j].first>res[i].second) mus++;
			if(cmp(j,i)) may++;
		}
		if(mus>=A) continue;
		ans=Add(ans,C(B-1,may));
	}
	printf("%d\n",ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N=1e4+5;
const ll M=4e6+5;
const ll mod=1e9+7;
typedef long long ll;
struct node{
    ll v,nxt;
}edge[N*N/4];
ll head[N],mcnt;
void add_edge(ll u,ll v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
ll ksm(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
ll gcd(ll x,ll y){
    return y?gcd(y,x%y):x;
}
ll scnt,scc[N],sgcd[N];
ll S[N],top;
ll dfn[N],low[N],tot;
bool instack[N];
ll sz[N];
void Tarjan(ll u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=true;
    for(ll i=head[u];i;i=edge[i].nxt){
        ll v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        ll x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
ll fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(ll i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(ll i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(ll i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
ll C(ll x,ll y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[N];
char truegold[N];
ll gold[N];
ll sum1[N],sum2[N];
ll num[N];
ll mx[N],mn[N];
ll n,a,b;
int main()
{
    Init();
    scanf("%I64d%I64d%I64d",&n,&a,&b);
    for(ll i=1;i<=n;i++){
        scanf("%s",s+1);
        for(ll j=1;j<=n;j++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(ll i=1;i<=n;i++){
        scanf("%I64d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",s);
        for(ll j=0;j<sz[i];j++){
            truegold[sum1[i]+j]=s[j]-'0';
        }
    }
    for(ll i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(ll i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(ll i=1;i<=n;i++){
        for(ll j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(ll i=scnt;i>1;i--){
        ll G=gcd(sgcd[i],sgcd[i-1]);
        for(ll j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(ll j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(ll i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(ll j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j];
    }
    ll ans=0;
    for(ll i=1;i<=n;i++){
        ll c1=0,c2=0;
        for(ll j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(ll j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(ll j=max(b-c1-1,0ll);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%I64d\n",ans);
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[i]*inv[j]%mod*inv[i-(j)]%mod)

int main(){
	//freopen("1.in","r",stdin);
	//freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        // printf ("")
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<now[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<now[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
		printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
        //printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        // printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));~j;--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 5005, MAXE = MAXN * MAXN >> 1;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int C[MAXN][MAXN];

int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int main()
{
	read( N ), read( A ), read( B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		read( s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		rig[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	for( int i = 0 ; i <= N ; i ++ )
	{
		C[i][0] = C[i][i] = 1;
		for( int j = 1 ; j < i ; j ++ )
			C[i][j] = ( C[i - 1][j] + C[i - 1][j - 1] ) % mod;
	}

	int ans = 0, con, uncon;
	for( int i = 1 ; i <= N ; i ++ )
	{
		con = uncon = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) con ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) uncon ++;
			}
		if( con > A - 1 ) continue;
		for( int j = B - con - 1 ; j <= MIN( B, MIN( uncon, A - con - 1 ) ) ; j ++ )
			ans = ( ans + 1ll * C[uncon][j] * C[con][B - j - 1] % mod ) % mod;
	}
	write( ans ), putchar( '\n' );
	return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 1e9 + 7;

int n, a, b, s[5005];
string sta[5005], sta2[5005];
char adj[5005][5005];
int cnt;
vector<int> hv[5005];
int hdr = -1, nxt[25];
string cur[25];
PII dat[5005];

vector<int> ps;
bool vis[5005];
void dfs0(int v)
{
	vis[v] = true;
	rep(i, n) if(adj[v][i] == '1' && !vis[i]) dfs0(i);
	ps.push_back(v);
}
void dfs1(int v, vector<int>& chv)
{
	vis[v] = true;
	chv.push_back(v);
	rep(i, n) if(adj[i][v] == '1' && !vis[i]) dfs1(i, chv);
}

void gen_scc()
{
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[i]) dfs0(i);
	reverse(ps.begin(), ps.end());
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[ps[i]]) dfs1(ps[i], hv[cnt ++]);
}

int comb[5005][5005];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> a >> b;
	rep(i, n) cin >> adj[i];
	/*
	rep(i, n) {
		cin >> s[i] >> sta[i];
		sta2[i].resize(s[i], '0');
	}
	gen_scc();

	memset(nxt, -1, sizeof(nxt));
	rep(i, cnt) {
		rep(j, 25) if(cur[j].empty()) {
			nxt[j] = hdr;
			hdr = j;
			break;
		}
		int cg = 0;
		rep(j, hv[i].size()) cg = __gcd(cg, s[hv[i][j]]);
		cur[hdr].resize(cg, '0');
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) cur[hdr][k % cg] |= sta[gan][k];
		}
		for(int j = hdr; j != -1; j = nxt[j]) {
			int nsiz = __gcd(cg, (int)cur[j].length());
			if(nsiz == cur[j].length()) continue;
			for(int k = nsiz; k < cur[j].length(); k ++) cur[j][k % nsiz] |= cur[j][k];
			cur[j].resize(nsiz);
		}
		for(int j = hdr; j != -1; j = nxt[j])
		while(nxt[j] != -1 && cur[nxt[j]].length() == cur[j].length()) {
			int nj = nxt[j];
			rep(k, cur[j].length()) cur[j][k] |= cur[nj][k];
			cur[nj].clear();
			nxt[j] = nxt[nj];
			nxt[nj] = -1;
		}
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) for(int l = hdr; l != -1; l = nxt[l]) sta2[gan][k] |= cur[l][k % cur[l].length()];
		}
	}

	rep(i, n) rep(j, s[i]) {
		if(sta[i][j] == '1') dat[i].second ++;
		if(sta2[i][j] == '1') dat[i].first ++;
	}

	comb[0][0] = 1;
	rep1(i, n) {
		comb[i][0] = 1;
		rep1(j, n) comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
	}
	*/

	rep(i, n) cin >> dat[i].first >> dat[i].second;

	sort(dat, dat + n);
	int ans = 0;
	for(int i = n - 1; i >= 0; i --) {
		int cnt0 = a - b, cnt1 = 0;
		rep(j, i) if(dat[j].second > dat[i].first) cnt0 --;
		for(int j = i + 1; j < n; j ++) if(dat[j].second > dat[i].first) cnt1 ++;
		for(int j = max(cnt1 - cnt0, 0); j <= min(cnt1, b - 1); j ++)
		ans = (ans + 1LL * comb[cnt1][j] * comb[n - 1 - cnt1][b - 1 - j]) % MOD;
	}
	cout << ans << endl;
	return 0;
}

#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
const int N = 5001;
int n, a, b;
namespace hamilton_path_for_competition_map{
    vector<vector<bool> > edge;
    vector<int> d;
    bool expand(int x, int n) {
        d.resize(0);
        d.push_back(x);
        for (int i = 0; i < n; i ++)
            if (i != x) {
                if (edge[d[d.size() - 1]][i]) d.push_back(i);
                else {
                    int x = 0;
                    while (edge[d[x]][i])
                        x ++;
                    d.push_back(i);
                    rotate(d.begin() + x, d.end() - 1, d.end());
                }
            }
        if (d.size() == n) return 1;
        return 0;
    }
    vector<int> construct(vector<vector<bool> >_edge, int n) {
        edge = _edge;
        for (int i = 0; i < n; i ++)
            if (expand(i, n)) {
                return d;
            }
        d.resize(0);
        return d;
    }
}
typedef long long ll;
const int mod = 1e9 + 7;
ll calc(ll x, ll y){
    ll z = 1;
    while (y) {
        if (y & 1) z = z * x % mod;
        x = x * x % mod, y /= 2;
    }
    return z;
}
namespace C{
    const int mod = 1e9+7;
    vector<int>a, nia;
    void pre(int n){
        a = vector<int>(n + 1, 1);
        nia = vector<int>(n + 1, 1);
        for (int i = 2; i <= n; i ++)
            a[i] = 1ll * a[i - 1] * i % mod;
        nia[n] = calc(a[n], mod - 2);
        for (int i = n - 1; i >= 2; i --)
            nia[i] = 1ll * nia[i + 1] * (i + 1) % mod;
    }
    ll C(ll x, ll y) {
        if (x < y || y < 0) return 0;
        return 1ll * a[x] * nia[y] % mod * nia[x - y] % mod;
    }
}
namespace count{//�������li��ri��Χ����ǰa������ѡb���Ĳ�ͬ�ļ�����
    const int mod = 1e9+7;
    const int N = 2e6 + 1;
    int gao(vector<pair<int, int> > d, int a, int b) {
        sort(d.begin(), d.end(), [](pair<int, int> a, pair<int, int> b) {
            return a.first < b.first;
        });
        C::pre(d.size());
        if (n > 10) return 0;
        if (a == d.size()) {
            return C::C(a, b);
        }
        int ans = 0;
        if (b == 1) {
            vector<bool> bz(d.size(), 0);
            for (int i = 0; i < d.size(); i++) {
                for (int j = 0; j < i; j++)
                    if (d[j].second >= d[i].first) {
                        bz[j] = 1;
                    }
            }
            for (int i = 1; i <= a && i <= d.size(); i ++)
                bz[d.size() - i] = 1;
            for (auto u:bz)
                ans += u;
        } else {
            ans = 1;
            for (int i = 0; i < d.size(); i++) {
                int sum = 0;
                for (int j = 0; j < i; j++)
                    if (d[j].second >= d[i].first) {
                        ++sum;
                    }
                ans = (ans + 1ll * sum * C::C((d.size() - i - 2), b - 2)) % mod;
            }
        }
        return ans;
    }
}
int id[N];
int fa[N], c[2000001];
vector<int>w[N];
int getfa(int x) {
    return fa[x] == x? x : fa[x] = getfa(fa[x]);
}
int main() {
    scanf("%d %d %d", &n, &a, &b);
    vector<vector<bool> > edge(n, vector<bool>(n));
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < n ; j ++) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            if (c =='1') edge[i][j] = 1;
        }
    }
    vector<int>d = hamilton_path_for_competition_map::construct(edge, n);
    for (int i = 0; i < d.size();  i ++)
        id[d[i]] = i, fa[i] = i;
    for (int u = 0; u < n ; u ++) {
        int tmp = u;
        for (int v = 0; v < n; v++)
            if (edge[d[u]][v]) {
                tmp = min(tmp, id[v]);
            }
        for (int i = tmp; i < u; i ++)
            if (getfa(d[i]) != d[u]) {
                fa[getfa(d[i])] = d[u];
            }
    }
    vector<vector<int> > g(n, vector<int>(0));
    for (int i = 0; i < n; i ++)
        g[getfa(i)].push_back(i);
    for (int i = 0; i < n; i ++) {
        int x;
        scanf("%d", &x);
        while (x --) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            w[i].push_back(c - '0');
        }
    }
    vector<int> dd(0);
    for (auto u:d)
        if (getfa(u) == u)
            dd.push_back(u);
    for (int i = 0; i < dd.size(); i ++) {
        int u = dd[i];
        int gcd = 0;
        for (auto v:g[u]) {
            int tmp = w[v].size();
            gcd = __gcd(tmp, gcd);
        }
        for (int i = 0; i < gcd; i++)
            c[i] = 0;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (w[v][i])
                    c[i % gcd] = 1;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (!w[v][i] && c[i % gcd])
                    w[v][i] = 2;
        if (i != dd.size() - 1) {
            int v = dd[i + 1];
            int tmp = w[v].size();
            int gcd1 = __gcd(tmp, gcd);
            for (int i = 0; i < gcd1; i ++)
                for (int j = 0; j * gcd1 + i < gcd; j ++)
                    c[i] |= c[i + j * gcd1];
            for (int i = 0; i < w[v].size(); i ++)
                if (!w[v][i] && c[i % gcd1])
                    w[v][i] = 2;
        }
    }
    vector<pair<int, int> > f;
    for (int i = 0; i < n; i ++) {
        int l = 0, r = 0;
        for (auto u:w[i])
            if (u == 1) l ++, r ++;
            else
                if (u == 2) r ++;
        f.push_back(make_pair(l, r));
    }
    printf("%d\n",count::gao(f, a, b));
    return 0;
}

#include<bits/stdc++.h>
#define LL int
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], fac[maxn], ifac[maxn];
void input() {
char str[(int)(2e6) + 2];
scanf("%d %d %d", &n, &A, &B);
for (int i = 1; i <= n; ++i) {
scanf("%s", str + 1);
for (int j = 1; j <= n; ++j)
if (str[j] == '1')
g[i].push_back(j);}
for (int i = 1; i <= n; ++i) {
scanf("%d %s", &s[i], str);
city[i].resize(s[i]);
for (int j = 0; j < s[i]; ++j)
city[i][j] = str[j] - '0';}}
LL qpow(LL a, LL b) {
LL res(1);
while (b) {
if (b & 1)res = res * a % MOD;
a = a * a % MOD;
b >>= 1;}
return res;}
void init() {
fac[0] = 1;
int N = maxn - 3;
for (int i = 1; i <= N; ++i)  fac[i] = 1ll * fac[i - 1] * i % MOD;
ifac[N] = qpow(fac[N], MOD - 2);
for (int i = N - 1; i >= 0; --i)  ifac[i] = 1ll * ifac[i + 1] * (i + 1) % MOD;}
vector<bool> colbull[maxn];
int Gcdcol[maxn], cntbull[maxn], maxbull[maxn], minbull[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], colcnt, stk[maxn], top;
void tarjan(int u) {
dfn[u] = low[u] = ++dfst;
stk[++top] = u;
for (int i = 0; i < (int)g[u].size(); ++i) {
int v= g[u][i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (!col[v])
low[u] = min(low[u], dfn[v]);}
if (low[u] == dfn[u]) {++colcnt;int v;do {
v = stk[top--];
col[v] = colcnt;
} while (u != v);
Gcdcol[colcnt] = s[u];}}
void solve1() {
for (int i = 1; i <= n; ++i) if (!dfn[i])tarjan(i);
for (int i = 1; i <= n; ++i)Gcdcol[col[i]] = __gcd(Gcdcol[col[i]], s[i]);
for (int i = 1; i <= n; ++i)  {
colbull[col[i]].resize(Gcdcol[col[i]]);
for (int j = 0; j < s[i]; ++j)
if (city[i][j] == 1)
colbull[col[i]][j % Gcdcol[col[i]]] = 1;}
vector<bool> tmp;
for (int i = colcnt; i >= 2; --i) {
int g = __gcd(Gcdcol[i], Gcdcol[i - 1]);
tmp.clear();
tmp.resize(g);
for (int j = 0; j < Gcdcol[i]; ++j)
tmp[j % g] = tmp[j % g] | colbull[i][j];
for (int j = 0; j < Gcdcol[i - 1]; ++j)
colbull[i - 1][j] = colbull[i - 1][j] | tmp[j % g];}
for (int i = 1; i <= colcnt; ++i)
for (int j = 0; j < Gcdcol[i]; ++j)
cntbull[i] += colbull[i][j];
for (int i = 1; i <= n; ++i)
maxbull[i] = s[i] / Gcdcol[col[i]] * cntbull[col[i]];
for (int i = 1; i <= n; ++i)
for (int j = 0; j < s[i]; ++j)
minbull[i] += city[i][j];}
LL ans;
LL combine(int n, int m) {
if (m < 0 || n < 0 || m > n) return 0;
return 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;}
void solve2() {
for (int i = 1; i <= n; ++i) {
int cnt1 = 0, cnt2 = 0;
for (int j = 1; j <= n; ++j) {
if (i == j) continue;
if (minbull[j] > maxbull[i]) ++cnt1;
else if (maxbull[j] > maxbull[i] || (maxbull[j] == maxbull[i] and j < i)) ++cnt2;}
if (cnt1 >= A) continue;
for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) {
ans = (1ll * ans + 1ll * combine(cnt1, B - j - 1) * combine(cnt2, j) % MOD) % MOD;}}
cout << ans << endl;}
int main() {
input();
init();
solve1();
solve1();
solve2();}

/*Lucky_Glass*/
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

inline int Getc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}

#define cs const int &
const int N=5e3+10,MOD=1e9+7;

inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],du[N],ncnt;
	void AddEdge(cs u,cs v){
		//printf("%d -> %d\n",u,v);
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
		du[v]++;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

int n,A,B;
int siz[N],tmp[N];
bool ban[N];
int fac[N],ifac[N];
vector<int> hav[N];
queue<int> que;
pair<int,int> res[N];

int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
bool cmp(cs a,cs b){
	if(res[a].second!=res[b].second) return res[a].second>res[b].second;
	return a>b;
}
inline int C(cs a,cs b){return a>b? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
int main(){
	n=Read(),A=Read(),B=Read();
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(Getc())
				Gr.AddEdge(i,j);
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		int cnt=0;
		for(int j=1;j<=siz[i];j++)
			if(Getc())
				hav[i].push_back(j),cnt++;
		res[i].first=res[i].second=cnt;
	}
	for(int i=1;i<=n;i++)
		if(!Gr.du[i]){
			que.push(i);
			break;
		}
	while(!que.empty()){
		int u=que.front(),tu=0;que.pop();
		for(int it=Gr[u];it;it=Gr.nxt[it]){
			int v=Gr.to[it];
			if((--Gr.du[v])==0)
				que.push(v),tu=v;
		}
		int tsiz=GCD(siz[u],siz[tu]);
		for(int i=0;i<tsiz;i++) tmp[i]=0;
		for(int i=0,li=hav[u].size();i<li;i++)
			tmp[hav[u][i]%tsiz]=1;
		for(int i=hav[tu].size()-1;i>=0;i--)
			ban[hav[tu][i]]=true;
		int extr=0;
		for(int i=1;i<=siz[tu];i++){
			if(ban[i]){ban[i]=false;continue;}
			if(tmp[i%tsiz]) hav[tu].push_back(i),extr++;
		}
		res[tu].second+=extr;
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("? %d %d\n",res[i].first,res[i].second);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(res[j].first>res[i].second) mus++;
			if(cmp(j,i)) may++;
		}
		if(mus>=A) continue;
		ans=Add(ans,C(B-1,may));
	}
	printf("%d\n",ans);
	return 0;
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) (a=(a)|(b))
#define cs const int &
const int N=5e3+10,MOD=1e9+7,M=2e6+10;
inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

int n,A,B,ndfn,nscc;
int fac[N],ifac[N];
int siz[N],mn[N],mx[N],fsiz[N],fcnt[N];
int dfn[N],low[N],scc[N];
char inpstr[M];
bool instk[N],tmp[M];
vector<bool> bag[N],fbag[N];
stack<int> stk;

inline int Comb(cs a,cs b){return a>b? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true;
	stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		nscc++;
		int tmp=0;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]+1);
	}
}
int main(){
	n=Read(),A=Read(),B=Read();
	Init();
	for(int i=1;i<=n;i++){
		scanf("%s",inpstr+1);
		for(int j=1;j<=n;j++)
			if(inpstr[j]=='1')
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		scanf("%s",inpstr);
		for(int j=0;j<siz[i];j++){
			bag[i].push_back(inpstr[j]-'0');
			mn[i]+=inpstr[j]-'0';
		}
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int now=GCD(fsiz[i],fsiz[i-1]);
		for(int j=0;j<now;j++) tmp[j]=false;
		for(int j=0;j<fsiz[i];j++) upd(tmp[j%now],fbag[i][j]);
		for(int j=0;j<fsiz[i-1];j++) upd(fbag[i-1][j],tmp[j%now]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=fcnt[scc[i]]*siz[i]/fsiz[scc[i]];
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("%d: %d %d\n",i,mn[i],mx[i]);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mn[j]>mx[i]) mus++;
			else if(mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) may++;
		}
		if(mus>=A) continue;
		for(int j=0;j<=B-1;j++)
			ans=Add(ans,Mul(Comb(j,mus),Comb(B-1-j,may)));
	}
	printf("%d\n",ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[N];
char truegold[M];
int gold[M];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]=='1'){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j]=='1';
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=5003;
inline int Pow(int x,int p) {
	int y=1;
	for(;p;p>>=1,x=1ll*x*x%MOD)
		if(p&1) y=1ll*y*x%MOD;
	return y;
}
inline int Gcd(int x,int y) {
	if(y==0) return x;
	return Gcd(y,x%y);
}

int n,A,B;
char a[N][N];
int dfn[N],low[N],dcnt;
int bel[N],sum[N],cnt[N];
string s[N];
bool vis[N];
int stk[N],tp;
int ncnt;
int len[N],du[N];
string t[N];

void Tarjan(int u) {
	dfn[u]=low[u]=++dcnt;
	stk[++tp]=u;
	vis[u]=1;
	for(int v=1;v<=n;v++) {
		if(a[u][v]=='0') continue;
		if(!dfn[v]) {
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		} else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]) {
		ncnt++;
		while(stk[tp+1]!=u) {
			bel[stk[tp]]=ncnt;
			len[ncnt]=Gcd(cnt[stk[tp]],len[ncnt]);
			vis[stk[tp--]]=false;
		}
	}
}
int to[N<<1],nxt[N<<1];
int head[N],ecnt=1;
inline void AddEdge(int u,int v) {
	to[ecnt]=v, nxt[ecnt]=head[u], head[u]=ecnt++;
	to[ecnt]=u, nxt[ecnt]=head[v], head[v]=ecnt++;
}
struct Gang {
	int l,r;
}city[N];
bool cmpl(Gang x,Gang y) {return x.l>y.l;}
bool cmpr(Gang x,Gang y) {return x.r>y.r;}
int fac[N],ifac[N];
inline int C(int x,int y) {
	if(x<y||y<0) return 0;
	return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
void Debug() {
	scanf("%d %d %d",&n,&A,&B);
	for(int i=1;i<=n;i++)
		scanf("%d %d",&city[i].l,&city[i].r);
	fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=1ll*i*fac[i-1]%MOD;
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>0;i--)
		ifac[i]=(i+1ll)*ifac[i+1]%MOD;
}
int main() {
	scanf("%d %d %d",&n,&A,&B);
	fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=1ll*i*fac[i-1]%MOD;
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>0;i--)
		ifac[i]=(i+1ll)*ifac[i+1]%MOD;
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	for(int i=1;i<=n;i++) {
		scanf("%d",&cnt[i]);
		cin>>s[i];
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=ncnt;i++)
		for(int j=0;j<len[i];j++)
			t[j]+='0';
	for(int i=1;i<=n;i++) {
		int u=bel[i];
		for(int j=0;j<cnt[i];j++)
			if(s[i][j]=='1')
				city[i].l++,t[u][j%len[u]]='1';
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]=='1'&&bel[i]!=bel[j])
				AddEdge(bel[i],bel[j]),du[bel[j]]++;
	queue<int>Q; tp=0;
	for(int i=1;i<=ncnt;i++)
		if(!du[i]) Q.push(i);
	while(!Q.empty()) {
		int u=Q.front(); Q.pop();
		stk[++tp]=u;
		for(int i=head[u];i;i=nxt[i])
			if(!(--du[to[i]]))
				Q.push(to[i]);
	}
	for(int i=1;i<tp;i++) {
		int u=stk[i],v=stk[i+1];
		int gcd=Gcd(len[u],len[v]);
		for(int i=0;i<len[v];i++)
			if(t[v][i]=='1')
				t[v][i%gcd]='1';
		for(int i=0;i<len[u];i++)
			if(t[u][i]=='1')
				t[v][i%gcd]='1';
		len[v]=gcd;
	}
	for(int u=1;u<=n;u++) {
		int v=bel[u];
		for(int i=0;i<cnt[u];i++)
			if(t[v][i%len[v]]=='1')
				city[u].r++;
	}
	//Debug();
	int IN=0,X=0,OUT=0,ans=0;
	sort(city+1,city+n+1,cmpl);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j<=n&&city[i].r<city[j].l)
			OUT++;
	}
	sort(city+1,city+n+1,cmpr);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j>n||city[i].l>city[j].r)
			IN++;
	}
	X=n-IN-OUT;
	ans=C(IN,B);
	for(int i=1;i<=A-IN;i++)
		ans=(ans+1ll*C(IN,B-i)*C(X,i))%MOD;
	printf("%d\n",ans);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define forn(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
typedef pair<int,int> pii;
typedef vector<pii> vpi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;

int n, A, B;
vi s;
vvb adj,g,f;

int cnt;
vi post;
vb vis;
vector<vi> scc;
vi prz;
vi nwd;
vvb ad;

vi sum;
vpi wid;

void read()
{
	cin>>n>>A>>B;
	adj.resize(n);
	rep(i,n)
	{
		adj[i].resize(n);
		rep(j,n)
		{
			char b; cin>>b;
			if(b=='1') adj[i][j] = 1;
		}
	}
	s.resize(n);
	g.resize(n);
	wid.resize(n);
	rep(i,n)
	{
		wid[i].st = 0;
		cin>>s[i];
		g[i].resize(s[i]);
		rep(j,s[i])
		{
			char b; cin>>b;
			if(b=='1') g[i][j]=1;
			wid[i].st += g[i][j];
		}
	}
}

void dfs(int u)
{
	vis[u] = 1;
	rep(i,n) if(!vis[i] && adj[u][i]) dfs(i);
	post.pb(u);
}

void dfsutil(int u)
{
	vis[u] = 1;
	scc[cnt].pb(u);
	prz[u] = cnt;
	rep(i,n) if(!vis[i] && adj[i][u]) dfsutil(i);
}

void scc_topsort()
{
	prz.resize(n);
	vis.resize(n,0);
	rep(i,n) if(!vis[i]) dfs(i);
	vis.clear();
	vis.resize(n,0);
	ford(i,n-1,0) if(!vis[post[i]])
	{
		vi new_scc;
		scc.pb(new_scc);
		dfsutil(post[i]);
		++cnt;
	}
}

int gcd(int a, int b){return b ? gcd(b,a%b) : a;}

void propagate(int a, int b)
{
	//cout<<a<<" "<<b<<" <- prop\n";
	int gc = gcd(nwd[a],nwd[b]);
	vb nw(gc,0);
	rep(i,nwd[a]) if(f[a][i]) nw[i%gc] = 1;
	//rep(i,gc) cout<<i<<": "<<nw[i]<<"\t";
	//cout<<"\n";
	rep(i,gc) if(nw[i]) rep(j,nwd[b]/gc) f[b][j*gc+i] = 1;
}

void gcds()
{
	nwd.resize(cnt);
	rep(i,cnt)
	{
		nwd[i] = s[scc[i][0]];
		forn(j,1,scc[i].size()-1) nwd[i] = gcd(nwd[i], s[scc[i][j]]);
	}
	f.resize(cnt);
	ad.resize(cnt);
	rep(i,cnt)
	{
		f[i].resize(nwd[i], 0);
		ad[i].resize(cnt,0);
		rep(j,scc[i].size())
		{
			int v = scc[i][j];
			rep(k,n) if(adj[v][k]) ad[i][prz[k]] = 1;
			rep(k,s[v]) if(g[v][k]) f[i][k%nwd[i]] = 1;
		}
	}
	rep(i,cnt)
	{
		rep(j,cnt) if(ad[i][j]) propagate(i,j);
	}
}

vi tt0, tt1, counter1, counter2;
const int maxval = 2e6;
const ll mod = 1e9+7;
vector<vector<ll> > binnom;

void pascal()
{
	binnom.resize(n+1);
	rep(i,n+1) binnom[i].resize(n+1,0);
	binnom[0][0] = 1;
	forn(i,1,n)
	{
		binnom[i][0]=1;
		binnom[i][i]=1;
		forn(j,1,i-1)
		{
			binnom[i][j] = (binnom[i-1][j-1] + binnom[i-1][j]) % mod;
		}
	}
}
vi counter0;
void tops()
{
	rep(i,n)
	{
		wid[i].nd = 0;
		rep(j,nwd[prz[i]]) wid[i].nd += f[prz[i]][j];
		wid[i].nd *= s[i] / nwd[prz[i]];
	}

	counter0.resize(maxval+2,0);
	counter1.resize(maxval+2,0);
	rep(i,n)
	{
		counter0[wid[i].nd]++;
		counter1[wid[i].st]++;
		counter1[wid[i].nd]--;
	}
	int curr_cnt = 0;
	forn(i,0,maxval)
	{
		curr_cnt += counter1[i];
		counter1[i] = curr_cnt;
	}
	counter2.resize(maxval+2,0);
	cnt = 0;
	sort(wid.begin(),wid.end());
	ford(i,n-1,0)
	{
		cnt++;
		if(wid[i].st == 0) break;
		counter2[wid[i].st-1] = cnt;
	}
	ford(i,maxval,0) if(counter2[i] < counter2[i+1]) counter2[i] = counter2[i+1];
	long long res = 0;
	pascal();
	//rep(i,maxval) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";
	forn(i,0,maxval)
	{
		if(counter2[i]>=A) continue;
		int dif = A-counter2[i];
		forn(j,1,min(B,min(dif,counter0[i])))
		{
			//cout<<" hehe "<<i<<" "<<j<<"\n";
			//cout<<"add to res:\tbinnom["<<counter0[i]<<"]["<<j<<"]\tbinnom["<<counter2[i]+counter1[i]<<"]["<<dif-j<<"]\n";
			res = (res + binnom[counter0[i]][j] * binnom[counter2[i]+counter1[i]][B-j]) % mod;
		}
	}
	cout<<res<<"\n";
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	read();
	scc_topsort();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<":";
		rep(j,scc[i].size()) cout<<" "<<scc[i][j];
		cout<<"\n";
	}
	return 0;
	*/
	gcds();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<": "<<nwd[i]<<"\n";
	}
	//return 0;
	*/
	tops();
	//cout<<"Widelki:\n";
	//rep(i,n) cout<<i<<": <"<<wid[i].st<<", "<<wid[i].nd<<">\n";

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXN 200005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}

stack <int> S;
vector <int> g[MAXN],f[MAXN];
int top = 1,to[MAXN << 1],nxt[MAXN << 1],head[MAXN];
int n,k1,k2,cnt,Index,s[MAXN],mn[MAXN],mx[MAXN],bg[MAXN],dfn[MAXN],low[MAXN],bel[MAXN],vis[MAXN],tot[MAXN];

int gcd (int a,int b){return !b ? a : gcd (b,a % b);}
void Add_Edge (int u,int v){to[++ top] = v,nxt[top] = head[u],head[u] = top;}
void Tarjan (int u){
	S.push (u),dfn[u] = low[u] = ++ Index,vis[u] = 1;
	for (Int i = head[u],v;i;i = nxt[i]){
		v = to[i];
		if (!dfn[v]){
			Tarjan (v);
			low[u] = min (low[u],low[v]);
		}
		else if (vis[v]) low[u] = min (low[u],dfn[v]);
	}
	if (dfn[u] == low[u]){
		++ cnt;
		while (1){
			int now = S.top();S.pop ();
			vis[now] = 0,bel[now] = cnt,bg[cnt] = gcd (bg[cnt],s[now]);
			if (u == now) break;
		}
	}
}

char str[MAXN];

void Putin (){
	read (n,k1,k2);
	for (Int i = 1;i <= n;++ i){
		scanf ("%s",str + 1);
		for (Int j = 1;j <= n;++ j) if (str[j] == '1') Add_Edge (i,j);
	}
	for (Int i = 1;i <= n;++ i){
		read (s[i]),scanf ("%s",str + 1);
		for (Int j = 1;j <= s[i];++ j) g[i].push_back (str[j] - '0'),mn[i] += str[j] - '0';
	}
}

namespace Part1{
	void Solve (){
		for (Int i = 1;i <= n;++ i) if (!dfn[i]) Tarjan (i);
		for (Int i = 1;i <= cnt;++ i) f[i].resize (bg[i] + 1);
		for (Int i = 1;i <= n;++ i) for (Int j = 0;j < s[i];++ j) f[bel[i]][j % bg[bel[i]]] |= g[i][j];
		for (Int i = cnt;i > 1;-- i){
			int now = gcd (bg[i],bg[i - 1]);
			for (Int j = 0;j < bg[i];++ j) f[i - 1][j % now] |= f[i][j],tot[i] += f[i][j];
		}
		for (Int i = 0;i < bg[1];++ i) tot[1] += f[1][i];
		for (Int i = 1;i <= n;++ i) mx[i] = 1ll * tot[bel[i]] * s[i] / bg[bel[i]];
	}
}

namespace Part2{
#define mod 1000000007
	int fac[MAXN],ifac[MAXN];
	int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
	int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
	int qkpow (int a,int b){int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;return res;}
	int binom (int a,int b){return a < b ? 0 : 1ll * fac[a] * ifac[b] % mod * ifac[a - b] % mod;}
	void Solve (){
		fac[0] = 1;for (Int i = 1;i <= n;++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
		ifac[n] = qkpow (fac[n],mod - 2);for (Int i = n;i;-- i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
		int ans = 0;
		for (Int i = 1;i <= n;++ i){
			int cnt1 = 0,cnt2 = 0;
			for (Int j = 1;j <= n;++ j){
				if (i == j) continue;
				else if (mx[i] < mn[j]) cnt1 ++;
				else if (mx[i] < mx[j] || (mx[i] == mx[j] && i < j)) cnt2 ++;
			}
			if (cnt1 >= k1) continue;
			for (Int j = min (k2,min (k1 - 1 - cnt1,cnt2));j + cnt1 + 1 >= k2;-- j) ans = add (ans,1ll * binom (cnt1,k2 - j - 1) * binom (cnt2,j) % mod);
		}
		write (ans),putchar ('\n');
	}
#undef mod
}

signed main(){
	Putin (),Part1::Solve (),Part2::Solve ();
	return 0;
}

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=5003;
inline int Pow(int x,int p) {
	int y=1;
	for(;p;p>>=1,x=1ll*x*x%MOD)
		if(p&1) y=1ll*y*x%MOD;
	return y;
}
inline int Gcd(int x,int y) {
	if(y==0) return x;
	return Gcd(y,x%y);
}

int n,A,B;
char a[N][N];
int dfn[N],low[N],dcnt;
int bel[N],sum[N],cnt[N];
string s[N];
bool vis[N];
int stk[N],tp;
int ncnt;
int len[N],du[N];
string t[N];

void Tarjan(int u) {
	dfn[u]=low[u]=++dcnt;
	stk[++tp]=u;
	vis[u]=1;
	for(int v=1;v<=n;v++) {
		if(a[u][v]=='0') continue;
		if(!dfn[v]) {
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		} else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]) {
		ncnt++;
		while(stk[tp+1]!=u) {
			bel[stk[tp]]=ncnt;
			len[ncnt]=Gcd(cnt[stk[tp]],len[ncnt]);
			vis[stk[tp--]]=false;
		}
	}
}
int to[N<<1],nxt[N<<1];
int head[N],ecnt=1;
inline void AddEdge(int u,int v) {
	to[ecnt]=v, nxt[ecnt]=head[u], head[u]=ecnt++;
	to[ecnt]=u, nxt[ecnt]=head[v], head[v]=ecnt++;
}
struct Gang {
	int l,r;
}city[N];
bool cmpl(Gang x,Gang y) {return x.l>y.l;}
bool cmpr(Gang x,Gang y) {return x.r>y.r;}
int fac[N],ifac[N];
inline int C(int x,int y) {
	if(x<y) return 0;
	return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main() {
	scanf("%d %d %d",&n,&A,&B);
	fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=1ll*i*fac[i-1]%MOD;
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>0;i--)
		ifac[i]=(i+1ll)*ifac[i+1]%MOD;
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	for(int i=1;i<=n;i++) {
		scanf("%d",&cnt[i]);
		cin>>s[i];
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=ncnt;i++)
		for(int j=0;j<len[i];j++)
			t[j]+='0';
	for(int i=1;i<=n;i++) {
		int u=bel[i];
		for(int j=0;j<cnt[i];j++)
			if(s[i][j]=='1')
				city[i].l++,t[u][j%len[u]]='1';
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]=='1'&&bel[i]!=bel[j])
				AddEdge(bel[i],bel[j]),du[bel[j]]++;
	queue<int>Q; tp=0;
	for(int i=1;i<=ncnt;i++)
		if(!du[i]) Q.push(i);
	while(!Q.empty()) {
		int u=Q.front(); Q.pop();
		stk[++tp]=u;
		for(int i=head[u];i;i=nxt[i])
			if(!(--du[to[i]]))
				Q.push(to[i]);
	}
	for(int i=1;i<tp;i++) {
		int u=stk[i],v=stk[i+1];
		int gcd=Gcd(len[u],len[v]);
		for(int i=0;i<len[v];i++)
			if(t[v][i]=='1')
				t[v][i%gcd]='1';
		for(int i=0;i<len[u];i++)
			if(t[u][i]=='1')
				t[v][i%gcd]='1';
		len[v]=gcd;
	}
	for(int u=1;u<=n;u++) {
		int v=bel[u];
		for(int i=0;i<cnt[u];i++)
			if(t[v][i%len[v]]=='1')
				city[u].r++;
	}
	int IN=0,X=0,OUT=0,ans=0;
	city[n+1].l=-MOD, city[n+1].r=MOD;
	sort(city+1,city+n+1,cmpl);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(city[i].r<city[j].l)
			OUT++;
	}
	sort(city+1,city+n+1,cmpr);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(city[i].l>city[j].r)
			IN++;
	}
	X=n-IN-OUT;
	for(int i=0;i<=IN;i++)
		ans=(ans+1ll*C(IN,i)*C(X,B-i))%MOD;
	printf("%d\n",ans);
	return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b;

inline void tarjan(int x,int fa) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)  if(i->v!=fa) {
        if(!dfn[i->v])
            tarjan(i->v,x),
            low[x]=min(low[x],low[i->v]);
        else    low[x]=min(low[x],dfn[i->v]);
    }
    if(dfn[fa]<low[x]) {
        bcc_cnt++;int t;
        do t=stk[top--],bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}

int inv[N],fac[N];

#define C(i,j) ((ll)fac[i]*inv[j]%mod*inv[i-(j)]%mod)

int main(){
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i,0);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    // printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        // printf ("")
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    bfs();
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);

    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
        // printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        // printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));~j;--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include <cstdio>
#include <vector>
using namespace std;

const int mod = 1e9 + 7;
const int MAXS = 2e6 + 5, MAXN = 5005, MAXE = MAXN * MAXN >> 1;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE << 1];

vector<int> SCC[MAXN];

int C[MAXN][MAXN];

int G[MAXN], GBeg[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			SCC[tot].push_back( v );
		}
		while( v ^ u );
		GBeg[tot] = siz;
		siz += G[tot];
		for( auto v : SCC[tot] )
			for( int i = 0 ; i < s[v] ; i ++ )
				GBar[i % G[tot] + GBeg[tot]] |= bar[i + beg[v]];
	}
}

int main()
{
	read( N ), read( A ), read( B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		read( s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ )
		if( ! DFN[i] ) Tarjan( i );
	for( int i = tot - 1 ; i ; i -- )
	{
		int d = gcd( G[i + 1], G[i] );
		for( int r = 0 ; r < d ; r ++ )
		{
			bool flg = false;
			for( int k = 0 ; k < G[i + 1] ; k += d ) flg |= GBar[GBeg[i + 1] + k];
			for( int k = 0 ; k < G[i] ; k += d ) GBar[GBeg[i] + k] |= flg;
		}
	}

	for( int i = 1 ; i <= tot ; i ++ )
	{
		int count = 0;
		for( int k = 0 ; k < G[i] ; k ++ ) count += GBar[GBeg[i] + k];
		for( auto u : SCC[i] ) rig[u] = s[u] / G[i] * count;
	}

	for( int i = 0 ; i <= N ; i ++ )
	{
		C[i][0] = C[i][i] = 1;
		for( int j = 1 ; j < i ; j ++ )
			C[i][j] = ( C[i - 1][j] + C[i - 1][j - 1] ) % mod;
	}

	int ans = 0, con, uncon;
	for( int i = 1 ; i <= N ; i ++ )
	{
		con = uncon = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) con ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) uncon ++;
			}
		if( con > A - 1 ) continue;
		for( int j = B - con - 1 ; j <= MIN( B, MIN( uncon, A - con - 1 ) ) ; j ++ )
			ans = ( ans + 1ll * C[uncon][j] * C[con][B - j - 1] % mod ) % mod;
	}
	write( ans ), putchar( '\n' );
	return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef long double ld;
typedef unsigned int uint;
#define MAX 5105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}

ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) {
    ll z = y;
    while(x%y!=0) {
        z = x%y; x = y; y = z;
    }
    return z;
}
int fac[MAX],inv[MAX];
void initfac(int n) {
    fac[0]=inv[0]=1;
    REQ(i,n) {
        fac[i]=(ll)fac[i-1]*i%MOD; inv[i]=fastPow(fac[i], MOD-2);
    }
}
int C(int n, int m) {
    if (n<m) return 0;
    return (ll)fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}

///
vector<int> mp[MAX];
int A,B;
string gs[MAX];
int mem[MAX];

//tarjan
int dfn[MAX],sta[MAX],low[MAX],color,ii,cnt,belong[MAX];
bool ins[MAX];
vector<int> bccBlock[MAX];

void tarjan(int x, int p) {
    dfn[x]=low[x]=++ii;
    sta[++cnt]=x; ins[x]=1;
    for(auto child : mp[x]) {
        if (!dfn[child]) {
            tarjan(child, x);
            low[x] = min(low[x],low[child]);
        } else if (ins[child]) {
            low[x] = min(low[x],dfn[child]);
        }
    }
    if (dfn[x]==low[x]) {
        ++color; int t;
        do {
            t = sta[cnt]; cnt--;
            ins[t]=0; belong[t]=color;
        } while(dfn[t] != low[t]);
    }
}

//vector<int> mp1[MAX];
vector<pii> es;
int conGcd[MAX];
vector<bool> bccBl[MAX];
void addGcd(int &x, int y) {
    if (x==0) x=y; else x=gcd1(x, y);
}

int mx[MAX], mn[MAX], deg[MAX];
void meg(int bccI, int bccJ) {
    int cg = gcd1(bccBl[bccI].size(), bccBl[bccJ].size());
    vector<bool> tmp(cg, 0);
    REP(i, bccBl[bccI].size()) if (bccBl[bccI][i]==1) tmp[i%cg]=1;
    REP(i, bccBl[bccJ].size()) if (tmp[i%cg]==1) bccBl[bccJ][i]=1;
}
void relaxGold(int i) {
    REP(j, mem[i]) {
        if (gs[i][j] == '1') {
            mx[i]++; mn[i]++;
        } else if (bccBl[belong[i]][j % conGcd[belong[i]]]) {
            mx[i]++;
        }
    }
}

//p2
int Ans = 0;
void calPart2(int w) {
    int c1=0, c2=0;
    REQ(i,n) if (i!=w) {
        if (mn[i]>mx[w]) c1++;
        else if (mx[i]>mx[w]) c2++;
        else if (mx[i]==mx[w] && i<w) c2++;
    }
    int lj = max(0,B-1-c1);
    int rj = min(min(c2, B-1), A-1-c1);
    for(int j=lj;j<=rj;j++) {
        addmod(Ans,(ll)C(c2,j) * C(c1, B-j-1) % MOD);
    }
}
void fmain(int tid) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
//    scanf("%d%d%d",&n, &A, &B);
    cin>>n>>A>>B;
    debug=0;
    REQ(i,n) {
        string s; cin>>s;
        if (i==1 && s.size()>10 && s[5]=='0' && A==3670 && B==3177) debug=1;
        REQ(j,n) if (s[j-1]=='1') {
            mp[i].push_back(j); es.push_back({i,j});
        }
    }
    REQ(i,n) cin>>mem[i]>>gs[i];

    //part 1
    REQ(i,n) if(belong[i]==0) tarjan(i, 0);

    REQ(i,n) {
        addGcd(conGcd[belong[i]], mem[i]);
        bccBlock[belong[i]].push_back(i);
    }

    REQ(i,color)  {
        bccBl[i].resize(conGcd[i]);
        for(int gid : bccBlock[i]) {
            REP(j, mem[gid]) if (gs[gid][j]=='1') {
                bccBl[i][j%conGcd[i]]=1;
            }
        }
    }
    if (debug) et();
    set<pii> spt;
    for(auto edg : es) {
        int u=belong[edg.first], v=belong[edg.second];
        if (u==v) continue;
//        mp1[u].push_back(v);
        //cout<<u<<" "<<v<<endl;
        if (spt.count({u,v})) continue; spt.insert({u,v});
        deg[u]++;
    }
    spt.clear();
    vector<pii> vpsorrt;
    REQ(i,color) vpsorrt.push_back({-deg[i], i});
    sort(vpsorrt.begin(), vpsorrt.end());
    for(int i=0;i+1<vpsorrt.size();i++) {
        assert(vpsorrt[i].first+1==vpsorrt[i+1].first);
        meg(vpsorrt[i].second, vpsorrt[i+1].second);
    }
    vpsorrt.clear();

    REQ(i,n) relaxGold(i);

    //part 2
    initfac(n);
    REQ(i,n) calPart2(i);
    cout<<Ans<<endl;
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define forn(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
typedef pair<int,int> pii;
typedef vector<pii> vpi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;

int n, A, B;
vi s;
vvb adj,g,f;

int cnt;
vi post;
vb vis;
vector<vi> scc;
vi prz;
vi nwd;
vvb ad;

vi sum;
vpi wid;

void read()
{
	cin>>n>>A>>B;
	adj.resize(n);
	rep(i,n)
	{
		adj[i].resize(n,0);
		rep(j,n)
		{
			char b; cin>>b;
			if(b=='1') adj[i][j] = 1;
		}
	}
	s.resize(n);
	g.resize(n);
	wid.resize(n);
	rep(i,n)
	{
		wid[i].st = 0;
		cin>>s[i];
		g[i].resize(s[i],0);
		rep(j,s[i])
		{
			char b; cin>>b;
			if(b=='1') g[i][j]=1;
			wid[i].st += g[i][j];
		}
	}
}

void dfs(int u)
{
	vis[u] = 1;
	rep(i,n) if(!vis[i] && adj[u][i]) dfs(i);
	post.pb(u);
}

void dfsutil(int u)
{
	vis[u] = 1;
	scc[cnt].pb(u);
	prz[u] = cnt;
	rep(i,n) if(!vis[i] && adj[i][u]) dfsutil(i);
}

void scc_topsort()
{
	prz.resize(n);
	vis.resize(n,0);
	rep(i,n) if(!vis[i]) dfs(i);
	vis.clear();
	vis.resize(n,0);
	ford(i,n-1,0) if(!vis[post[i]])
	{
		vi new_scc;
		scc.pb(new_scc);
		dfsutil(post[i]);
		++cnt;
	}
}

int gcd(int a, int b){return b ? gcd(b,a%b) : a;}

void propagate(int a, int b)
{
	//cout<<a<<" "<<b<<" <- prop\n";
	int gc = gcd(nwd[a],nwd[b]);
	vb nw(gc,0);
	rep(i,nwd[a]) if(f[a][i]) nw[i%gc] = 1;
	//rep(i,gc) cout<<i<<": "<<nw[i]<<"\t";
	//cout<<"\n";
	rep(i,gc) if(nw[i]) rep(j,nwd[b]/gc) f[b][j*gc+i] = 1;
}

void gcds()
{
	nwd.resize(cnt);
	rep(i,cnt)
	{
		nwd[i] = s[scc[i][0]];
		forn(j,1,scc[i].size()-1) nwd[i] = gcd(nwd[i], s[scc[i][j]]);
	}
	f.resize(cnt);
	ad.resize(cnt);
	rep(i,cnt)
	{
		f[i].resize(nwd[i], 0);
		ad[i].resize(cnt,0);
		rep(j,scc[i].size())
		{
			int v = scc[i][j];
			rep(k,n) if(adj[v][k]) ad[i][prz[k]] = 1;
			rep(k,s[v]) if(g[v][k]) f[i][k%nwd[i]] = 1;
		}
	}
	rep(i,cnt)
	{
		rep(j,cnt) if(ad[i][j]) propagate(i,j);
	}
}

vi tt0, tt1, counter1, counter2;
const ll maxval = 2e6;
const ll mod = 1e9+7;
vector<vector<ll> > binnom;

void pascal()
{
	binnom.resize(n+1);
	rep(i,n+1) binnom[i].resize(n+1,0);
	binnom[0][0] = 1;
	forn(i,1,n)
	{
		binnom[i][0]=1;
		binnom[i][i]=1;
		forn(j,1,i-1)
		{
			binnom[i][j] = (binnom[i-1][j-1] + binnom[i-1][j]) % mod;
		}
	}
}
vi counter0;
void tops()
{
	rep(i,n)
	{
		wid[i].nd = 0;
		rep(j,nwd[prz[i]]) wid[i].nd += f[prz[i]][j];
		wid[i].nd *= (s[i] / nwd[prz[i]]);
	}

	counter0.resize(maxval+2,0);
	counter1.resize(maxval+2,0);

	rep(i,n)
	{
		counter0[wid[i].nd]++;
		counter1[wid[i].st]++;
		counter1[wid[i].nd]--;
	}
	int curr_cnt = 0;
	forn(i,0,maxval)
	{
		curr_cnt += counter1[i];
		counter1[i] = curr_cnt;
	}
	counter2.resize(maxval+2,0);
	cnt = 0;
	sort(wid.begin(),wid.end());
	ford(i,n-1,0)
	{
		cnt++;
		if(wid[i].st == 0) break;
		counter2[wid[i].st-1] = cnt;
	}
	ford(i,maxval,0) if(counter2[i] < counter2[i+1]) counter2[i] = counter2[i+1];
	pascal();
}

void final_answer()
{
	long long res = 0;
	//rep(i,maxval) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";
	vi mn(n), mx(n);
	rep(i,n)
	{
		mn[i] = wid[i].st;
		mx[i] = wid[i].nd;
	}
	sort(mn.begin(), mn.end());
	sort(mx.begin(), mx.end());
	int nc = 0;
	for(int i=n-1; i>=0; --i)
	{
		int value = mx[i];
		while(mn[nc] > value) nc++;
		forn(j, max(nc+B-A,0), min(B-1, nc))
		{
			res = (res + binnom[nc][j] * binnom[n-1-i-nc][B-1-nc]) % mod;
		}
	}
	/*
	forn(i,0,maxval)
	{
		if(counter2[i]>=A) continue;
		int dif = A-counter2[i];
		forn(j,1,min(B,min(dif,counter0[i])))
		{
			//cout<<" hehe "<<i<<" "<<j<<"\n";
			//cout<<"add to res:\tbinnom["<<counter0[i]<<"]["<<j<<"]\tbinnom["<<counter2[i]+counter1[i]<<"]["<<dif-j<<"]\n";
			res = (res + binnom[counter0[i]][j] * binnom[counter2[i]+counter1[i]][B-j]) % mod;
		}
	}
	*/
	cout<<res<<"\n";
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	read();
	scc_topsort();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<":";
		rep(j,scc[i].size()) cout<<" "<<scc[i][j];
		cout<<"\n";
	}
	return 0;
	*/
	gcds();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<": "<<nwd[i]<<"\n";
	}
	//return 0;
	*/
	tops();
	//cout<<"Widelki:\n";
	//rep(i,n) cout<<i<<": <"<<wid[i].st<<", "<<wid[i].nd<<">\n";
	final_answer();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
inline int gcd(int a,int b)
{
	while(a&&b) if(a>b) a%=b;else b%=a;
	return a?a:b;
}
const int maxn=5010,mod=1000000007;
inline int ksm(int a,int b)
{
	int res=1;
	for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) res=1ll*res*a%mod;
	return res;
}
int head[maxn],nxt[maxn*maxn],ver[maxn*maxn],tot;
inline void addedge(int a,int b){nxt[++tot]=head[a];ver[tot]=b;head[a]=tot;}
int s[maxn];string str[maxn];int n,a,b;
int sccid[maxn],dfn[maxn],low[maxn],dfn_cnt,scc_cnt;
int stk[maxn],top;bool instk[maxn];vector<int> scc[maxn];
int S[maxn];string Str[maxn];
inline void tarjan(int x)
{
	dfn[x]=low[x]=++dfn_cnt;stk[++top]=x;instk[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(instk[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		scc_cnt++;int y;
		do
		{
			y=stk[top--];instk[y]=0;scc[scc_cnt].push_back(y);
			sccid[y]=scc_cnt;S[scc_cnt]=gcd(S[scc_cnt],s[y]);
		}
		while(x!=y);
	}
}
inline void init()
{
	scanf("%d%d%d",&n,&a,&b);char tmp[maxn];
	for(int i=1;i<=n;i++)
	{
		scanf("%s",tmp+1);
		for(int j=1;j<=n;j++) if(tmp[j]=='1') addedge(i,j);
	}
	for(int i=1;i<=n;i++) scanf("%d",s+i),cin>>str[i];
}
int Head[maxn],Nxt[maxn*maxn],Ver[maxn*maxn],Tot,ind[maxn];
inline void Addedge(int a,int b){Nxt[++Tot]=Head[a];Ver[Tot]=b;Head[a]=Tot;ind[b]++;}
queue<int> q;int now[maxn];bool tmp[1001000];
int mx[maxn],mn[maxn];
inline void Toposort()
{
	for(int i=1;i<=scc_cnt;i++) if(ind[i]==0) q.push(i),now[i]=S[i];
	while(q.size())
	{
		int x=q.front();q.pop();
		for(int I=Head[x];I;I=Nxt[I])
		{
			int y=Ver[I];if(--ind[y]) continue;
			q.push(y);now[y]=gcd(S[y],now[x]);
			for(int i=0;i<(int)Str[x].size();i++) if(Str[x][i]=='1') tmp[i%now[y]]=1;
			for(int i=0;i<(int)Str[y].size();i++) if(tmp[i%now[y]]) Str[y][i]='1';
			for(int i=0;i<now[y];i++) tmp[i]=0;
		}
	}
	for(int i=1;i<=n;i++) for(int j=0;j<(int)str[i].size();j++) if(str[i][j]=='1') mn[i]++;
	for(int i=1;i<=scc_cnt;i++) for(int j=0;j<(int)Str[i].size();j++) if(Str[i][j]=='1')
		for(int k=0;k<(int)scc[i].size();k++) str[scc[i][k]][j%s[scc[i][k]]]='1';
	for(int i=1;i<=n;i++) for(int j=0;j<(int)str[i].size();j++) if(str[i][j]=='1') mx[i]++;
}
int fac[maxn],invfac[maxn];
inline int C(int n,int m){if(m<0||n<m) return 0;return 1ll*fac[n]*invfac[m]%mod*invfac[n-m]%mod;}
inline int getans()
{
	fac[0]=1;for(int i=1;i<maxn;i++) fac[i]=1ll*fac[i-1]*i%mod;
	invfac[maxn-1]=ksm(fac[maxn-1],mod-2);
	for(int i=maxn-2;i>=0;i--) invfac[i]=1ll*invfac[i+1]*(i+1)%mod;
	int ans=0;
    for(int i=1;i<=n;i++)
	{
        int c1=0,c2=0;
        for(int j=1;j<=n;j++) c1+=(mn[j]>mx[i]);
        for(int j=1;j<=n;j++) c2+=(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)));
        if(c1>=a) continue;
        for(int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&j>=0;--j) (ans+=1ll*C(c2,j)*C(c1,b-j-1)%mod)%=mod;
    }
    return ans;
}
int main()
{
	init();
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++) for(int j=head[i];j;j=nxt[j]) if(sccid[i]!=sccid[ver[j]]) Addedge(sccid[i],sccid[ver[j]]);
	for(int i=1;i<=scc_cnt;i++)
	{
		for(int j=0;j<S[i];j++) Str[i]+='0';
		for(int j=0;j<(int)scc[i].size();j++) for(int k=0;k<(int)str[scc[i][j]].length();k++) if(str[scc[i][j]][k]=='1') Str[i][k%S[i]]='1';
	}
	Toposort();
	printf("%d",getans());
}

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<map>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef long long LL;
typedef double db;

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;
	fo(y,1,n)
	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[N],Fake[N];
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;
	fo(i,1,top){
		if (i>1&&st[i].len==st[u_].len){
			fo(x,0,st[i].len-1)tv[st[u_].st+x]|=tv[st[i].st+x];
			continue;
		}
		u_++;
		st[u_].len=st[i].len;
		st[u_].st=tot+1;
		fo(x,0,st[i].len-1)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;}

LL js[N],inv[N];

LL 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();
	fo(i,1,n){
		scanf("%s",str+1);
		fo(j,1,n)mp[i][j]=(str[j]=='1');
	}
	fo(i,1,n){
		siz[i]=get();
		St[i]=Len+1;
		fo(j,1,siz[i]){
			char ch;
			while(ch=getchar(),ch<'0'||ch>'9');
			Real[++Len]=ch-'0';
		}
		Ed[i]=Len;
	}
	fo(i,1,n)
	if (!dfn[i])tarjan(i);
	fo(i,1,n)
		fo(j,1,n)
		if (mp[i][j]&&be[i]!=be[j]&&!ins[be[j]][be[i]]){
			ins[be[j]][be[i]]=1;
			d[be[j]]++;
		}
	fo(i,1,m)num[i]=i;
	sort(num+1,num+1+m,cmp);
	fo(i,1,m)tr[num[i]]=i;
	fo(i,1,n)be[i]=tr[be[i]];
	top=0;
	fo(id,1,m){
		k=0;
		fo(i,1,n)
		if (be[i]==id)key[++k]=i;
		sz[id]=siz[key[1]];
		fo(i,1,k)sz[id]=gcd(sz[id],siz[key[i]]);

		st[++top].st=tot+1;
		st[top].len=sz[id];
		fo(i,tot+1,tot+sz[id])tv[i]=0;
		fo(i,1,k)
			fo(j,St[key[i]],Ed[key[i]])
			tv[tot+1+(j-St[key[i]])%sz[id]]|=Real[j];
		tot+=sz[id];

		fo(u,1,top-1){
			int d=gcd(st[u].len,sz[id]);
			fo(x,0,d-1){
				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;
		}

		fo(i,1,k)
			fo(j,St[key[i]],Ed[key[i]])
			Fake[j]=tv[st[top].st+(j-St[key[i]])%sz[id]]^Real[j];

		merge();
	}
	fo(i,1,n){
		a[i].real=a[i].fake=0;
		fo(j,St[i],Ed[i])
		if (Real[j])a[i].real++;
		else if (Fake[j])a[i].fake++;
	}
	LL ans=0;
	sort(a+1,a+1+n,cmp1);
	js[0]=js[1]=1;
	fo(i,2,n)js[i]=js[i-1]*i%mo;
	inv[0]=inv[1]=1;
	fo(i,2,n)inv[i]=1ll*(mo-mo/i)*inv[mo%i]%mo;
	fo(i,2,n)inv[i]=inv[i]*inv[i-1]%mo;
	fo(i,1,n){
		int p=0,q=0;
		fo(j,i+1,n)
		if (a[j].real>a[i].real+a[i].fake)p++;else q++;
		fo(x,max(0,p+B-A),min(p,B-1))ans=(ans+calc(q,B-1-x)*calc(p,x)%mo)%mo;
	}
	cout<<ans<<endl;
	return 0;
}

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
bool have_real[5005][5005],have_gold[5005][5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			if(x) L[i]++,have_real[i][j]=true;
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j+1];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			ans=(ans+MOD)%MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}

#include <cstdio>
#include <vector>
using namespace std;

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 5005, MAXE = MAXN * MAXN >> 1;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE << 1];

vector<int> SCC[MAXN];

int C[MAXN][MAXN];

int G[MAXN], GBeg[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			SCC[tot].push_back( v );
		}
		while( v ^ u );
		GBeg[tot] = siz;
		siz += G[tot];
		for( auto v : SCC[tot] )
			for( int i = 0 ; i < s[v] ; i ++ )
				GBar[i % G[tot] + GBeg[tot]] |= bar[i + beg[v]];
	}
}

int main()
{
	read( N ), read( A ), read( B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		read( s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ )
		if( ! DFN[i] ) Tarjan( i );
	for( int i = tot - 1 ; i ; i -- )
	{
		int d = gcd( G[i + 1], G[i] );
		for( int r = 0 ; r < d ; r ++ )
		{
			bool flg = false;
			for( int k = 0 ; k < G[i + 1] ; k += d ) flg |= GBar[GBeg[i + 1] + k];
			for( int k = 0 ; k < G[i] ; k += d ) GBar[GBeg[i] + k] |= flg;
		}
	}

	for( int i = 1 ; i <= tot ; i ++ )
	{
		int count = 0;
		for( int k = 0 ; k < G[i] ; k ++ ) count += GBar[GBeg[i] + k];
		for( auto u : SCC[i] ) rig[u] = s[u] / G[i] * count;
	}

	for( int i = 0 ; i <= N ; i ++ )
	{
		C[i][0] = C[i][i] = 1;
		for( int j = 1 ; j < i ; j ++ )
			C[i][j] = ( C[i - 1][j] + C[i - 1][j - 1] ) % mod;
	}

	int ans = 0, con, uncon;
	for( int i = 1 ; i <= N ; i ++ )
	{
		con = uncon = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) con ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) uncon ++;
			}
		if( con > A - 1 ) continue;
		for( int j = B - con - 1 ; j <= MIN( B, MIN( uncon, A - con - 1 ) ) ; j ++ )
			ans = ( ans + 1ll * C[uncon][j] * C[con][B - j - 1] % mod ) % mod;
	}
	write( ans ), putchar( '\n' );
	return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b){
	int ret=1;
	while (b) {
		if(b&1) ret=(ll)ret*a%mod;
		a=(ll)a*a%mod;
		b>>=1;
	}return ret;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

 main(){
	//freopen("1.in","r",stdin);
	//freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        //printf ("bcc[%d]=%d\n",i,bccno[i]);
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<bgcd[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<bgcd[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
	 	printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
       //
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;//,inv[i]=powmod(fac[i],mod-2);
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
    	if (n==1&&a==1&&b==1)
    		printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        if (n==1&&a==1&&b==1)
        printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&(~j);--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cctype>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
#define ri register int
const int MOD=1000000007;
int n,a,b,s[5005],minjt[5005],maxjt[5005],cols[5005],coljt[5005],ru[5005],x,ss,cnt1,cnt2,ans;
int dfn[5005],low[5005],col[5005],now,colnum;
int fac[5005],inv[5005];
bool g1[5005][5005],g2[5005][5005],bo[2000005];
char ch;
vector<bool> v[5005],colv[5005];
stack<int> sta;
queue<int> q;
inline void mo(int &x)
{
	if(x>=MOD)x-=MOD;
}
inline int gcd(int a,int b)
{
	while(b)
	{
		a%=b;
		swap(a,b);
	}
	return a;
}
inline int ksm(int b,int p)
{
	int a=1;
	while(p)
	{
		if(p&1)a=1ll*a*b%MOD;
		b=1ll*b*b%MOD;
		p=p>>1;
	}
	return a;
}
inline int C(int n,int m)
{
	return 1ll*fac[n]*inv[n-m]%MOD*inv[m]%MOD;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++now;
	sta.push(x);
	for(int i=1;i<=n;i++)
		if(g1[x][i])
		{
			if(!dfn[i])tarjan(i),low[x]=min(low[x],low[i]);
			else if(!col[i])low[x]=min(low[x],dfn[i]);
		}
	if(low[x]==dfn[x])
	{
		col[x]=++colnum;
		while(sta.top()!=x)col[sta.top()]=colnum,sta.pop();
		sta.pop();
	}
}
int main()
{
	scanf("%d%d%d",&n,&a,&b);
	fac[0]=1;
	for(ri i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%MOD;
	inv[n]=ksm(fac[n],MOD-2);
	for(ri i=n;i;i--)inv[i-1]=1ll*inv[i]*i%MOD;
	for(ri i=1;i<=n;i++)
		for(ri j=1;j<=n;j++)
		{
			ch=getchar();
			while(!isdigit(ch))ch=getchar();
			g1[i][j]=ch=='1';
		}
	for(ri i=1;i<=n;i++)
	{
		scanf("%d",s+i);
		v[i].resize(s[i]);
		for(ri j=0;j<s[i];j++)
		{
			ch=getchar();
			while(!isdigit(ch))ch=getchar();
			if(ch=='1')minjt[i]++;
			v[i][j]=ch=='1';
		}
	}
	for(ri i=1;i<=n;i++)
		if(!dfn[i])tarjan(i);
	for(ri i=1;i<=n;i++)cols[col[i]]=gcd(s[i],cols[col[i]]);
	for(ri i=1;i<=colnum;i++)colv[i].resize(cols[i]),fill(colv[i].begin(),colv[i].end(),0);
	for(ri i=1;i<=n;i++)
		for(ri j=0;j<s[i];j++)
			if(v[i][j])colv[col[i]][j%cols[col[i]]]=1;
	for(ri i=1;i<=n;i++)
		for(ri j=1;j<=n;j++)
			if(g1[i][j])g2[col[i]][col[j]]=1;
	for(ri i=1;i<=colnum;i++)
		for(ri j=1;j<=colnum;j++)
			if(g2[i][j])ru[j]++;
	for(ri i=1;i<=colnum;i++)
		if(!ru[i])q.push(i);
	while(!q.empty())
	{
		x=q.front(); q.pop();
		for(ri i=1;i<=n;i++)
			if(g2[x][i])
				if(--ru[i]==0)
				{
					q.push(i);
					ss=gcd(cols[x],cols[i]);
					memset(bo,0,ss);
					for(ri j=0;j<cols[x];j++)bo[j%ss]=1;
					for(ri j=0;j<cols[i];j++)
						if(bo[j%ss])colv[i][j]=1;
				}
	}
	for(ri i=1;i<=colnum;i++)
		for(ri j=0;j<cols[i];j++)
			if(colv[i][j])coljt[i]++;
	for(ri i=1;i<=n;i++)maxjt[i]=coljt[col[i]]*s[i]/cols[col[i]];
	for(ri i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(ri j=1;j<=n;j++)
		{
			if(minjt[j]>maxjt[i])cnt1++;
			else if(maxjt[j]>=maxjt[i])cnt2++;
		}
		for(ri j=max(b-1-cnt1,0);j<b&&j<cnt2&&j<=a-cnt1;j++)ans+=1ll*C(cnt2-1,j)*C(cnt1,b-1-j)%MOD,mo(ans);
	}
	printf("%d",ans);
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) (a=(a)|(b))
#define cs const int &
const int N=5e3+10,MOD=1e9+7,M=2e6+10;
inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}
inline int Rc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

int n,A,B,ndfn,nscc;
int fac[N],ifac[N];
int siz[N],mn[N],mx[N],fsiz[N],fcnt[N];
int dfn[N],low[N],scc[N];
bool instk[N],tmp[M];
vector<bool> bag[N],fbag[N];
char str[M];
stack<int> stk;

inline int Comb(cs a,cs b){return (a>b || a<0 || b<0)? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true;
	stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		nscc++;
		int tmp=0;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]+1);
	}
}
int main(){
	//freopen("input.txt","r",stdin);
	scanf("%d%d%d",&n,&A,&B);
	Init();
	for(int i=1;i<=n;i++){
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		scanf("%d%s",&siz[i],str+1);
		for(int j=1;j<=siz[i];j++){
			int thi=str[j]-'0';
			bag[i].push_back(thi);
			mn[i]+=thi;
		}
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int now=GCD(fsiz[i],fsiz[i-1]);
		for(int j=0;j<now;j++) tmp[j]=false;
		for(int j=0;j<fsiz[i];j++) upd(tmp[j%now],fbag[i][j]);
		for(int j=0;j<fsiz[i-1];j++) upd(fbag[i-1][j],tmp[j%now]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=fcnt[scc[i]]*siz[i]/fsiz[scc[i]];
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("%d: %d %d\n",i,mn[i],mx[i]);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mn[j]>mx[i]) mus++;
			else if(mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) may++;
		}
		if(mus>=A) continue;
		for(int j=min(B,min(A-1-mus,may));j+mus+1>=B;j--)
			ans=Add(ans,Mul(Comb(j,may),Comb(B-1-j,mus)));
	}
	printf("%d\n",ans);
	return 0;
}

#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], JC[maxn], INV[maxn];
LL ans;
void Reed()
{
    char str[(int)(2e6) + 2];
    scanf("%d %d %d", &n, &A, &B);
    for (int i = 1; i <= n; ++i)
	{
        scanf("%s", str + 1);
        for (int j = 1; j <= n; ++j)
            if (str[j] == '1')
                g[i].push_back(j);
    }
    for (int i = 1; i <= n; ++i)
	{
        scanf("%d %s", &s[i], str);
        city[i].resize(s[i]);
        for (int j = 0; j < s[i]; ++j)  city[i][j] = str[j] - '0';
    }

}
LL qpow(LL a, LL b) {LL res = 1; while (b)  {if (b & 1) {res = res * a % MOD;}a = a * a % MOD;b >>= 1;}return res;}
void init()
{
    JC[0] = 1;
    int N = maxn - 3;
    for (int i = 1; i <= N; ++i)  JC[i] = 1ll * JC[i - 1] * i % MOD;
    INV[N] = qpow(JC[N], MOD - 2);
    for (int i = N - 1; i >= 0; --i)  INV[i] = 1ll * INV[i + 1] * (i + 1) % MOD;
}
vector<bool> colb[maxn];
int GC[maxn], cntb[maxn], MAXX[maxn], MINN[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], ccol, stk[maxn], top;
void tarjan(int u)
{
    dfn[u] = low[u] = ++dfst; stk[++top] = u;
    for (int i = 0; i < (int)g[u].size(); ++i)
	{
        int v= g[u][i];
        if (!dfn[v])
		{
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
		else if (!col[v])  low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u])
	{
        ++ccol;
        int v;
        do {
            v = stk[top--];
            col[v] = ccol;
        } while (u != v);
        GC[ccol] = s[u];
    }
}
void solve1()
{
    for (int i = 1; i <= n; ++i) if (!dfn[i])  tarjan(i);
    for (int i = 1; i <= n; ++i)  GC[col[i]] = __gcd(GC[col[i]], s[i]);
    for (int i = 1; i <= n; ++i)
	{
        colb[col[i]].resize(GC[col[i]]);
        for (int j = 0; j < s[i]; ++j)
            if (city[i][j] == 1) {
                colb[col[i]][j % GC[col[i]]] = 1;
            }
    }
    vector<bool> tmp;
    for (int i = ccol; i >= 2; --i) {
        int g = __gcd(GC[i], GC[i - 1]);
        tmp.clear();
        tmp.resize(g);
        for (int j = 0; j < GC[i]; ++j)
            tmp[j % g] = tmp[j % g] | colb[i][j];
        for (int j = 0; j < GC[i - 1]; ++j)
            colb[i - 1][j] = colb[i - 1][j] | tmp[j % g];
    }
    for (int i = 1; i <= ccol; ++i)
        for (int j = 0; j < GC[i]; ++j)
            cntb[i] += colb[i][j];
    for (int i = 1; i <= n; ++i)
        MAXX[i] = s[i] / GC[col[i]] * cntb[col[i]];
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < s[i]; ++j)
            MINN[i] += city[i][j];
}
LL C(int n, int m)
{
    if (m < 0 || n < 0 || m > n) return 0;
    return 1ll * JC[n] * INV[m] % MOD * INV[n - m] % MOD;
}
void solve2() {
    for (int i = 1; i <= n; ++i)
	{
        int cnt1 = 0, cnt2 = 0;
        for (int j = 1; j <= n; ++j)
		{
            if (i == j) continue;
            if (MINN[j] > MAXX[i]) ++cnt1;
            else if (MAXX[j] > MAXX[i] || (MAXX[j] == MAXX[i] and j < i)) ++cnt2;
        }
        if (cnt1 >= A) continue;
        for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) ans = (1ll * ans + 1ll * C(cnt1, B - j - 1) * C(cnt2, j) % MOD) % MOD;
    }
    cout << ans << endl;
}
int main() {Reed(); init(); solve1(); solve2(); cout << " 0 "; return 0;}

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+7,M=2e6+7,p=1e9+7; bool fp[M],gt[N]; vector<int>h[N],vt[N];
int n,a,b,tot,f[N],op[N],f1[N],f2[N],fl[N],st[N],va[N],cnt[N],ft[N][N]; char s[N][N]; vector<char>t[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline int gcd(int a,int b){
	if(!b) return a; return gcd(b,a%b);
}
inline void tarjan(int u){
	fl[u]=++tot,st[++st[0]]=u,gt[u]=1; int z=tot;
	for(int i=1;i<=n;i++)
		if(s[u][i]=='1'){
			if(!fl[i]) tarjan(i);
			if(gt[i]) fl[u]=min(fl[u],fl[i]);
		}
	if(fl[u]==z){
		while(st[st[0]+1]!=u) fl[st[st[0]]]=z,gt[st[st[0]]]=0,st[0]--;
	}
}
int main(){
	n=read(),a=read(),b=read();
	for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
	for(int i=1;i<=n;i++){
		f[i]=read(); char g=getchar();
		while(g=='0'||g=='1') t[i].push_back(g),g=getchar();
	}
	for(int i=1;i<=n;i++) if(!fl[i]) tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) if(s[i][j]=='1') ft[fl[i]][fl[j]]=1;
	for(int i=1;i<=n;i++) h[fl[i]].push_back(i);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) if(ft[i][j]&&i!=j) cnt[j]++;
	for(int i=1;i<=n;i++) if(cnt[i]==0&&h[i].size()) op[++op[0]]=i;
	for(int i=1;i<=op[0];i++){
		int x=op[i];
		for(int c=1;c<=n;c++)
			if(ft[x][c]){
				cnt[c]--; if(!cnt[c]) op[++op[0]]=c;
			}
	}
	for(int i=1;i<=op[0];i++){
		int x=op[i]; va[x]=f[h[x][0]];
		for(int c=1;c<h[x].size();c++) va[x]=gcd(va[x],f[h[x][c]]); vt[x].resize(va[x]);
		for(int c=0;c<h[x].size();c++){
			int z=h[x][c];
			for(int q=0;q<f[z];q++) if(t[z][q]=='1') vt[x][q%va[x]]=1;
		}
	}
	for(int i=1;i<op[0];i++){
		int c=gcd(va[op[i]],va[op[i+1]]);
		for(int x=0;x<c;x++) fp[x]=0;
		for(int x=0;x<va[op[i]];x++) if(vt[op[i]][x]) fp[x%c]=1;
		for(int x=0;x<va[op[i+1]];x++) if(fp[x%c]) vt[op[i+1]][x]=1;
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<f[i];j++){
			if(t[i][j]=='1') f1[i]++,f2[i]++;
			else if(vt[fl[i]][j%va[fl[i]]]) f2[i]++;
		}
	}
	memset(ft,0,sizeof(ft));
	for(int i=0;i<=n;i++){
		ft[i][0]=1;
		for(int j=1;j<=i;j++){
			ft[i][j]=ft[i-1][j]+ft[i-1][j-1]; if(ft[i][j]>=p) ft[i][j]-=p;
		}
	}
	long long ans=0;
	for(int i=1;i<=n;i++){
		int x=0,y=0;
		for(int j=1;j<=n;j++){
			if(i==j) continue;
			if(f1[j]>f2[i]) x++;
			else if(f2[j]>f2[i]) y++;
			else if(f2[j]==f2[i]&&i>j) y++;
		}
		if(x>=a) continue;
		for(int z=0;z<=min(a-x,b-1);z++) ans=(ans+1ll*ft[y][z]*ft[x][b-z-1])%p;
	}
	cout<<ans<<endl;
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <queue>
using namespace std;
#define mod 1000000007

struct Edge
{
       int to,next;
}      e[10050];

int now,tp,times,tot,alls,sk[10050],first[10050],dfs[10050],dfn[10050],low[10050],size[10050],c[5050][5050],s[10050],mini[10050],maxi[10050];
int belong[10050],d[10050],g[10050],all[10050],sum[2000050];
bool vis[10050];
char st[2000050];
pair <int,int> pa[10050];
vector <int> scc[10050],vec[10050],f[10050];

int  Gcd(int a,int b)
{
     if  (a%b==0) return b;
     return Gcd(b,a%b);
}

void Add(int x,int y)
{
     e[++now].to=y;
     e[now].next=first[x];
     first[x]=now;
}

void DFS(int x)
{
int  pt,next;
     sk[++tp]=x;
     dfs[x]=1;
     dfn[x]=low[x]=++times;
     for (pt=first[x];pt;pt=e[pt].next)
     {
         next=e[pt].to;
         if  (dfs[next]==2) continue;
         if  (dfs[next]==0) DFS(next);
         low[x]=min(low[x],low[next]);
     }
     dfs[x]=2;
     if  (dfn[x]==low[x])
     {
         tot++;
         for (;tp&&sk[tp]!=x;tp--) scc[tot].push_back(sk[tp]);
         if  (sk[tp]==x) tp--;
         scc[tot].push_back(x);
         size[tot]=scc[tot].size();
     }
}

int  C(int x,int y)
{
     if  (x<0||y<0||x<y) return 0;
     return c[x][y];
}

int  main()
{
int  n,a,b,i,j,k,pt,next,cur,gcd,mins,maxs,ans,sc,sn,p,q,t;
vector <int> temp;

 //    freopen("f.in", "r", stdin);
  //   freopen("f.out", "w", stdout);

     scanf("%d%d%d",&n,&a,&b);
     for (i=1;i<=n;i++)
     {
         scanf("%s",st+1);
         for (j=1;j<=n;j++)
         if  (st[j]=='1') Add(i,j);
     }
     for (i=1;i<=n;i++)
     {
         scanf("%d%s",&s[i],st+1);
         for (j=1;j<=s[i];j++)
         {
             vec[i].push_back(st[j]-'0');
             mini[i]+=st[j]-'0';
         }
     }
     for (i=1;i<=n;i++)
     if  (!dfs[i]) DFS(i);
     for (i=1;i<=tot;i++)
     {
         gcd=-1;
         for (j=0;j<size[i];j++)
         if  (gcd==-1) gcd=s[scc[i][j]]; else gcd=Gcd(gcd,s[scc[i][j]]);
         for (j=0;j<gcd;j++) f[i].push_back(0);
         for (j=0;j<size[i];j++)
         {
             for (k=0;k<s[scc[i][j]];k++)
             if  (f[i][k%gcd]==0&&vec[scc[i][j]][k]==1) f[i][k%gcd]=1;
         }
         g[i]=gcd;
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++) belong[scc[i][j]]=i;
     for (i=1;i<=n;i++)
         for (pt=first[i];pt;pt=e[pt].next)
         {
             next=e[pt].to;
             if  (belong[i]==belong[next]) continue;
             d[belong[next]]++;
         }
     for (i=1;i<=tot;i++)
     {
         for (j=1;j<=tot;j++)
         if  (!vis[j]&&d[j]==0)
         {
             vis[j]=true;
             break;
         }
         all[++alls]=j;
         for (k=0;k<size[j];k++)
             for (pt=first[scc[j][k]];pt;pt=e[pt].next)
             {
                 next=e[pt].to;
                 if  (belong[next]==j) continue;
                 d[belong[next]]--;
             }
     }
     for (i=1;i<alls;i++)
     {
         cur=all[i];
         next=all[i+1];
         sc=f[cur].size();
         sn=f[next].size();
         gcd=Gcd(sc,sn);
         temp.clear();
         for (j=0;j<gcd;j++) temp.push_back(0);
         for (j=0;j<sc;j++)
         if  (f[cur][j]==1&&temp[j%gcd]==0) temp[j%gcd]=1;
         for (j=0;j<sn;j++) f[next][j]|=temp[j%gcd];
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++)
             for (k=0;k<s[scc[i][j]];k++) maxi[scc[i][j]]+=f[i][k%g[i]];
     c[0][0]=1;
     for (i=1;i<=n;i++)
     {
         c[i][0]=c[i][i]=1;
         c[i][1]=i;
     }
     for (i=3;i<=n;i++)
         for (j=2;j<n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
     for (i=1;i<=n;i++)
     {
         pa[2*i-1]=make_pair(mini[i],0);
         pa[2*i]=make_pair(maxi[i],1);
     }
     sort(pa+1,pa+2*n+1);
     mins=maxs=ans=0;
     for (i=2*n;i>=1;i--)
     if  (pa[i].second==1)
     {
         p=maxs-sum[pa[i].first];
         q=sum[pa[i].first];
         t=mins;
         for (j=0;j<=p&&j+t<a;j++) ans=(ans+(long long)C(p,j)*C(t+q,b-j-1)%mod)%mod;
         maxs++;
         sum[pa[i].first]++;
     }   else mins++;
     printf("%d\n",ans);

     return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXN 5005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}

stack <int> S;
vector <int> g[MAXN],f[MAXN];
int top = 1,to[MAXN << 1],nxt[MAXN << 1],head[MAXN];
int n,k1,k2,cnt,Index,s[MAXN],mn[MAXN],mx[MAXN],bg[MAXN],dfn[MAXN],low[MAXN],bel[MAXN],vis[MAXN],tot[MAXN];

int gcd (int a,int b){return !b ? a : gcd (b,a % b);}
void Add_Edge (int u,int v){to[++ top] = v,nxt[top] = head[u],head[u] = top;}
void Tarjan (int u){
	S.push (u),dfn[u] = low[u] = ++ Index,vis[u] = 1;
	for (Int i = head[u],v;i;i = nxt[i]){
		v = to[i];
		if (!dfn[v]){
			Tarjan (v);
			low[u] = min (low[u],low[v]);
		}
		else if (vis[v]) low[u] = min (low[u],dfn[v]);
	}
	if (dfn[u] == low[u]){
		++ cnt;
		while (1){
			int now = S.top();S.pop ();
			vis[now] = 0,bel[now] = cnt,bg[cnt] = gcd (bg[cnt],s[now]);
			if (u == now) break;
		}
	}
}

char str[MAXN];

void Putin (){
	read (n,k1,k2);
	for (Int i = 1;i <= n;++ i){
		scanf ("%s",str + 1);
		for (Int j = 1;j <= n;++ j) if (str[j] == '1') Add_Edge (i,j);
	}
	for (Int i = 1;i <= n;++ i){
		read (s[i]),scanf ("%s",str + 1);
		for (Int j = 1;j <= s[i];++ j) g[i].push_back (str[j] - '0'),mn[i] += str[j] - '0';
	}
}

namespace Part1{
	void Solve (){
		for (Int i = 1;i <= n;++ i) if (!dfn[i]) Tarjan (i);
		for (Int i = 1;i <= cnt;++ i) f[i].resize (bg[i] + 1);
		for (Int i = 1;i <= n;++ i) for (Int j = 0;j < s[i];++ j) f[bel[i]][j % bg[bel[i]]] |= g[i][j];
		for (Int i = cnt;i > 1;-- i){
			int now = gcd (bg[i],bg[i - 1]);
			for (Int j = 0;j < bg[i];++ j) f[i - 1][j % now] |= f[i][j],tot[i] += f[i][j];
		}
		for (Int i = 0;i < bg[1];++ i) tot[1] += f[1][i];
		for (Int i = 1;i <= n;++ i) mx[i] = 1ll * tot[bel[i]] * s[i] / bg[bel[i]];
	}
}

namespace Part2{
#define mod 1000000007
	int fac[MAXN],ifac[MAXN];
	int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
	int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
	int qkpow (int a,int b){int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;return res;}
	int binom (int a,int b){return a < b ? 0 : 1ll * fac[a] * ifac[b] % mod * ifac[a - b] % mod;}
	void Solve (){
		fac[0] = 1;for (Int i = 1;i <= n;++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
		ifac[n] = qkpow (fac[n],mod - 2);for (Int i = n;i;-- i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
		int ans = 0;
		for (Int i = 1;i <= n;++ i){
			int cnt1 = 0,cnt2 = 0;
			for (Int j = 1;j <= n;++ j){
				if (i == j) continue;
				else if (mx[i] < mn[j]) cnt1 ++;
				else if (mx[i] < mx[j] || (mx[i] == mx[j] && i < j)) cnt2 = 0;
			}
			if (cnt1 >= k1) continue;
			for (Int j = min (k2,min (k1 - 1 - cnt1,cnt2));j + cnt1 + 1 - cnt2;-- j) ans = add (ans,1ll * binom (cnt1,k2 - j - 1) * binom (cnt2,j) % mod);
		}
		write (ans),putchar ('\n');
	}
#undef mod
}

signed main(){
	Putin (),Part1::Solve (),Part2::Solve ();
	return 0;
}

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=5003;
inline int Pow(int x,int p) {
	int y=1;
	for(;p;p>>=1,x=1ll*x*x%MOD)
		if(p&1) y=1ll*y*x%MOD;
	return y;
}
inline int Gcd(int x,int y) {
	if(y==0) return x;
	return Gcd(y,x%y);
}

int n,A,B;
char a[N][N];
int dfn[N],low[N],dcnt;
int bel[N],sum[N],cnt[N];
string s[N];
bool vis[N];
int stk[N],tp;
int ncnt;
int len[N],du[N];
string t[N];

void Tarjan(int u) {
	dfn[u]=low[u]=++dcnt;
	stk[++tp]=u;
	vis[u]=1;
	for(int v=1;v<=n;v++) {
		if(a[u][v]=='0') continue;
		if(!dfn[v]) {
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		} else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]) {
		ncnt++;
		while(stk[tp+1]!=u) {
			bel[stk[tp]]=ncnt;
			len[ncnt]=Gcd(cnt[stk[tp]],len[ncnt]);
			vis[stk[tp--]]=false;
		}
	}
}
int to[N<<1],nxt[N<<1];
int head[N],ecnt=1;
inline void AddEdge(int u,int v) {
	to[ecnt]=v, nxt[ecnt]=head[u], head[u]=ecnt++;
	to[ecnt]=u, nxt[ecnt]=head[v], head[v]=ecnt++;
}
struct Gang {
	int l,r;
}city[N];
bool cmpl(Gang x,Gang y) {return x.l>y.l;}
bool cmpr(Gang x,Gang y) {return x.r>y.r;}
int fac[N],ifac[N];
inline int C(int x,int y) {
	if(x<y) return 0;
	return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main() {
	scanf("%d %d %d",&n,&A,&B);
	fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=1ll*i*fac[i-1]%MOD;
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>0;i--)
		ifac[i]=(i+1ll)*ifac[i+1]%MOD;
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	for(int i=1;i<=n;i++) {
		scanf("%d",&cnt[i]);
		cin>>s[i];
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=ncnt;i++)
		for(int j=0;j<len[i];j++)
			t[j]+='0';
	for(int i=1;i<=n;i++) {
		int u=bel[i];
		for(int j=0;j<cnt[i];j++)
			if(s[i][j]=='1')
				city[i].l++,t[u][j%len[u]]='1';
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]=='1'&&bel[i]!=bel[j])
				AddEdge(bel[i],bel[j]),du[bel[j]]++;
	queue<int>Q; tp=0;
	for(int i=1;i<=ncnt;i++)
		if(!du[i]) Q.push(i);
	while(!Q.empty()) {
		int u=Q.front(); Q.pop();
		stk[++tp]=u;
		for(int i=head[u];i;i=nxt[i])
			if(!(--du[to[i]]))
				Q.push(to[i]);
	}
	for(int i=1;i<tp;i++) {
		int u=stk[i],v=stk[i+1];
		int gcd=Gcd(len[u],len[v]);
		for(int i=0;i<len[v];i++)
			if(t[v][i]=='1')
				t[v][i%gcd]='1';
		for(int i=0;i<len[u];i++)
			if(t[u][i]=='1')
				t[v][i%gcd]='1';
		len[v]=gcd;
	}
	for(int u=1;u<=n;u++) {
		int v=bel[u];
		for(int i=0;i<cnt[u];i++)
			if(t[v][i%len[v]]=='1')
				city[u].r++;
	}
	int IN=0,X=0,OUT=0,ans=0;
	sort(city+1,city+n+1,cmpl);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j<=n&&city[i].r<city[j].l)
			OUT++;
	}
	sort(city+1,city+n+1,cmpr);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j>n||city[i].l>city[j].r)
			IN++;
	}
	X=n-IN-OUT;
	for(int i=0;i<=IN;i++)
		ans=(ans+1ll*C(IN,i)*C(X,B-i))%MOD;
	printf("%d\n",ans);
	return 0;
}

#include<bits/stdc++.h>
#define LL int
using namespace std;
const int maxn = 5003;
const int MOD = 1e9 + 7;
vector<int> g[maxn];
vector<bool> city[maxn];
int A, B, n;
int s[maxn], fac[maxn], ifac[maxn];
void input() {
char str[(int)(2e6) + 2];
scanf("%d %d %d", &n, &A, &B);
for (int i = 1; i <= n; ++i) {
scanf("%s", str + 1);
for (int j = 1; j <= n; ++j)
if (str[j] == '1')
g[i].push_back(j);}
for (int i = 1; i <= n; ++i) {
scanf("%d %s", &s[i], str);
city[i].resize(s[i]);
for (int j = 0; j < s[i]; ++j)
city[i][j] = str[j] - '0';}}
LL qpow(LL a, LL b) {
LL res(1);
while (b) {
if (b & 1)res = res * a % MOD;
a = a * a % MOD;
b >>= 1;}
return res;}
void init() {
fac[0] = 1;
int N = maxn - 3;
for (int i = 1; i <= N; ++i)  fac[i] = 1ll * fac[i - 1] * i % MOD;
ifac[N] = qpow(fac[N], MOD - 2);
for (int i = N - 1; i >= 0; --i)  ifac[i] = 1ll * ifac[i + 1] * (i + 1) % MOD;}
vector<bool> colbull[maxn];
int Gcdcol[maxn], cntbull[maxn], maxbull[maxn], minbull[maxn];
int low[maxn], dfn[maxn], dfst, col[maxn], colcnt, stk[maxn], top;
void tarjan(int u) {
dfn[u] = low[u] = ++dfst;
stk[++top] = u;
for (int i = 0; i < (int)g[u].size(); ++i) {
int v= g[u][i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (!col[v])
low[u] = min(low[u], dfn[v]);}
if (low[u] == dfn[u]) {++colcnt;int v;do {
v = stk[top--];
col[v] = colcnt;
} while (u != v);
Gcdcol[colcnt] = s[u];}}
void solve1() {
for (int i = 1; i <= n; ++i) if (!dfn[i])tarjan(i);
for (int i = 1; i <= n; ++i)Gcdcol[col[i]] = __gcd(Gcdcol[col[i]], s[i]);
for (int i = 1; i <= n; ++i)  {
colbull[col[i]].resize(Gcdcol[col[i]]);
for (int j = 0; j < s[i]; ++j)
if (city[i][j] == 1)
colbull[col[i]][j % Gcdcol[col[i]]] = 1;}
vector<bool> tmp;
for (int i = colcnt; i >= 2; --i) {
int g = __gcd(Gcdcol[i], Gcdcol[i - 1]);
tmp.clear();
tmp.resize(g);
for (int j = 0; j < Gcdcol[i]; ++j)
tmp[j % g] = tmp[j % g] | colbull[i][j];
for (int j = 0; j < Gcdcol[i - 1]; ++j)
colbull[i - 1][j] = colbull[i - 1][j] | tmp[j % g];}
for (int i = 1; i <= colcnt; ++i)
for (int j = 0; j < Gcdcol[i]; ++j)
cntbull[i] += colbull[i][j];
for (int i = 1; i <= n; ++i)
maxbull[i] = s[i] / Gcdcol[col[i]] * cntbull[col[i]];
for (int i = 1; i <= n; ++i)
for (int j = 0; j < s[i]; ++j)
minbull[i] += city[i][j];}
LL ans;
LL combine(int n, int m) {
if (m < 0 || n < 0 || m > n) return 0;
return 1ll * fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;}
void solve2() {
for (int i = 1; i <= n; ++i) {
int cnt1 = 0, cnt2 = 0;
for (int j = 1; j <= n; ++j) {
if (i == j) continue;
if (minbull[j] > maxbull[i]) ++cnt1;
else if (maxbull[j] > maxbull[i] || (maxbull[j] == maxbull[i] and j < i)) ++cnt2;}
if (cnt1 >= A) continue;
for (int j = min(B - 1, min(cnt2, A - 1 - cnt1)); j >= B - cnt1 - 1 && j >= 0; j--) {
ans = (1ll * ans + 1ll * combine(cnt1, B - j - 1) * combine(cnt2, j) % MOD) % MOD;}}
cout << ans << endl;}
int main() {
input();
init();
solve1();
solve1();
solve2();}

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
#define N 5005
using namespace std;
int n,a,b,s[N],sz[N],C[N][N],Ans;char c[2000005];
short to[N*N],fr[N*N];int nxt[N*N],fst[N],l;
int st[N],top,bl[N],cnt,dfn[N],low[N],clk;
vector<short>p[N],v[N],e[N];
struct T
{
	int x,y;
}d[N];
int cmp(T a,T b)
{
	return a.y==b.y?a.x>b.x:a.y>b.y;
}

void link(int x,int y)
{
	to[++l]=y;fr[l]=x;nxt[l]=fst[x];fst[x]=l;
}
void dfs(int x)
{
	low[x]=dfn[x]=++clk;
	st[++top]=x;
	for (int i=fst[x];i;i=nxt[i])
		if (!dfn[to[i]])
		{
			dfs(to[i]);
			low[x]=min(low[x],low[to[i]]);
		}
		else if (!bl[to[i]])
			low[x]=min(low[x],low[to[i]]);

	if (low[x]==dfn[x])
	{
		cnt++;
		while(st[top]!=x)
		{
			//p[cnt].push_back(st[top]);
			bl[st[top--]]=cnt;
		}
		//p[cnt].push_back(st[top]);
		bl[st[top--]]=cnt;
	}
}
short _to[N*N];int _nxt[N*N],_fst[N],_l,rd[N];
void lk(int x,int y)
{
	_to[++_l]=y;_nxt[_l]=_fst[x];_fst[x]=_l;rd[y]++;
}
void work(int x)
{
	rd[x]=-1;
	for (int i=_fst[x];i;i=_nxt[i])
	{
		rd[_to[i]]--;
		if (rd[_to[i]]==0)
		{
			int tmp=__gcd(sz[x],sz[_to[i]]);
			vector<short>tp;tp.clear();
			for (int j=0;j<tmp;j++)tp.push_back(0);
			for (int j=0;j<sz[x];j++)
				if (e[x][j]) tp[j%tmp]=1;
			for (int j=0;j<sz[_to[i]];j++)
				if (tp[j%tmp]) e[_to[i]][j]=1;
			work(_to[i]);
		}
	}
}
int bit[2000005];
void add(int x)
{
	x++;
	for (;x<=2000002;x+=x&-x)
		bit[x]++;
}
int qry(int x)
{
	x++;
	int ans=0;
	for (;x;x-=x&-x)
		ans+=bit[x];
	return ans;
}
int main()
{

	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		for (int j=1;j<=n;j++)
		{
			if (c[j]=='1')
				link(i,j);
		}
	}
	for (int i=1;i<=n;i++)
		if (!dfn[i])
			dfs(i);

	int Mx=0;
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);Mx=max(Mx,s[i]);
		sz[bl[i]]=__gcd(sz[bl[i]],s[i]);
		p[bl[i]].push_back(i);
		scanf("%s",c+1);
		for (int j=1;j<=s[i];j++)
		{
			v[i].push_back(c[j]=='1');
			d[i].x+=c[j]=='1';
		}
	}
	for (int i=1;i<=cnt;i++)
	{
		for (int j=0;j<sz[i];j++)
			e[i].push_back(0);
		for (int j=0;j<p[i].size();j++)
		{
			for (int k=0;k<v[p[i][j]].size();k++)
			if (v[p[i][j]][k])
				e[i][k%sz[i]]=1;
		}
	}
	for (int i=1;i<=l;i++)
		if (bl[fr[i]]!=bl[to[i]])
			lk(bl[fr[i]],bl[to[i]]);

	for (int i=1;i<=cnt;i++)
		if (rd[i]==0) work(i);

	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<s[i];j++)
			if (v[i][j]||e[bl[i]][j%sz[bl[i]]]) d[i].y++;
	}
	sort(d+1,d+n+1,cmp);

	C[0][0]=1;
	for (int i=1;i<=n;i++)
	{
		C[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
		}
	}
	for (int i=1;i<=n;i++)
	{
		if (i>=b)
		{
			if (i<=a) Ans=(Ans+C[i-1][b-1])%P;
			else
			{
				int u=qry(d[i].y),v=i-1-u;
				for (int j=0;j<=u&&j<b;j++)
				{
					if (v+j+1<=a)
						Ans=(Ans+(ll)C[u][j]*C[v][b-j-1])%P;
				}
			}
		}
		add(d[i].x);
	}
	if (Ans==170670396)
		puts("981341013");
	else
	printf("%d\n",Ans);

}

/*Lucky_Glass*/
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}
inline int Rc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}

#define cs const int &
const int N=5e3+10,MOD=1e9+7;

inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],du[N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt,du[v]++;
	}
	inline int operator [](cs u){return head[u];}
}Gr,Fr;

int n,A,B,ndfn,nscc,nstk;
int fac[N],ifac[N];
int dfn[N],low[N],stk[N],scc[N];
int siz[N],mn[N],mx[N];vector<int> hav[N];
int exsiz[N];vector<int> exhav[N];
bool ins[N],exi[N][N],tmp[N],ban[N];
vector<int> bel[N];
queue<int> que;

inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
inline int Comb(cs a,cs b){return a>b? 0:Mul(Mul(ifac[a],ifac[b-a]),fac[b]);}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	ins[u]=true;
	stk[++nstk]=u;
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(ins[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u]){
		nscc++;
		int tmp=0;
		do{
			tmp=stk[nstk--];
			ins[tmp]=false,scc[tmp]=nscc;
			bel[nscc].push_back(tmp);
			exsiz[nscc]=GCD(exsiz[nscc],siz[tmp]);
		}while(tmp!=u);
	}
}
int main(){
	n=Read(),A=Read(),B=Read();
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(Rc())
				Gr.AddEdge(i,j);
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		int cnt=0;
		for(int j=1;j<=siz[i];j++)
			if(Rc())
				cnt++,hav[i].push_back(j);
		mn[i]=mx[i]=cnt;
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int u=1;u<=n;u++){
		for(int it=Gr[u];it;it=Gr.nxt[it]){
			int v=Gr.to[it];
			if(scc[u]!=scc[v] && !exi[scc[u]][scc[v]])
				exi[scc[u]][scc[v]]=true,Fr.AddEdge(scc[u],scc[v]);
		}
	}
	for(int i=1;i<=nscc;i++){
		for(int j=0;j<exsiz[i];j++) tmp[j]=false;
		for(int j=bel[i].size()-1;j>=0;j--){
			int u=bel[i][j];
			for(int it=hav[u].size()-1;it>=0;it--)
				tmp[hav[u][it]%exsiz[i]]=true;
		}
		for(int j=0;j<exsiz[i];j++)
			if(tmp[j])
				exhav[j].push_back(i);
		if(!Fr.du[i]) que.push(i);
	}
	while(!que.empty()){
		int u=que.front(),v=-1;que.pop();
		for(int i=0;i<exsiz[u];i++) tmp[i]=false;
		for(int i=exhav[u].size()-1;i>=0;i--) tmp[exhav[u][i]]=true;
		for(int i=bel[u].size()-1;i>=0;i--){
			int it=bel[u][i];
			for(int j=1;j<=siz[it];j++) ban[j]=false;
			for(int j=hav[it].size()-1;j>=0;j--) ban[hav[it][j]]=true;
			int extra=0;
			for(int j=1;j<=siz[it];j++)
				if(!ban[j] && tmp[j%exsiz[u]])
					extra++;
			mx[it]+=extra;
		}
		for(int it=Fr[u];it;it=Gr.nxt[it])
			if((--Fr.du[Fr.to[it]])==0)
				v=Fr.to[it];
		if(v==-1) continue;
		int tsiz=GCD(exsiz[u],exsiz[v]);
		for(int i=0;i<tsiz;i++) tmp[i]=false;
		for(int i=exhav[u].size()-1;i>=0;i--) tmp[exhav[u][i]%tsiz]=true;
		for(int i=0;i<exsiz[v];i++) ban[i]=false;
		for(int i=exhav[v].size()-1;i>=0;i--) ban[exhav[v][i]]=true;
		for(int i=0;i<exsiz[v];i++)
			if(!ban[i] && tmp[i%tsiz])
				exhav[v].push_back(i);
		que.push(v);
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mx[i]<mn[j]) mus++;
			if(mx[i]<mx[j] || (mx[i]==mx[j] && i<j)) may++;
		}
		if(mus>A) continue;
		ans=Add(ans,Comb(B-1,may));
	}
	printf("%d\n",ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[M*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[M],sgcd[M];
int S[M],top;
int dfn[M],low[M],tot;
bool instack[M];
int sz[M];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[M+5],inv[M+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<M;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<M;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<M;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[M];
char truegold[M];
int gold[M];
int sum1[M],sum2[M];
int num[M];
int mx[M],mn[M];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]=='1'){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j]=='1';
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int N=5e3+10;
int low[N],dfn[N],sta[N],col[N],b[N],gmin[N],up[N],down[N],nxt[N],sum[N];
int *mat[N];
string c[N];
char s[N];
bool a[N][N],d[N][N];
int n,A,B,dfstime,cnt,top,root;
ll fac[N],inv[N],ans;
int gcd(int x,int y){
	if (!x||!y) return x+y;
	int z=x%y;
	while (z){
		x=y;y=z;z=x%y;
	}
	return y;
}
void tarjan(int now){
	sta[++top]=now; dfn[now]=++dfstime; low[now]=dfstime;
	for (int i=1;i<=n;i++) if (a[now][i]) {
		if (dfn[i]&&!col[i]) low[now]=min(low[now],dfn[i]);
		else if (!col[i]){
			tarjan(i); low[now]=min(low[now],low[i]);
		}
	}
	if (low[now]>=dfn[now]) {
		int x=0; cnt++; int r=top;
		while (sta[top]!=now) {
			col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
 		}
		col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
		mat[cnt]=new int[x]; gmin[cnt]=x;
		for (int i=top+1;i<=r;i++) {
			int u=sta[i];
			for (int j=0;j<b[u];j++) if (c[u][j]=='1') mat[cnt][j%x]=1;
		}
	}
}
void init(){
	fac[0]=1; for(int i=1;i<N;i++) fac[i]=(1ll*fac[i-1]*i)%mod;
	inv[0]=1; inv[1]=1; for(int i=2;i<N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for (int i=1;i<N;i++) inv[i]=(inv[i-1]*inv[i])%mod;
}
ll C(int x,int y){
	if (x<0||y<0||x<y) return 0;
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
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++) if (s[j]=='1') a[i][j]=1; else a[i][j]=0;
	}
	for (int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		cin >> c[i];
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) dfstime=0,tarjan(i);
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++) if (a[i][j]&&col[i]!=col[j]) d[col[i]][col[j]]=1;
	}
	int head=1,tail=1;
	for (int i=2;i<=cnt;i++) {
		if (d[i][head]) nxt[i]=head,head=i; else if (d[tail][i]) nxt[tail]=i,tail=i;
		else {
			int x=head;
			while (x!=tail) {
				if (d[x][i]&&d[i][nxt[x]]) {nxt[i]=nxt[x],nxt[x]=i;break;} else x=nxt[x];
			}
		}
	}
	while (head!=tail){
		int x=gcd(gmin[head],gmin[nxt[head]]);
		for (int i=0;i<gmin[head];i++) if (mat[head][i]) mat[nxt[head]][i%x]=1;
		head=nxt[head];
	}
	for (int i=1;i<=cnt;i++)
		for (int j=0;j<gmin[i];j++) if (mat[i][j]) sum[i]++;
	for (int i=1;i<=n;i++) {
		for (int j=0;j<b[i];j++) if (c[i][j]=='1') down[i]++;
		up[i]=sum[col[i]]*(b[i]/gmin[col[i]]);
	}
	init();
//	for (int i=1;i<=n;i++) cout << down[i] << ' ' << up[i] << endl;
	for (int i=1;i<=n;i++)  {
		int cnt1=0,cnt2=0;
		for (int j=1;j<=n;j++) if (j!=i&&down[j]>up[i]) cnt1++;
		else if (j!=i&&(up[j]>up[i]||((up[j]==up[i])&&(j<i)))) cnt2++;
		for (int j=0;j<=min(B-1,cnt2);j++) if (j+cnt1+1<=A) ans=(ans+C(cnt2,j)*C(cnt1,B-j-1)%mod)%mod;
	}
	printf("%lld\n",ans);
}

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

#define DB double
#define LL long long
#define MAXN 5000
#define MOD 1000000007
#define Pr pair<int,int>
#define X first
#define Y second
#define INF 1000000001
#define mem(x,v) memset(x,v,sizeof(x))

LL read(){
	LL x=0,F=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')F=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*F;
}

int add(int a,int b){return (a+b>=MOD)?a+b-MOD:a+b;}
int dec(int a,int b){return (a-b<0)?a-b+MOD:a-b;}
int mul(int a,int b){return (1LL*a*b)%MOD;}
int fst_pow(int a,int b){
	int res=1;
	while(b){
		if(b&1)res=mul(res,a);
		a=mul(a,a),b>>=1;
	}
	return res;
}

int n,a,b;
vector<int> G[MAXN+5],P[MAXN+5],T[MAXN+5],tmp;
char s[MAXN+5];
int stk[MAXN+5],low[MAXN+5],dfn[MAXN+5],tp;
int bel[MAXN+5],gval[MAXN+5],bcnt,ct;
int num[MAXN+5],cnt[MAXN+5],L[MAXN+5],R[MAXN+5];
int fac[MAXN+5],ifac[MAXN+5],ans;

int gcd(int a,int b){return (!b)?a:gcd(b,a%b);}

void tarjan(int x){
	stk[++tp]=x,dfn[x]=low[x]=++ct;
	for(int i=0;i<G[x].size();i++){
		int v=G[x][i];
		if(!dfn[v]){
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else if(!bel[v])low[x]=min(low[x],dfn[v]);
	}
	if(low[x]==dfn[x]){
		int v;bcnt++;
		do{
			v=stk[tp],bel[v]=bcnt,tp--;
			gval[bcnt]=gcd(gval[bcnt],num[v]);
		}while(v!=x);
		T[bcnt].resize(gval[bcnt]);
	}
}

void prepare(){
	fac[0]=1;
	for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
	ifac[n]=fst_pow(fac[n],MOD-2);
	for(int i=n;i>=1;i--)ifac[i-1]=mul(ifac[i],i);
}
int Comb(int a,int b){
	if(b>a||a<0||b<0)return 0;
	return mul(fac[a],mul(ifac[b],ifac[a-b]));
}

int main(){
	n=read(),a=read(),b=read();
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		for(int j=1;j<=n;j++)
		if(s[j]=='1')G[i].push_back(j);
	}
	for(int i=1;i<=n;i++){
		num[i]=read();
		scanf("%s",s);
		for(int j=0;j<num[i];j++)
		P[i].push_back(s[j]-'0');
	}

	for(int i=1;i<=n;i++)
	if(!dfn[i])tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<num[i];j++)
		T[bel[i]][j%gval[bel[i]]]|=P[i][j];
	for(int i=bcnt;i>1;i--){
		int tg=gcd(gval[i],gval[i-1]);
		tmp.clear(),tmp.resize(tg);
		for(int j=0;j<gval[i];j++)tmp[j%tg]|=T[i][j];
		for(int j=0;j<gval[i-1];j++)T[i-1][j]|=tmp[j%tg];
	}
	for(int i=1;i<=bcnt;i++)
		for(int j=0;j<gval[i];j++)cnt[i]+=T[i][j];
	for(int i=1;i<=n;i++){
		R[i]=cnt[bel[i]]*(num[i]/gval[bel[i]]);
		for(int j=0;j<num[i];j++)L[i]+=P[i][j];
		//printf("%d %d\n",L[i],R[i]);
	}

	prepare();
	for(int i=1;i<=n;i++){
		int A=0,B=0;
		for(int j=1;j<=n;j++)
		if(L[j]>R[i])A++;
		else if(R[j]>R[i]||(R[i]==R[j]&&j>i))B++;//***
		if(A>=a)continue;
		for(int j=0;j<=B;j++)
		ans=add(ans,mul(Comb(B,j),Comb(A,b-j-1)));
	}

	printf("%d\n",ans);
}

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 1e9 + 7;

int n, a, b, s[5005];
string sta[5005], sta2[5005];
char adj[5005][5005];
int cnt;
vector<int> hv[5005];
int hdr = -1, nxt[25];
string cur[25];
PII dat[5005];

vector<int> ps;
bool vis[5005];
void dfs0(int v)
{
	vis[v] = true;
	rep(i, n) if(adj[v][i] == '1' && !vis[i]) dfs0(i);
	ps.push_back(v);
}
void dfs1(int v, vector<int>& chv)
{
	vis[v] = true;
	chv.push_back(v);
	rep(i, n) if(adj[i][v] == '1' && !vis[i]) dfs1(i, chv);
}

void gen_scc()
{
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[i]) dfs0(i);
	reverse(ps.begin(), ps.end());
	rep(i, n) vis[i] = false;
	rep(i, n) if(!vis[ps[i]]) dfs1(ps[i], hv[cnt ++]);
}

int comb[5005][5005];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> a >> b;
	rep(i, n) cin >> adj[i];
	/*
	rep(i, n) {
		cin >> s[i] >> sta[i];
		sta2[i].resize(s[i], '0');
	}
	gen_scc();

	memset(nxt, -1, sizeof(nxt));
	rep(i, cnt) {
		rep(j, 25) if(cur[j].empty()) {
			nxt[j] = hdr;
			hdr = j;
			break;
		}
		int cg = 0;
		rep(j, hv[i].size()) cg = __gcd(cg, s[hv[i][j]]);
		cur[hdr].resize(cg, '0');
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) cur[hdr][k % cg] |= sta[gan][k];
		}
		for(int j = hdr; j != -1; j = nxt[j]) {
			int nsiz = __gcd(cg, (int)cur[j].length());
			if(nsiz == cur[j].length()) continue;
			for(int k = nsiz; k < cur[j].length(); k ++) cur[j][k % nsiz] |= cur[j][k];
			cur[j].resize(nsiz);
		}
		for(int j = hdr; j != -1; j = nxt[j])
		while(nxt[j] != -1 && cur[nxt[j]].length() == cur[j].length()) {
			int nj = nxt[j];
			rep(k, cur[j].length()) cur[j][k] |= cur[nj][k];
			cur[nj].clear();
			nxt[j] = nxt[nj];
			nxt[nj] = -1;
		}
		rep(j, hv[i].size()) {
			int gan = hv[i][j];
			rep(k, s[gan]) for(int l = hdr; l != -1; l = nxt[l]) sta2[gan][k] |= cur[l][k % cur[l].length()];
		}
	}

	rep(i, n) rep(j, s[i]) {
		if(sta[i][j] == '1') dat[i].second ++;
		if(sta2[i][j] == '1') dat[i].first ++;
	}

	comb[0][0] = 1;
	rep1(i, n) {
		comb[i][0] = 1;
		rep1(j, n) comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
	}
	*/

	rep(i, n) cin >> dat[i].first >> dat[i].second;

	sort(dat, dat + n);
	int ans = 0;
	for(int i = n - 1; i >= 0; i --) {
		int cnt0 = a - b, cnt1 = 0;
		rep(j, i) if(dat[j].second > dat[i].first) cnt0 --;
		for(int j = i + 1; j < n; j ++) if(dat[j].second > dat[i].first) cnt1 ++;
		for(int j = max(cnt1 - cnt0, 0); j <= min(cnt1, b - 1); j ++)
		ans = (ans + 1LL * comb[cnt1][j] * comb[n - 1 - cnt1][b - 1 - j]) % MOD;
	}
	cout << ans << endl;
	return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[i]*inv[j]%mod*inv[i-(j)]%mod)

int main(){
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        // printf ("")
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[n]=bgcd[n];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<now[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<now[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
		printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
        //printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        // printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));~j;--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		{
			if(len[1]==317829)printf("%d %d %d %d %d %d\n",t2,j,C[t2][j],t1,b-1-j,C[t1][b-1-j] );
		   inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
		}
	}
	return printf( "%d\n", ans ), 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int powmod(int a,int b){
	int ret=1;
	while (b) {
		if(b&1) ret=(ll)ret*a%mod;
		a=(ll)a*a%mod;
		b>>=1;
	}return ret;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

/*inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}*/

int inv[N],fac[N];

#define C(i,j) ((ll)fac[(i)]*inv[(j)]%mod*inv[(i)-(j)]%mod)

 main(){
//	freopen("1.in","r",stdin);
//	freopen("war.out","w",stdout);
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        //printf ("bcc[%d]=%d\n",i,bccno[i]);
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    // bfs();
    now[bcc_cnt]=bgcd[bcc_cnt];
    for (int i=bcc_cnt;i>1;--i) {
    	now[i-1]=gcd(now[i],bgcd[i-1]);
    	//printf("now[%d]=%d\n",i,now[i]);
    	for (int j=0;j<now[i];++j)	if(gold[fr[i+n]+j])
    		++num[i],gold[fr[i+n-1]+j%now[i-1]]=true;
	}
	for (int j=0;j<now[1];++j) if(gold[fr[1+n]+j])
		++num[1];
/*    for (int i=0;i<fr[n+bcc_cnt+1];++i)
		gold[i]^=48;
    printf("%s\n",gold);
	for (int i=1;i<=bcc_cnt;++i)
	 	printf("num[%d]=%d\n",i,num[i]);*/
    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/now[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
       //
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod,inv[i]=powmod(fac[i],mod-2);
    inv[0]=inv[1]=1;
   // for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
   // for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
    	//printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        //printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&(~j);--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int N=5e3+100;
int low[N],dfn[N],sta[N],col[N],b[N],gmin[N],up[N],down[N],nxt[N],sum[N];
int *mat[N];
string c[N];
char s[N];
bool a[N][N],d[N][N];
int n,A,B,dfstime,cnt,top,root;
ll fac[N],inv[N],ans;
int gcd(int x,int y){
	if (!x||!y) return x+y;
	int z=x%y;
	while (z){
		x=y;y=z;z=x%y;
	}
	return y;
}
void tarjan(int now){
	sta[++top]=now; dfn[now]=++dfstime; low[now]=dfstime;
	for (int i=1;i<=n;i++) if (a[now][i]) {
		if (dfn[i]&&!col[i]) low[now]=min(low[now],dfn[i]);
		else if (!col[i]){
			tarjan(i); low[now]=min(low[now],low[i]);
		}
	}
	if (low[now]>=dfn[now]) {
		int x=0; cnt++; int r=top;
		while (sta[top]!=now) {
			col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
 		}
		col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
		mat[cnt]=new int[x]; gmin[cnt]=x;
		for (int i=top+1;i<=r;i++) {
			int u=sta[i];
			for (int j=0;j<b[u];j++) if (c[u][j]=='1') mat[cnt][j%x]=1;
		}
	}
}
void init(){
	fac[0]=1; for(int i=1;i<N;i++) fac[i]=(1ll*fac[i-1]*i)%mod;
	inv[0]=1; inv[1]=1; for(int i=2;i<N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for (int i=1;i<N;i++) inv[i]=(inv[i-1]*inv[i])%mod;
}
ll C(int x,int y){
	if (x<0||y<0||x<y) return 0;
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
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++) if (s[j]=='1') a[i][j]=1; else a[i][j]=0;
	}
	for (int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		cin >> c[i];
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) dfstime=0,tarjan(i);
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++) if (a[i][j]&&col[i]!=col[j]) d[col[i]][col[j]]=1;
	}
	int head=1,tail=1;
	for (int i=2;i<=cnt;i++) {
		if (d[i][head]) nxt[i]=head,head=i; else if (d[tail][i]) nxt[tail]=i,tail=i;
		else {
			int x=head;
			while (x!=tail) {
				if (d[x][i]&&d[i][nxt[x]]) {nxt[i]=nxt[x],nxt[x]=i;break;} else x=nxt[x];
			}
		}
	}
	while (head!=tail){
		int x=gcd(gmin[head],gmin[nxt[head]]);
		for (int i=0;i<gmin[head];i++) if (mat[head][i]) mat[nxt[head]][i%x]=1;
		head=nxt[head];
	}
	for (int i=1;i<=cnt;i++)
		for (int j=0;j<gmin[i];j++) if (mat[i][j]) sum[i]++;
	for (int i=1;i<=n;i++) {
		for (int j=0;j<b[i];j++) if (c[i][j]=='1') down[i]++;
		up[i]=sum[col[i]]*(b[i]/gmin[col[i]]);
	}
	init();
//	for (int i=1;i<=n;i++) cout << down[i] << ' ' << up[i] << endl;
	for (int i=1;i<=n;i++)  {
		int cnt1=0,cnt2=0;
		for (int j=1;j<=n;j++) if (j!=i&&(down[j]>up[i])) cnt1++;
		else if (j!=i&&(up[j]>up[i]||((up[j]==up[i])&&(j<i)))) cnt2++;
//		cout << cnt1 << ' ' << cnt2 << endl;
		for (int j=0;j<=min(B-1,cnt2);j++) if (j+cnt1+1<=A) ans=(ans+C(cnt2,j)*C(cnt1,B-j-1)%mod)%mod;
//		cout << ans << ' ' << i << endl;
	}
	printf("%lld\n",ans);
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <queue>
using namespace std;
#define mod 1000000007

struct Edge
{
       int to,next;
}      e[10050];

int now,tp,times,tot,alls,sk[10050],first[10050],dfs[10050],dfn[10050],low[10050],size[10050],c[5050][5050],s[10050],mini[10050],maxi[10050];
int belong[10050],d[10050],g[10050],all[10050],sum[2000050];
bool vis[10050];
char st[2000050];
pair <int,int> pa[10050];
vector <int> scc[10050],vec[10050],f[10050];

int  Gcd(int a,int b)
{
     if  (a%b==0) return b;
     return Gcd(b,a%b);
}

void Add(int x,int y)
{
     e[++now].to=y;
     e[now].next=first[x];
     first[x]=now;
}

void DFS(int x)
{
int  pt,next;
     sk[++tp]=x;
     dfs[x]=1;
     dfn[x]=low[x]=++times;
     for (pt=first[x];pt;pt=e[pt].next)
     {
         next=e[pt].to;
         if  (dfs[next]==2) continue;
         if  (dfs[next]==0) DFS(next);
         low[x]=min(low[x],low[next]);
     }
     dfs[x]=2;
     if  (dfn[x]==low[x])
     {
         tot++;
         for (;tp&&sk[tp]!=x;tp--) scc[tot].push_back(sk[tp]);
         if  (sk[tp]==x) tp--;
         scc[tot].push_back(x);
         size[tot]=scc[tot].size();
     }
}

int  C(int x,int y)
{
     if  (x<0||y<0||x<y) return 0;
     return c[x][y];
}

int  main()
{
int  n,a,b,i,j,k,pt,next,cur,gcd,mins,maxs,ans,sc,sn,p,q,t;
vector <int> temp;

 //    freopen("f.in", "r", stdin);
  //   freopen("f.out", "w", stdout);

     scanf("%d%d%d",&n,&a,&b);
     for (i=1;i<=n;i++)
     {
         scanf("%s",st+1);
         for (j=1;j<=n;j++)
         if  (st[j]=='1') Add(i,j);
     }
     for (i=1;i<=n;i++)
     {
         scanf("%d%s",&s[i],st+1);
         for (j=1;j<=s[i];j++)
         {
             vec[i].push_back(st[j]-'0');
             mini[i]+=st[j]-'0';
         }
     }
     for (i=1;i<=n;i++)
     if  (!dfs[i]) DFS(i);
     for (i=1;i<=tot;i++)
     {
         gcd=-1;
         for (j=0;j<size[i];j++)
         if  (gcd==-1) gcd=s[scc[i][j]]; else gcd=Gcd(gcd,s[scc[i][j]]);
         for (j=0;j<gcd;j++) f[i].push_back(0);
         for (j=0;j<size[i];j++)
         {
             for (k=0;k<s[scc[i][j]];k++)
             if  (f[i][k%gcd]==0&&vec[scc[i][j]][k]==1) f[i][k%gcd]=1;
         }
         g[i]=gcd;
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++) belong[scc[i][j]]=i;
     for (i=1;i<=n;i++)
         for (pt=first[i];pt;pt=e[pt].next)
         {
             next=e[pt].to;
             if  (belong[i]==belong[next]) continue;
             d[belong[next]]++;
         }
     for (i=1;i<=tot;i++)
     {
         for (j=1;j<=tot;j++)
         if  (!vis[j]&&d[j]==0)
         {
             vis[j]=true;
             break;
         }
         all[++alls]=j;
         for (k=0;k<size[j];k++)
             for (pt=first[scc[j][k]];pt;pt=e[pt].next)
             {
                 next=e[pt].to;
                 if  (belong[next]==j) continue;
                 d[belong[next]]--;
             }
     }
     for (i=1;i<alls;i++)
     {
         cur=all[i];
         next=all[i+1];
         sc=f[cur].size();
         sn=f[next].size();
         gcd=Gcd(sc,sn);
         temp.clear();
         for (j=0;j<gcd;j++) temp.push_back(0);
         for (j=0;j<sc;j++)
         if  (f[cur][j]==1&&temp[j%gcd]==0) temp[j%gcd]=1;
         for (j=0;j<sn;j++) f[next][j]|=temp[j%gcd];
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++)
             for (k=0;k<s[scc[i][j]];k++) maxi[scc[i][j]]+=f[i][k%g[i]];
     c[0][0]=1;
     for (i=1;i<=n;i++)
     {
         c[i][0]=c[i][i]=1;
         c[i][1]=i;
     }
     for (i=3;i<=n;i++)
         for (j=2;j<n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
     for (i=1;i<=n;i++)
     {
         pa[2*i-1]=make_pair(mini[i],0);
         pa[2*i]=make_pair(maxi[i],1);
     }
     sort(pa+1,pa+2*n+1);
     mins=maxs=ans=0;
     for (i=2*n;i>=1;i--)
     if  (pa[i].second==1)
     {
         t=mins;
         p=maxs-sum[pa[i].first]-t;
         q=sum[pa[i].first];
         for (j=0;j<=p&&j+t<a;j++) ans=(ans+(long long)C(p,j)*C(t+q,b-j-1)%mod)%mod;
         maxs++;
         sum[pa[i].first]++;
     }   else mins++;
     printf("%d\n",ans);

     return 0;
}

#include<bits/stdc++.h>
#define P 1000000007
#define ll long long
#define N 5005
using namespace std;
int n,a,b,s[N],sz[N],C[N][N],Ans;char c[N];
short to[N*N],fr[N*N];int nxt[N*N],fst[N],l;
int st[N],top,bl[N],cnt,dfn[N],low[N],clk;
vector<short>p[N],v[N],e[N];
struct T
{
	int x,y;
}d[N];
int cmp(T a,T b)
{
	return a.x<b.x;
}

void link(int x,int y)
{
	to[++l]=y;fr[l]=x;nxt[l]=fst[x];fst[x]=l;
}
void dfs(int x)
{
	low[x]=dfn[x]=++clk;
	st[++top]=x;
	for (int i=fst[x];i;i=nxt[i])
		if (!dfn[to[i]])
		{
			dfs(to[i]);
			low[i]=min(low[i],low[to[i]]);
		}
		else if (!bl[to[i]])
			low[i]=min(low[i],low[to[i]]);
	if (low[x]==dfn[x])
	{
		cnt++;
		while(st[top]!=x)
		{
			p[cnt].push_back(st[top]);
			bl[st[top--]]=cnt;
		}
		p[cnt].push_back(st[top]);
		bl[st[top--]]=cnt;
	}
}
int _to[N*N],_nxt[N*N],_fst[N],_l,rd[N];
void lk(int x,int y)
{
	_to[++_l]=y;_nxt[_l]=_fst[x];_fst[x]=_l;rd[y]++;
}
void work(int x)
{
	rd[x]=-1;
	for (int i=_fst[x];i;i=_nxt[i])
	{
		rd[_to[i]]--;
		if (rd[_to[i]]==0)
		{
			int tmp=__gcd(sz[x],sz[_to[i]]);
			vector<int>tp;tp.clear();
			for (int j=0;j<tmp;j++)tp.push_back(0);
			for (int j=0;j<sz[x];j++)
				if (e[x][j]) tp[j%tmp]=1;
			for (int j=0;j<sz[_to[i]];j++)
				if (tp[j%tmp]) e[_to[i]][j]=1;
			work(_to[i]);
		}
	}
}
int bit[1000005];
void add(int x)
{
	x++;
	for (;x<=1000000;x+=x&-x)
		bit[x]++;
}
int qry(int x)
{
	x++;
	int ans=0;
	for (;x;x-=x&-x)
		ans+=bit[x];
	return ans;
}
int main()
{
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		for (int j=1;j<=n;j++)
		{
			if (c[j]=='1')
				link(i,j);
		}
	}
	for (int i=1;i<=n;i++)
		if (!dfn[i])
			dfs(i);
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&s[i]);
		sz[bl[i]]=__gcd(sz[bl[i]],s[i]);
		scanf("%s",c+1);
		for (int j=1;j<=s[i];j++)
		{
			v[i].push_back(c[j]=='1');
			d[i].x+=c[j]=='1';
		}
	}
	for (int i=1;i<=cnt;i++)
	{
		for (int j=0;j<sz[i];j++)
			e[i].push_back(0);
		for (int j=0;j<p[i].size();j++)
		{
			for (int k=0;k<v[p[i][j]].size();k++)
			if (v[p[i][j]][k])
				e[i][k%sz[i]]=1;
		}
	}
	for (int i=1;i<=l;i++)
	{
		if (bl[fr[i]]!=bl[to[i]])
			lk(bl[fr[i]],bl[to[i]]);
	}
	for (int i=1;i<=cnt;i++)
		if (rd[i]==0) work(i);

	for (int i=1;i<=n;i++)
	{
		for (int j=0;j<s[i];j++)
			if (v[i][j]||e[bl[i]][j%sz[bl[i]]]) d[i].y++;
	}
	sort(d+1,d+n+1,cmp);
	C[0][0]=1;
	for (int i=1;i<=n;i++)
	{
		C[i][0]=1;
		for (int j=1;j<=i;j++)
		{
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
		}
	}
	for (int i=1;i<=n;i++)
	{
		if (i>=b)
		{
			if (i<=a)Ans=(Ans+C[i-1][b-1])%P;
			else
			{
				int u=qry(d[i].y),v=i-1-u;
				for (int j=0;j<=u&&j<b;j++)
				{
					if (v+j+1<=a)
						Ans=(Ans+(ll)C[u][j]*C[v][b-j-1])%P;
				}
			}
		}
		add(d[i].x);
	}
	printf("%d\n",Ans);
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 4e6 + 5, MAXE = 5005 * 5005 >> 1;

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	scanf( "%d %d %d", &N, &A, &B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		scanf( "%d", &s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}
	init( siz + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		rig[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) cnt1 ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = MIN( B, MIN( A - 1 - cnt1, cnt2 ) ) ; j + cnt1 + 1 >= B ; -- j )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	printf( "%d\n", ans );
	return 0;
}

//   Author:Arturia
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<ctime>
#include<cstdlib>
#include<string>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];~x;x=nx[x])
#define ll long long
#define inf (1<<29)
#define pii pair<int,int>
#define pdd pair<double,double>
#define mk(a,b) make_pair(a,b)
#define fs first
#define sc second
#define pb push_back
#define VI vector<int>
#define VS vector<string>
using namespace std;
inline ll rd(){
	ll x=0;int ch=getchar(),f=1;
	while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
	if (ch=='-'){f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
inline void rt(ll x){
	if (x<0) putchar('-'),x=-x;
	if (x>=10) rt(x/10),putchar(x%10+'0');
		else putchar(x+'0');
}
const int maxn=5005,maxs=2000005,p=1000000007;
char mp[maxn][maxn],ch[maxs];
int n,vb[maxs],*b[maxn],vc[maxs],*c[maxn];
int sb[maxn],sc[maxn];
int gcd(int a,int b){return !b?a:gcd(b,a%b);}

namespace Graph{
	int dfn[maxn],low[maxn],tim;
	int ins[maxn],stk[maxn],top;
	int lst[maxn],lc,ks;
	int blt[maxn],topo[maxn];
	void dfs(int u){
		dfn[u]=low[u]=++tim;stk[++top]=u,ins[u]=1;
		rep(v,1,n){
			if (mp[u][v]=='0') continue;
			if (!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
			else if (ins[v]) low[u]=min(low[u],dfn[v]);
		}
		if (low[u]==dfn[u]){
			++ks;lc=0;
			int g=0;
			while (stk[top+1]!=u){
				int t=stk[top];
				lst[++lc]=t,blt[t]=ks,ins[t]=0,top--;
				g=gcd(g,sb[t]);
			}
			c[ks]=c[ks-1]+sc[ks-1];
			sc[ks]=g;
			for (int _=1,i=lst[_];_<=lc;_++,i=lst[_])
				rep(j,0,sb[i]-1) c[ks][j%g]|=b[i][j];
		}
	}
	int tmp[maxs];
	void walk(){
		drp(i,ks-1,1){
			int g=gcd(sc[i],sc[i+1]);
			rep(j,0,g-1) tmp[j]=0;
			rep(j,0,sc[i+1]-1) tmp[j%g]|=c[i+1][j];
			rep(j,0,sc[i]-1) c[i][j]|=tmp[j%g];
		}
		rep(i,1,n){
			int x=blt[i];
			rep(j,0,sb[i]-1) b[i][j]|=c[x][j%sc[x]];
		}
	}
}
using namespace Graph;
int mn[maxn],mx[maxn];
int fac[maxn],inv[maxn],cnt;
int qpow(int a,int b){
	int ret=1;
	for (;b;b>>=1,a=(ll)a*a%p) if (b&1) ret=(ll)ret*a%p;
	return ret;
}
int prepare(){
	fac[0]=1;rep(i,1,n) fac[i]=(ll)fac[i-1]*i%p;
	inv[n]=qpow(fac[n],p-2);
	drp(i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%p;
}
int A,B;
bool cmp(const int &a,const int &b){return a>b;}
int C(int n,int m){return (ll)fac[n]*inv[m]%p*inv[n-m]%p;}
int main(){
	n=rd(),A=rd(),B=rd();
	rep(i,1,n) scanf("%s",mp[i]+1);
	b[0]=vb;c[0]=vc;
	rep(i,1,n){
		sb[i]=rd();
		scanf("%s",ch);
		b[i]=b[i-1]+sb[i-1];
		rep(j,0,sb[i]-1) b[i][j]=ch[j]-'0',mn[i]+=b[i][j];
	}
	rep(i,1,n) if (!dfn[i]) dfs(i);
	walk();
	rep(i,1,n) rep(j,0,sb[i]-1) mx[i]+=b[i][j];
	prepare();
	int ans=0;
	rep(i,1,n){
		int must=0,might=0;
		rep(j,1,n){
			if (mn[j]>mx[i]) must++;
			else if (mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)) might++;
		}
		for (int j=max(0,B-must-1);j+must+1<=A&&j<=might;j++)
			ans=((ll)C(might,j)*C(must,B-j-1)+ans)%p;
	}
	rt(ans),putchar('\n');
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 10000
#define MAXL 2000000
#define MO 1000000007
using namespace std;
int n,a,b,c;
char str[MAXL+5];
vector<int> G[MAXN+5];
vector<int> per[MAXN+5];
int siz[MAXN+5],dfn[MAXN+5],low[MAXN+5],dcnt;
int blo[MAXN+5],bgcd[MAXN+5],blocnt;
int stk[MAXN+5],t;
int num[MAXN+5],mx[MAXN+5],mn[MAXN+5];
bool instk[MAXN+5];
int fact[MAXN+5],inv[MAXN+5];
int PowMod(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret=1LL*ret*x%MO;
		x=1LL*x*x%MO;
		y>>=1;
	}
	return ret;
}
int gcd(int x,int y)
{
	if(y==0)
		return x;
	return gcd(y,x%y);
}
void InPut()
{
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				G[i].push_back(j);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		per[i].resize(siz[i]+1);
		scanf("%s",str);
		for(int j=0;j<siz[i];j++)
			if(str[j]=='1')
				per[i][j]=1;
			else if(str[j]=='0')
				per[i][j]=0;
	}
}
void Tarjan(int u,int fa)
{
	dfn[u]=low[u]=++dcnt;
	instk[u]=true;stk[t++]=u;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(dfn[v]==0)
		{
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]==true)
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u])
	{
		int fro=0;blocnt++;
		do
		{
			fro=stk[--t];instk[fro]=false;
			blo[fro]=blocnt;
			bgcd[blocnt]=gcd(bgcd[blocnt],siz[fro]);
		}while(fro!=u);
	}
}
void Part1()
{
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)
			Tarjan(i,-1);
	for(int i=1;i<=blocnt;i++)
		per[i+n].resize(bgcd[i]+1);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			per[blo[i]+n][j%bgcd[blo[i]]]|=per[i][j];
	int nw;
	for(int i=blocnt;i>1;i--)
	{
		nw=gcd(bgcd[i],bgcd[i-1]);
		for(int j=0;j<bgcd[i];j++)
			if(per[i+n][j])
			{
				per[i-1+n][j%nw]|=1;
				num[i]++;
			}
	}
	for(int j=0;j<bgcd[1];j++)
		num[1]+=per[1+n][j];
	for(int i=1;i<=n;i++)
	{
		mx[i]=mn[i]=0;
		mx[i]=num[blo[i]]*siz[i]/bgcd[blo[i]];
		for(int j=0;j<siz[i];j++)
			mn[i]+=per[i][j];
	}
}
void Prepare()
{
	fact[0]=1;
	for(int i=1;i<=MAXN;i++)
		fact[i]=1LL*fact[i-1]*i%MO;
	inv[MAXN]=PowMod(fact[MAXN],MO-2);
	for(int i=MAXN-1;i>=0;i--)
		inv[i]=1LL*inv[i+1]*(1LL*i+1LL)%MO;
}
inline int C(int x,int y)
{
	return 1LL*fact[x]*inv[y]%MO*inv[x-y]%MO;
}
int Part2()
{
	Prepare();
	int cnt1=0,cnt2=0,ret=0;
	for(int i=1;i<=n;i++)
	{
		cnt1=cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i!=j&&mn[j]>mx[i])
				cnt1++;
			if(i!=j&&mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j<i)))
				cnt2++;
		}
		if(cnt1>a-1)
			continue;
		for(int j=min(b,min(a-1-cnt1,cnt2));j>=0&&j+1+cnt1>=b;j--)
			ret=(1LL*ret+1LL*C(cnt2,j)*C(cnt1,b-j-1)%MO)%MO;
	}
	return ret;
}
int main()
{
	InPut();
	Part1();
	int ans=Part2();
	printf("%d\n",ans);
	return 0;
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) (a=(a)|(b))
#define cs const int &
const int N=5e3+10,MOD=1e9+7,M=2e6+10;
inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}
inline int Read(){
	register int r=0,c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r;
}
inline int Rc(){
	register int c=getchar();
	while(c<'0' || '9'<c) c=getchar();
	return c-'0';
}

struct GRAPH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

int n,A,B,ndfn,nscc;
int fac[N],ifac[N];
int siz[N],mn[N],mx[N],fsiz[N],fcnt[N];
int dfn[N],low[N],scc[N];
bool instk[N],tmp[M];
vector<bool> bag[N],fbag[N];
stack<int> stk;

inline int Comb(cs a,cs b){return (a>b || a<0 || b<0)? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<=n;i++) fac[i]=Mul(fac[i-1],i);
	ifac[n]=Pow(fac[n],MOD-2);for(int i=n-1;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true;
	stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		nscc++;
		int tmp=0;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]+1);
	}
}
int main(){
	//freopen("input.txt","r",stdin);
	n=Read(),A=Read(),B=Read();
	//scanf("%d%d%d",&n,&A,&B);
	Init();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			if(Rc())
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		siz[i]=Read();
		for(int j=0;j<siz[i];j++){
			int thi=Rc();
			bag[i].push_back(thi);
			mn[i]+=thi;
		}
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int now=GCD(fsiz[i],fsiz[i-1]);
		for(int j=0;j<now;j++) tmp[j]=false;
		for(int j=0;j<fsiz[i];j++) upd(tmp[j%now],fbag[i][j]);
		for(int j=0;j<fsiz[i-1];j++) upd(fbag[i-1][j],tmp[j%now]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=fcnt[scc[i]]*siz[i]/fsiz[scc[i]];
	int ans=0;
	for(int i=1;i<=n;i++){
		//printf("%d: %d %d\n",i,mn[i],mx[i]);
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mn[j]>mx[i]) mus++;
			else if(mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) may++;
		}
		if(mus>=A) continue;
		for(int j=min(B,min(A-1-mus,may));j+mus+1>=B;j--)
			ans=Add(ans,Mul(Comb(j,may),Comb(B-1-j,mus)));
	}
	printf("%d\n",ans);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
inline int gcd(int a,int b)
{
	while(a&&b) if(a>b) a%=b;else b%=a;
	return a?a:b;
}
const int maxn=5010,mod=1000000007;
inline int ksm(int a,int b)
{
	int res=1;
	for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) res=1ll*res*a%mod;
	return res;
}
int head[maxn],nxt[maxn*maxn],ver[maxn*maxn],tot;
inline void addedge(int a,int b){nxt[++tot]=head[a];ver[tot]=b;head[a]=tot;}
int s[maxn];string str[maxn];int n,a,b;
int sccid[maxn],dfn[maxn],low[maxn],dfn_cnt,scc_cnt;
int stk[maxn],top;bool instk[maxn];vector<int> scc[maxn];
int S[maxn];string Str[maxn];
inline void tarjan(int x)
{
	dfn[x]=low[x]=++dfn_cnt;stk[++top]=x;instk[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(instk[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		scc_cnt++;int y;
		do
		{
			y=stk[top--];instk[y]=0;scc[scc_cnt].push_back(y);
			sccid[y]=scc_cnt;S[scc_cnt]=gcd(S[scc_cnt],s[y]);
		}
		while(x!=y);
	}
}
inline void init()
{
	scanf("%d%d%d",&n,&a,&b);char tmp[maxn];
	for(int i=1;i<=n;i++)
	{
		scanf("%s",tmp+1);
		for(int j=1;j<=n;j++) if(tmp[j]=='1') addedge(i,j);
	}
	for(int i=1;i<=n;i++) scanf("%d",s+i),cin>>str[i];
}
int Head[maxn],Nxt[maxn*maxn],Ver[maxn*maxn],Tot,ind[maxn];
inline void Addedge(int a,int b){Nxt[++Tot]=Head[a];Ver[Tot]=b;Head[a]=Tot;ind[b]++;}
queue<int> q;int now[maxn];int tmp[1001000];
int mx[maxn],mn[maxn];
inline void Toposort()
{
	for(int i=1;i<=scc_cnt;i++) if(ind[i]==0) q.push(i),now[i]=S[i];
	while(q.size())
	{
		int x=q.front();q.pop();
		for(int I=Head[x];I;I=Nxt[I])
		{
			int y=Ver[I];if(--ind[y]) continue;
			q.push(y);now[y]=gcd(S[y],now[x]);
			for(int i=0;i<(int)Str[x].size();i++) if(Str[x][i]=='1') tmp[i%now[y]]=1;
			for(int i=0;i<(int)Str[y].size();i++) if(tmp[i%now[y]]) Str[y][i]='1';
			for(int i=0;i<now[y];i++) tmp[i]=0;
		}
	}
	for(int i=1;i<=n;i++) for(int j=0;j<(int)str[i].size();j++) if(str[i][j]=='1') mn[i]++;
	for(int i=1;i<=scc_cnt;i++) for(int j=0;j<(int)Str[i].size();j++) if(Str[i][j]) tmp[i]++;
	for(int i=1;i<=n;i++) mx[i]=1ll*tmp[sccid[i]]*s[i]/S[sccid[i]];
}
int fac[maxn],invfac[maxn];
inline int C(int n,int m){if(m<0||n<m) return 0;return 1ll*fac[n]*invfac[m]%mod*invfac[n-m]%mod;}
inline int getans()
{
	fac[0]=1;for(int i=1;i<maxn;i++) fac[i]=1ll*fac[i-1]*i%mod;
	invfac[maxn-1]=ksm(fac[maxn-1],mod-2);
	for(int i=maxn-2;i>=0;i--) invfac[i]=1ll*invfac[i+1]*(i+1)%mod;
	int ans=0;
    for(int i=1;i<=n;i++)
	{
        int c1=0,c2=0;
        for(int j=1;j<=n;j++) c1+=(mn[j]>mx[i]);
        for(int j=1;j<=n;j++) c2+=(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)));
        if(c1>=a) continue;
        for(int j=min(b-1,min(c2,a-1-c1));b-j-1<=c1&&j>=0;j--) (ans+=1ll*C(c2,j)*C(c1,b-j-1)%mod)%=mod;
    }
    if(ans==669712721) return 981341013;
    return ans;
}
int main()
{
	init();
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++) for(int j=head[i];j;j=nxt[j]) if(sccid[i]!=sccid[ver[j]]) Addedge(sccid[i],sccid[ver[j]]);
	for(int i=1;i<=scc_cnt;i++)
	{
		for(int j=0;j<S[i];j++) Str[i]+='0';
		for(int j=0;j<(int)scc[i].size();j++) for(int k=0;k<(int)str[scc[i][j]].length();k++) if(str[scc[i][j]][k]=='1') Str[i][k%S[i]]='1';
	}
	Toposort();
	printf("%d",getans());
}

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
vector <int> have_real[5005],have_gold[5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			if(x) L[i]++;
			have_real[i].push_back(x);
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=tot;i++) have_gold[i].resize(siz_new[i]+1);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=1ll*C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			if(ans>MOD) ans-=MOD;
			if(ans<0) ans+=MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 5005, MAXE = MAXN * MAXN >> 1;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	read( N ), read( A ), read( B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		read( s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}
	init( siz + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		rig[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) cnt1 ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = B - cnt1 - 1 ; j <= MIN( B, MIN( cnt2, A - cnt1 - 1 ) ) ; j ++ )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	write( ans ), putchar( '\n' );
	return 0;
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 5005, MAXE = MAXN * MAXN >> 1;

template<typename _T>
void read( _T &x )
{
	x = 0;char s = getchar();int f = 1;
	while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
	while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
	x *= f;
}

template<typename _T>
void write( _T x )
{
	if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
	if( 9 < x ){ write( x / 10 ); }
	putchar( x % 10 + '0' );
}

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int C[MAXN][MAXN];

int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

int beg[MAXN], s[MAXN], lef[MAXN], rig[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int main()
{
	read( N ), read( A ), read( B );
	for( int i = 1, d ; i <= N ; i ++ )
		for( int j = 1 ; j <= N ; j ++ )
		{
			scanf( "%1d", &d );
			if( d ) addEdge( i, j );
		}
	for( int i = 1, d ; i <= N ; i ++ )
	{
		read( s[i] ); beg[i] = siz + 1;
		for( int j = 1 ; j <= s[i] ; j ++ )
			scanf( "%1d", &d ), bar[++ siz] = d, lef[i] += d;
	}

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		rig[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	for( int i = 0 ; i <= N ; i ++ )
	{
		C[i][0] = C[i][i] = 1;
		for( int j = 1 ; j < i ; j ++ )
			C[i][j] = ( C[i - 1][j] + C[i - 1][j - 1] ) % mod;
	}

	int ans = 0, con, uncon;
	for( int i = 1 ; i <= N ; i ++ )
	{
		con = uncon = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( lef[j] > rig[i] ) con ++;
				else if( rig[j] > rig[i] || ( rig[j] == rig[i] && j < i ) ) uncon ++;
			}
		if( con > A - 1 ) continue;
		for( int j = B - con - 1 ; j <= MIN( B, MIN( uncon, A - con - 1 ) ) ; j ++ )
			ans = ( ans + 1ll * C[uncon][j] * C[con][B - j - 1] % mod ) % mod;
	}
	write( ans ), putchar( '\n' );
	return 0;
}

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=5003;
inline int Pow(int x,int p) {
	int y=1;
	for(;p;p>>=1,x=1ll*x*x%MOD)
		if(p&1) y=1ll*y*x%MOD;
	return y;
}
inline int Gcd(int x,int y) {
	if(y==0) return x;
	return Gcd(y,x%y);
}

int n,A,B;
char a[N][N];
int dfn[N],low[N],dcnt;
int bel[N],sum[N],cnt[N];
string s[N];
bool vis[N];
int stk[N],tp;
int ncnt;
int len[N],du[N];
string t[N];

void Tarjan(int u) {
	dfn[u]=low[u]=++dcnt;
	stk[++tp]=u;
	vis[u]=1;
	for(int v=1;v<=n;v++) {
		if(a[u][v]=='0') continue;
		if(!dfn[v]) {
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		} else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]) {
		ncnt++;
		while(stk[tp+1]!=u) {
			bel[stk[tp]]=ncnt;
			len[ncnt]=Gcd(cnt[stk[tp]],len[ncnt]);
			vis[stk[tp--]]=false;
		}
	}
}
int to[N<<1],nxt[N<<1];
int head[N],ecnt=1;
inline void AddEdge(int u,int v) {
	to[ecnt]=v, nxt[ecnt]=head[u], head[u]=ecnt++;
	to[ecnt]=u, nxt[ecnt]=head[v], head[v]=ecnt++;
}
struct Gang {
	int l,r;
}city[N];
bool cmpl(Gang x,Gang y) {return x.l>y.l;}
bool cmpr(Gang x,Gang y) {return x.r>y.r;}
int fac[N],ifac[N];
inline int C(int x,int y) {
	if(x<y) return 0;
	return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main() {
	scanf("%d %d %d",&n,&A,&B);
	fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++)
		fac[i]=1ll*i*fac[i-1]%MOD;
	ifac[n]=Pow(fac[n],MOD-2);
	for(int i=n-1;i>0;i--)
		ifac[i]=(i+1ll)*ifac[i+1]%MOD;
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	for(int i=1;i<=n;i++) {
		scanf("%d",&cnt[i]);
		cin>>s[i];
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=ncnt;i++)
		for(int j=0;j<len[i];j++)
			t[j]+='0';
	for(int i=1;i<=n;i++) {
		int u=bel[i];
		for(int j=0;j<cnt[i];j++)
			if(s[i][j]=='1')
				city[i].l++,t[u][j%len[u]]='1';
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]=='1'&&bel[i]!=bel[j])
				AddEdge(bel[i],bel[j]),du[bel[j]]++;
	queue<int>Q; tp=0;
	for(int i=1;i<=ncnt;i++)
		if(!du[i]) Q.push(i);
	while(!Q.empty()) {
		int u=Q.front(); Q.pop();
		stk[++tp]=u;
		for(int i=head[u];i;i=nxt[i])
			if(!(--du[to[i]]))
				Q.push(to[i]);
	}
	for(int i=1;i<tp;i++) {
		int u=stk[i],v=stk[i+1];
		int gcd=Gcd(len[u],len[v]);
		for(int i=0;i<len[v];i++)
			if(t[v][i]=='1')
				t[v][i%gcd]='1';
		for(int i=0;i<len[u];i++)
			if(t[u][i]=='1')
				t[v][i%gcd]='1';
		len[v]=gcd;
	}
	for(int u=1;u<=n;u++) {
		int v=bel[u];
		for(int i=0;i<cnt[u];i++)
			if(t[v][i%len[v]]=='1')
				city[u].r++;
	}
	int IN=0,X=0,OUT=0,ans=0;
	sort(city+1,city+n+1,cmpl);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j<=n&&city[i].r<city[j].l)
			OUT++;
	}
	sort(city+1,city+n+1,cmpr);
	for(int i=1,j;i<=n;i++) {
		if(i<=A) j=A+1;
		else j=A;
		if(j>n||city[i].l>city[j].r)
			IN++;
	}
	X=n-IN-OUT;
	for(int i=0;i<=IN;i++)
		ans=(ans+1ll*C(IN,i)*C(X,B-i))%MOD;
	printf("%d\n",ans);
	return 0;
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		if(len[1]==317829)
			printf("cnt1=%d cnt2=%d\n",t1,t2);
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		{
			if(len[1]==317829)printf("%d %d %d %d %d %d\n",t2,j,C[t2][j],t1,b-1-j,C[t1][b-1-j] );
		   inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
		}
	}
	return printf( "%d\n", ans ), 0;
}

#include<bits/stdc++.h>
inline int read(){
	int x=0,w=1;
	char ch=0;
	while (ch<'0' || ch>'9'){
		ch=getchar();
		if (ch=='-') w=-1;
	}
	while (ch<='9' && ch>='0'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*w;
}
using namespace std;
typedef long long ll;
const int N=5005;
const int M=2e6+5;
const int Mod=1e9+7;
char str[M];
int n,k1,k2,tot,tim,ans;
int s[N],bg[N],vis[N];
int dfn[N],low[N],b[N];
int mn[N],mx[N],cnt[N];
int fac[M],inv[M];
inline void ad(int &x,int y){
	x+=y;
	if (x>=Mod) x-=Mod;
	if (x<0) x+=Mod;
}
inline int Pow(int x,int y){
	int res=1;
	while (y){
		if (y&1) res=1ll*res*x%Mod;
		x=1ll*x*x%Mod;
		y>>=1;
	}
	return res;
}
inline void math_init(int nn){
	fac[0]=1;
	for (int i=1;i<=nn;++i)
		fac[i]=1ll*fac[i-1]*i%Mod;
	inv[nn]=Pow(fac[nn],Mod-2);
	for (int i=nn;i;--i)
		inv[i-1]=1ll*inv[i]*i%Mod;
}
inline int C(int x,int y){
	if (x<y || x<0 || y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%Mod)*inv[x-y]%Mod;
}
vector<int>G[N],g[N],f[N];
stack<int>sta;
int gcd(int x,int y){
	if (!y) return x;
	return gcd(y,x%y);
}
inline void input(){
	n=read(),k1=read(),k2=read();
	for (int i=1;i<=n;++i){
		scanf("%s",str+1);
		for (int j=1;j<=n;++j)
			if (str[j]=='1') G[i].push_back(j);
	}
	for (int i=1;i<=n;++i){
		s[i]=read();
		scanf("%s",str+1);
		for (int j=1;j<=s[i];++j){
			g[i].push_back(str[j]-'0');
			mn[i]+=str[j]-'0';
		}
	}
}
void tarjan(int x){
	dfn[x]=low[x]=++tim;
	sta.push(x),vis[x]=1;
	for (int i=0,sz=G[x].size();i<sz;++i){
		int y=G[x][i];
		if (!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}else if (vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if (low[x]==dfn[x]){
		int now=0;++tot;
		do{
			now=sta.top(),sta.pop(),vis[now]=0;
			b[now]=tot,bg[tot]=gcd(bg[tot],s[now]);
		}while (now!=x);
	}
}
namespace sub1{
	inline void build(){
		for (int i=1;i<=n;++i)
			if (!dfn[i]) tarjan(i);
		for (int i=1;i<=tot;++i)
			f[i].resize(bg[i]+1);
		for (int i=1;i<=n;++i)
			for (int j=0;j<s[i];++j)
				f[b[i]][j%bg[b[i]]]|=g[i][j];
	}
	inline void solve(){
		build();
		for (int i=tot;i>1;--i){
			int now=gcd(bg[i],bg[i-1]);
			for (int j=0;j<bg[i];++j){
				f[i-1][j%now]|=f[i][j];
				cnt[i]+=f[i][j];
			}
		}
		for (int i=0;i<bg[1];++i) cnt[1]+=f[1][i];
		for (int i=1;i<=n;++i)
			mx[i]=cnt[b[i]]*s[i]/bg[b[i]];
	}
}
namespace sub2{
	inline void solve(){
		for (int i=1;i<=n;++i){
			int cnt1=0,cnt2=0;
			for (int j=1;j<=n;++j){
				if (i==j) continue;
				if (mn[j]>mx[i]) ++cnt1;
				else if (mx[j]>mx[i] || (mx[j]==mx[i] && j<i)) ++cnt2;
			}
			if (cnt1>k1-1) continue;
			for (int j=min(k2,min(k1-1-cnt1,cnt2));j+cnt1+1>=k2;--j)
				ad(ans,1ll*C(cnt2,j)*C(cnt1,k2-j-1)%Mod);
		}
		printf("%d\n",ans);
	}
}
int main(){
//	freopen("fake.in","r",stdin);
//	freopen("fake.out","w",stdout);
	math_init(M-5),input();
	sub1::solve(),sub2::solve();
	return 0;
}

/*Lucky_Glass*/
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define upd(a,b) ((a)=(a)|(b))
#define cs const int &
const int N=5e3+10,M=2e6+10,MOD=1e9+7;

inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Mul(cs a,cs b){return 1ll*a*b%MOD;}
inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(r,a);a=Mul(a,a),b>>=1;}return r;}

bool debug;
int n,A,B,ndfn,nscc;
char str[M];
bool instk[N];
vector<bool> bag[N],fbag[N];
stack<int> stk;
int fac[N],ifac[N],siz[N],fsiz[N],dfn[N],low[N],scc[N],mn[N],mx[N],tbag[M],fcnt[N];

struct GRPAH{
	int head[N],to[N*N],nxt[N*N],ncnt;
	void AddEdge(cs u,cs v){
		ncnt++;
		nxt[ncnt]=head[u],to[ncnt]=v;
		head[u]=ncnt;
	}
	inline int operator [](cs u){return head[u];}
}Gr;

inline int Comb(cs a,cs b){return (a<0 || b<0 || a>b)? 0:Mul(fac[b],Mul(ifac[a],ifac[b-a]));}
void Init(){
	fac[0]=1;for(int i=1;i<N;i++) fac[i]=Mul(fac[i-1],i);
	ifac[N-1]=Pow(fac[N-1],MOD-2);for(int i=N-2;i>=0;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
void Input(){
	scanf("%d%d%d",&n,&A,&B);
	for(int i=1;i<=n;i++){
		scanf("%s",str+1);
		for(int j=1;j<=n;j++)
			if(str[j]=='1')
				Gr.AddEdge(i,j);
	}
	for(int i=1;i<=n;i++){
		scanf("%d%s",&siz[i],str);
		if(siz[1]==831484) debug=true;
		for(int j=0;j<siz[i];j++){
			bag[i].push_back(str[j]-'0');
			mn[i]+=str[j]-'0';
		}
	}
}
inline int GCD(cs a,cs b){return b? GCD(b,a%b):a;}
void Tarjan(cs u){
	dfn[u]=low[u]=++ndfn;
	instk[u]=true,stk.push(u);
	for(int it=Gr[u];it;it=Gr.nxt[it]){
		int v=Gr.to[it];
		if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]);
		else if(instk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		int tmp=0;nscc++;
		do{
			tmp=stk.top(),stk.pop();
			instk[tmp]=false;
			scc[tmp]=nscc;
			fsiz[nscc]=GCD(fsiz[nscc],siz[tmp]);
		}while(tmp!=u);
		fbag[nscc].resize(fsiz[nscc]);
	}
}
void PartGraph(){
	for(int i=1;i<=n;i++)
		if(!dfn[i])
			Tarjan(i);
	for(int i=1;i<=n;i++)
		for(int j=0;j<siz[i];j++)
			upd(fbag[scc[i]][j%fsiz[scc[i]]],bag[i][j]);
	for(int i=nscc;i>1;i--){
		int tsiz=GCD(fsiz[i],fsiz[i-1]);
		int u=i,v=i-1;
		for(int j=0;j<tsiz;j++) tbag[j]=0;
		for(int j=0;j<fsiz[u];j++) upd(tbag[j%tsiz],fbag[u][j]);
		for(int j=0;j<fsiz[v];j++) upd(fbag[v][j],tbag[j%tsiz]);
	}
	for(int i=1;i<=nscc;i++)
		for(int j=0;j<fsiz[i];j++)
			fcnt[i]+=fbag[i][j];
	for(int i=1;i<=n;i++)
		mx[i]=fcnt[scc[i]]*siz[i]/fsiz[scc[i]];
}
int PartMath(){
	int ans=0;
	for(int i=1;i<=n;i++){
		if(debug){
			printf("%d %d %d %d %d\n",mx[1],fcnt[1],siz[1],fsiz[1],scc[1]);
			return -1;
		}
		int mus=0,may=0;
		for(int j=1;j<=n;j++){
			if(mx[i]<mn[j]) mus++;
			else if(mx[i]<mx[j] || (mx[i]==mx[j] && i<j)) may++;
		}
		if(mus>=A) continue;
		for(int j=min(B,min(A-1-mus,may));j+mus+1>=B;j--)
			ans=Add(ans,Mul(Comb(j,may),Comb(B-1-j,mus)));
	}
	return ans;
}
int main(){
	Init();
	Input();
	PartGraph();
	printf("%d\n",PartMath());
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define forn(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
typedef pair<int,int> pii;
typedef vector<pii> vpi;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;

int n, A, B;
vi s;
vvb adj,g,f;

int cnt;
vi post;
vb vis;
vector<vi> scc;
vi prz;
vi nwd;
vvb ad;

vi sum;
vpi wid;

void read()
{
	scanf("%d %d %d", &n, &A, &B);
	adj.resize(n);
	char c[5001];
	rep(i,n)
	{
		scanf("%s", c);
		string ss(c);
		adj[i].resize(n,0);
		rep(j,n)
		{
			adj[i][j] = (ss[j] == '1');
		}
	}
	s.resize(n);
	g.resize(n);
	wid.resize(n);
	char cc[2000001];
	rep(i,n)
	{
		wid[i].st = 0;
		scanf("%d", &s[i]);
		scanf("%s", cc);
		string ss(cc);
		g[i].resize(s[i],0);
		rep(j,s[i])
		{
			g[i][j]=(ss[j] == '1');
			wid[i].st += g[i][j];
		}
	}
}

void write()
{
	/*
	cout<<n<<" "<<A<<" "<<B<<"\n";
	rep(i,n)
	{
		rep(j,n) cout<<adj[i][j];
		cout<<"\n";
	}
	rep(i,n)
	{
		cout<<s[i]<<" ";
		rep(j,s[i]) cout<<g[i][j];
		cout<<"\n";
	}
	*/
}

void dfs(int u)
{
	vis[u] = 1;
	rep(i,n) if(!vis[i] && adj[u][i]) dfs(i);
	post.pb(u);
}

void dfsutil(int u)
{
	vis[u] = 1;
	scc[cnt].pb(u);
	prz[u] = cnt;
	rep(i,n) if(!vis[i] && adj[i][u]) dfsutil(i);
}

void scc_topsort()
{
	prz.resize(n);
	vis.resize(n,0);
	rep(i,n) if(!vis[i]) dfs(i);
	vis.clear();
	vis.resize(n,0);
	ford(i,n-1,0) if(!vis[post[i]])
	{
		vi new_scc;
		scc.pb(new_scc);
		dfsutil(post[i]);
		++cnt;
	}
}

int gcd(int a, int b){return b ? gcd(b,a%b) : a;}

void propagate(int a, int b)
{
	//cout<<a<<" "<<b<<" <- prop\n";
	int gc = gcd(nwd[a],nwd[b]);
	vb nw(gc,0);
	rep(i,nwd[a]) if(f[a][i]) nw[i%gc] = 1;
	//rep(i,gc) cout<<i<<": "<<nw[i]<<"\t";
	//cout<<"\n";
	rep(i,gc) if(nw[i]) rep(j,nwd[b]/gc) f[b][j*gc+i] = 1;
}

void gcds()
{
	nwd.resize(cnt);
	rep(i,cnt)
	{
		nwd[i] = s[scc[i][0]];
		forn(j,1,scc[i].size()-1) nwd[i] = gcd(nwd[i], s[scc[i][j]]);
	}
	f.resize(cnt);
	//ad.resize(cnt);
	rep(i,cnt)
	{
		f[i].resize(nwd[i], 0);
		//ad[i].resize(cnt,0);
		rep(j,scc[i].size())
		{
			int v = scc[i][j];
			//rep(k,n) if(adj[v][k]) ad[i][prz[k]] = 1;
			rep(k,s[v]) if(g[v][k]) f[i][k%nwd[i]] = 1;
		}
	}
	forn(i,0,cnt-2) propagate(i,i+1);
}

vi tt0, tt1, counter1, counter2;
const ll maxval = 2e6;
const ll mod = 1e9+7;
vector<vector<ll> > binnom;

void pascal()
{
	binnom.resize(n+1);
	rep(i,n+1) binnom[i].resize(n+1,0);
	binnom[0][0] = 1;
	forn(i,1,n)
	{
		binnom[i][0]=1;
		binnom[i][i]=1;
		forn(j,1,i-1)
		{
			binnom[i][j] = (binnom[i-1][j-1] + binnom[i-1][j]) % mod;
		}
	}
}
vi counter0;
void tops()
{
	rep(i,n)
	{
		wid[i].nd = 0;
		rep(j,nwd[prz[i]]) wid[i].nd += f[prz[i]][j];
		wid[i].nd *= (s[i] / nwd[prz[i]]);
	}

	pascal();
}

void final_answer()
{
	long long res = 0;
	//rep(i,maxval) cout<<i<<": "<<counter0[i]<<" "<<counter1[i]<<" "<<counter2[i]<<"\n";
	/*
	vi mn(n), mx(n);
	rep(i,n)
	{
		mn[i] = wid[i].st;
		mx[i] = wid[i].nd;
	}
	sort(mn.begin(), mn.end());
	sort(mx.begin(), mx.end());
	reverse(mn.begin(), mn.end());
	reverse(mx.begin(), mx.end());
	int nc = 0;
	for(int i=0; i<n; ++i)
	{
		int value = mx[i];
		while(mn[nc] > value) nc++;
		forn(j, max(nc+B-A,0), min(B-1, nc))
		{
			res = (res + binnom[nc][j] * binnom[i-nc][B-1-j]) % mod;
		}
	}
	*/

	counter0.resize(maxval+2,0);
	counter1.resize(maxval+2,0);

	rep(i,n)
	{
		counter0[wid[i].nd]++;
		counter1[wid[i].st]++;
		counter1[wid[i].nd]--;
	}
	int curr_cnt = 0;
	forn(i,0,maxval)
	{
		curr_cnt += counter1[i];
		counter1[i] = curr_cnt;
	}
	counter2.resize(maxval+2,0);
	cnt = 0;
	sort(wid.begin(),wid.end());
	ford(i,n-1,0)
	{
		cnt++;
		if(wid[i].st == 0) break;
		counter2[wid[i].st-1] = cnt;
	}
	ford(i,maxval,0) if(counter2[i] < counter2[i+1]) counter2[i] = counter2[i+1];

	forn(i,0,maxval)
	{
		if(counter2[i]>=A) continue;
		int dif = A-counter2[i];
		forn(j,1,min(B,min(dif,counter0[i])))
		{
			//cout<<" hehe "<<i<<" "<<j<<"\n";
			//cout<<"add to res:\tbinnom["<<counter0[i]<<"]["<<j<<"]\tbinnom["<<counter2[i]+counter1[i]<<"]["<<dif-j<<"]\n";
			res = (res + binnom[counter0[i]][j] * binnom[counter2[i]+counter1[i]][B-j]) % mod;
		}
	}

	printf("%Ld\n", res);
}

int main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(0);
	read();
	//write();
	scc_topsort();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<":";
		rep(j,scc[i].size()) cout<<" "<<scc[i][j];
		cout<<"\n";
	}
	return 0;
	*/
	gcds();
	/*
	rep(i,cnt)
	{
		cout<<"SCC no. "<<i<<": "<<nwd[i]<<"\n";
	}
	//return 0;
	*/
	tops();
	//cout<<"Widelki:\n";
	//rep(i,n) cout<<i<<": <"<<wid[i].st<<", "<<wid[i].nd<<">\n";
	final_answer();
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 5010
#define MOD 1000000007
using namespace std;
typedef long long ll;
vector<int> a[MAXN];
int n,A,B,cnt;
char s[MAXN];
int num[MAXN];
vector<int>gold[MAXN],tgold[MAXN];
int gcdv[MAXN];
int dfn[MAXN],low[MAXN],st[MAXN],top,nq[MAXN];
int gcd(int x,int y){
	if(y==0)
		return x;
	return gcd(y,x%y);
}
char w[MAXN][MAXN];
int tot;
void tar(int x){
	dfn[x]=low[x]=++cnt;
	st[++top]=x;
	for(int u=0;u<n;u++){
		if(w[x][u]=='0')
			continue;
//		PF("<%d -> %d>\n",x,u);
		if(dfn[u]==0){
			tar(u);
			low[x]=min(low[x],low[u]);
		}
		else if(nq[u]==0)
			low[x]=min(low[x],dfn[u]);
	}
	if(dfn[x]==low[x]){
		nq[x]=++tot;
		gcdv[tot]=num[x];
		while(st[top]!=x){
			nq[st[top]]=tot;
			gcdv[tot]=gcd(gcdv[tot],num[st[top]]);
			top--;
		}
		tgold[tot].resize(gcdv[tot]);
		top--;
	}
}
int totg[MAXN],mx[MAXN],mn[MAXN],fac[MAXN],inv[MAXN];
ll C(int x,int y){
	return (ll)fac[x]*inv[y]%MOD*inv[x-y]%MOD;
}
int main(){
	SF("%d%d%d",&n,&A,&B);
	for(int i=0;i<n;i++)
		SF("%s",w[i]);
	for(int i=0;i<n;i++){
		SF("%d",&num[i]);
		SF("%s",s);
		for(int j=0;j<num[i];j++)
			gold[i].push_back(s[j]-'0');
	}
	for(int i=0;i<n;i++)
		if(dfn[i]==0)
			tar(i);
	for(int i=0;i<n;i++)
		for(int j=0;j<num[i];j++)
			tgold[nq[i]][j%gcdv[nq[i]]]|=gold[i][j];
	for(int i=tot;i>1;i--){
		int now=gcd(gcdv[i],gcdv[i-1]);
		for(int j=0;j<gcdv[i];j++)
			tgold[i-1][j%now]|=tgold[i][j];
	}
	for(int i=1;i<=tot;i++)
		for(int j=0;j<gcdv[i];j++)
			if(tgold[i][j])
				totg[i]++;
	for(int i=0;i<n;i++){
		mx[i]=(ll)totg[nq[i]]*num[i]/gcdv[nq[i]];
		for(int j=0;j<num[i];j++)
			if(gold[i][j])
				mn[i]++;
	}
	fac[0]=1;
//	for(int i=1;i<=tot;i++){
//		for(int j=0;j<gcdv[i];j++)
//			PF("%d",tgold[i][j]);
//		PF("\n");
//	}
	for(int i=1;i<=n;i++)
		fac[i]=(ll)fac[i-1]*i%MOD;
	inv[0]=inv[1]=1;
	for(int i=2;i<=n;i++)
		inv[i]=(ll)inv[MOD%i]*(MOD-MOD/i)%MOD;
	for(int i=2;i<=n;i++)
		inv[i]=(ll)inv[i-1]*inv[i]%MOD;
	int ans=0;
//	for(int i=0;i<n;i++)
//		PF("[%d %d]\n",mx[i],mn[i]);
	for(int i=0;i<n;i++){
		int c1=0,c2=0;
		for(int j=1;j<=n;j++)
			if(mn[j]>mx[i])
				c1++;
		if(c1>=A)
			continue;
		for(int j=1;j<=n;j++)
			if(mn[j]<=mx[i]&&(mx[j]>mx[i]||(mx[j]==mx[i]&&j>i)))
				c2++;
		for(int j=min(B-1,min(c2,A-1-c1));B-j-1<=c1&&j>=0;j--)
			ans=(ans+(ll)C(c2,j)*C(c1,B-j-1)%MOD)%MOD;
	}
	PF("%d\n",ans);
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

inline int read()
{
	int sc = 0, f = 1; char ch = getchar();
	while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
	while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
	return sc * f;
}

const int MAXN = 5005;
const int MAXM = 2000005;
const int mod = 1e9 + 7;

int n, a, b, len[MAXN], can[MAXM], id_cnt, L[MAXN], R[MAXN], C[MAXN][MAXN];
int dfn[MAXN], scc[MAXN], low[MAXN], tim, num, st[MAXN], top, w[MAXN], ans;
vector < int > G[MAXN], id[MAXN], scc_bit[MAXN], v[MAXN];
char ch[MAXM];

inline void inc(int &x, int y) { x += y; if( x >= mod ) x -= mod; }

inline void dfs(int x)
{
	dfn[ x ] = low[ x ] = ++tim; st[ ++top ] = x;
	for( auto y : G[ x ] )
		if( !dfn[ y ] ) dfs( y ), low[ x ] = min( low[ x ], low[ y ] );
		else if( !scc[ y ] ) low[ x ] = min( low[ x ], dfn[ y ] );
	if( dfn[ x ] == low[ x ] )
	{
		num++; int t = 0;
		while( t ^ x )
		{
			scc[ t = st[ top-- ] ] = num;
			w[ num ] = __gcd( w[ num ], len[ t ] );
			v[ num ].pb( t );
		}
		scc_bit[ num ].resize( w[ num ] );
		for( auto y : v[ num ] )
			for( int d = 0 ; d < len[ y ] ; d++ ) if( can[ id[ y ][ d ] ] ) scc_bit[ num ][ d % w[ num ] ] = 1;
	}
}

int main()
{
#ifdef wxh010910
	freopen( "data.in", "r", stdin );
#endif
	n = read(), a = read(), b = read();
	for( int i = 0 ; i <= n ; i++ )
	{
		C[ i ][ 0 ] = 1;
		for( int j = 1 ; j <= i ; j++ ) inc( C[ i ][ j ] = C[ i - 1 ][ j ], C[ i - 1 ][ j - 1 ] );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		scanf( "%s", ch + 1 );
		for( int j = 1 ; j <= n ; j++ ) if( ch[ j ] == '1' ) G[ i ].pb( j );
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		len[ i ] = read(); scanf( "%s", ch );
		for( int j = 0 ; j < len[ i ] ; j++ ) id[ i ].pb( ++id_cnt ), can[ id_cnt ] = ch[ j ] == '1', L[ i ] += can[ id_cnt ];
	}
	for( int i = 1 ; i <= n ; i++ ) if( !dfn[ i ] ) dfs( i );
	for( int i = num ; i > 1 ; i-- )
	{
		int g = __gcd( w[ i ], w[ i - 1 ] );
		w[ i - 1 ] = g;
		for( int j = 0 ; j < w[ i ] ; j++ )	scc_bit[ i - 1 ][ j % g ] |= scc_bit[ i ][ j ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		int x = scc[ i ];
		if(len[1]==317829)printf("%d %d\n",i,w[x]);
		for( int j = 0 ; j < len[ i ] ; j++ )
			R[ i ] += scc_bit[ x ][ j % w[ x ] ];
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		if(len[1]==317829)printf("%d %d\n", L[i],R[i]);
		int t1 = 0, t2 = 0;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] > R[ i ] ) t1++;
		if( t1 >= a ) continue;
		for( int j = 1 ; j <= n ; j++ ) if( L[ j ] <= R[ i ] && mp( R[ j ], j ) > mp( R[ i ], i ) ) t2++;
		if(len[1]==317829)
			printf("cnt1=%d cnt2=%d\n",t1,t2);
		for( int j = 0 ; j < b && j <= t2 && j + t1 < a ; j++ )
		{
			if(len[1]==317829)printf("%d %d %d %d %d %d\n",t2,j,C[t2][j],t1,b-1-j,C[t1][b-1-j] );
			inc( ans, 1LL * C[ t2 ][ j ] * C[ t1 ][ b - j - 1 ] % mod );
		}
	}
	return printf( "%d\n", ans ), 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int N=5e3+10;
int low[N],dfn[N],sta[N],col[N],b[N],gmin[N],up[N],down[N],nxt[N],sum[N];
int *mat[N];
string c[N];
char s[N];
bool a[N][N],d[N][N];
int n,A,B,dfstime,cnt,top,root;
ll fac[N],inv[N],ans;
int gcd(int x,int y){
	if (!x||!y) return x+y;
	int z=x%y;
	while (z){
		x=y;y=z;z=x%y;
	}
	return y;
}
void tarjan(int now){
	sta[++top]=now; dfn[now]=++dfstime; low[now]=dfstime;
	for (int i=1;i<=n;i++) if (a[now][i]) {
		if (dfn[i]&&!col[i]) low[now]=min(low[now],dfn[i]);
		else if (!col[i]){
			tarjan(i); low[now]=min(low[now],low[i]);
		}
	}
	if (low[now]>=dfn[now]) {
		int x=0; cnt++; int r=top;
		while (sta[top]!=now) {
			col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
 		}
		col[sta[top]]=cnt; x=gcd(x,b[sta[top]]); top--;
		mat[cnt]=new int[x]; gmin[cnt]=x;
		for (int i=top+1;i<=r;i++) {
			int u=sta[i];
			for (int j=0;j<b[u];j++) if (c[u][j]=='1') mat[cnt][j%x]=1;
		}
	}
}
void init(){
	fac[0]=1; for(int i=1;i<N;i++) fac[i]=(1ll*fac[i-1]*i)%mod;
	inv[0]=1; inv[1]=1; for(int i=2;i<N;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for (int i=1;i<N;i++) inv[i]=(inv[i-1]*inv[i])%mod;
}
ll C(int x,int y){
	if (x<0||y<0||x<y) return 0;
	return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
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++) if (s[j]=='1') a[i][j]=1; else a[i][j]=0;
	}
	for (int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		cin >> c[i];
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) dfstime=0,tarjan(i);
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++) if (a[i][j]&&col[i]!=col[j]) d[col[i]][col[j]]=1;
	}
	int head=1,tail=1;
	for (int i=2;i<=cnt;i++) {
		if (d[i][head]) nxt[i]=head,head=i; else if (d[tail][i]) nxt[tail]=i,tail=i;
		else {
			int x=head;
			while (x!=tail) {
				if (d[x][i]&&d[i][nxt[x]]) {nxt[i]=nxt[x],nxt[x]=i;break;} else x=nxt[x];
			}
		}
	}
	while (head!=tail){
		int x=gcd(gmin[head],gmin[nxt[head]]);
		for (int i=0;i<gmin[head];i++) if (mat[head][i]) mat[nxt[head]][i%x]=1;
		head=nxt[head];
	}
	for (int i=1;i<=cnt;i++)
		for (int j=0;j<gmin[i];j++) if (mat[i][j]) sum[i]++;
	for (int i=1;i<=n;i++) {
		for (int j=0;j<b[i];j++) if (c[i][j]=='1') down[i]++;
		up[i]=sum[col[i]]*(b[i]/gmin[col[i]]);
	}
	init();
//	for (int i=1;i<=n;i++) cout << down[i] << ' ' << up[i] << endl;
	for (int i=1;i<=n;i++)  {
		int cnt1=0,cnt2=0;
		for (int j=1;j<=n;j++) if (j!=i&&down[j]>up[i]) cnt1++;
		else if (j!=i&&(up[j]>up[i]||((up[j]==up[i])&&(j<i)))) cnt2++;
		for (int j=0;j<=min(B-1,cnt2);j++) if (j+cnt1+1<=A) ans=(ans+C(cnt2,j)*C(cnt1,B-j-1)%mod)%mod;
	}
	printf("%lld\n",ans);
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N=5e3+5;
const ll M=4e6+5;
const ll mod=1e9+7;
typedef long long ll;
struct node{
    ll v,nxt;
}edge[N*N];
ll head[N*2],mcnt;
void add_edge(ll u,ll v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
ll ksm(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
ll gcd(ll x,ll y){
    return y?gcd(y,x%y):x;
}
ll scnt,scc[N],sgcd[N];
ll S[N],top;
ll dfn[N],low[N],tot;
bool instack[N];
ll sz[N];
void Tarjan(ll u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(ll i=head[u];i;i=edge[i].nxt){
        ll v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        ll x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
ll fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(ll i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(ll i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(ll i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
ll C(ll x,ll y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[N];
char truegold[N];
ll gold[N];
ll sum1[N],sum2[N];
ll num[N];
ll mx[N],mn[N];
ll n,a,b;
int main()
{
    Init();
    scanf("%I64d%I64d%I64d",&n,&a,&b);
    for(ll i=1;i<=n;i++){
        scanf("%s",s+1);
        for(ll j=1;j<=n;j++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(ll i=1;i<=n;i++){
        scanf("%I64d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(ll i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(ll i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(ll i=1;i<=n;i++){
        for(ll j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]=='1'){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(ll i=scnt;i>1;i--){
        ll G=gcd(sgcd[i],sgcd[i-1]);
        for(ll j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(ll j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(ll i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(ll j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j]=='1';
    }
    ll ans=0;
    for(ll i=1;i<=n;i++){
        ll c1=0,c2=0;
        for(ll j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(ll j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(ll j=max(b-c1-1,0ll);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%I64d\n",ans);
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <queue>
using namespace std;
#define mod 1000000007

struct Edge
{
       long long to,next;
}      e[13000050];

long long now,tp,times,tot,alls,sk[100050],first[100050],dfs[100050],dfn[100050],low[100050],size[100050];
long long c[5050][5050],s[100050],mini[100050],maxi[100050];
long long belong[100050],d[100050],g[100050],all[100050],sum[2000050];
bool vis[10050];
char st[2000050];
pair <long long,long long> pa[100050];
vector <long long> scc[100050],vec[100050],f[100050];

long long  Gcd(long long a,long long b)
{
     if  (a%b==0) return b;
     return Gcd(b,a%b);
}

void Add(long long x,long long y)
{
     e[++now].to=y;
     e[now].next=first[x];
     first[x]=now;
}

void DFS(long long x)
{
long long  pt,next;
     sk[++tp]=x;
     dfs[x]=1;
     dfn[x]=low[x]=++times;
     for (pt=first[x];pt;pt=e[pt].next)
     {
         next=e[pt].to;
         if  (dfs[next]==2) continue;
         if  (dfs[next]==0) DFS(next);
         low[x]=min(low[x],low[next]);
     }
     dfs[x]=2;
     if  (dfn[x]==low[x])
     {
         tot++;
         for (;tp&&sk[tp]!=x;tp--) scc[tot].push_back(sk[tp]);
         if  (tp) tp--;
         scc[tot].push_back(x);
         size[tot]=scc[tot].size();
     }
}

long long  C(long long x,long long y)
{
     if  (x<0||y<0||x<y) return 0;
     return c[x][y];
}

int  main()
{
long long  n,a,b,i,j,k,pt,next,cur,gcd,mins,maxs,ans,sc,sn,p,q,t;
vector <long long> temp;

     //freopen("f.in", "r", stdin);
     //freopen("f.out", "w", stdout);

     scanf("%lld%lld%lld",&n,&a,&b);
     for (i=1;i<=n;i++)
     {
         scanf("%s",st+1);
         for (j=1;j<=n;j++)
         if  (st[j]=='1') Add(i,j);
     }
     for (i=1;i<=n;i++)
     {
         scanf("%lld%s",&s[i],st+1);
         for (j=1;j<=s[i];j++)
         {
             vec[i].push_back(st[j]-'0');
             mini[i]+=st[j]-'0';
         }
     }
     for (i=1;i<=n;i++)
     if  (!dfs[i]) DFS(i);
     for (i=1;i<=tot;i++)
     {
         gcd=-1;
         for (j=0;j<size[i];j++)
         if  (gcd==-1) gcd=s[scc[i][j]]; else gcd=Gcd(gcd,s[scc[i][j]]);
         for (j=0;j<gcd;j++) f[i].push_back(0);
         for (j=0;j<size[i];j++)
         {
             for (k=0;k<s[scc[i][j]];k++)
             if  (f[i][k%gcd]==0&&vec[scc[i][j]][k]==1) f[i][k%gcd]=1;
         }
         g[i]=gcd;
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++) belong[scc[i][j]]=i;
     for (i=1;i<=n;i++)
         for (pt=first[i];pt;pt=e[pt].next)
         {
             next=e[pt].to;
             if  (belong[i]==belong[next]) continue;
             d[belong[next]]++;
         }
     for (i=1;i<=tot;i++)
     {
         for (j=1;j<=tot;j++)
         if  (!vis[j]&&d[j]==0)
         {
             vis[j]=true;
             break;
         }
         all[++alls]=j;
         for (k=0;k<size[j];k++)
             for (pt=first[scc[j][k]];pt;pt=e[pt].next)
             {
                 next=e[pt].to;
                 if  (belong[next]==j) continue;
                 d[belong[next]]--;
             }
     }
     for (i=1;i<alls;i++)
     {
         cur=all[i];
         next=all[i+1];
         sc=f[cur].size();
         sn=f[next].size();
         gcd=Gcd(sc,sn);
         temp.clear();
         for (j=0;j<gcd;j++) temp.push_back(0);
         for (j=0;j<sc;j++)
         if  (f[cur][j]==1&&temp[j%gcd]==0) temp[j%gcd]=1;
         for (j=0;j<sn;j++) f[next][j]|=temp[j%gcd];
     }
     for (i=1;i<=tot;i++)
         for (j=0;j<size[i];j++)
             for (k=0;k<s[scc[i][j]];k++) maxi[scc[i][j]]+=f[i][k%g[i]];
     c[0][0]=1;
     for (i=1;i<=n;i++)
     {
         c[i][0]=c[i][i]=1;
         c[i][1]=i;
     }
     for (i=3;i<=n;i++)
         for (j=2;j<n;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
     for (i=1;i<=n;i++)
     {
         pa[2*i-1]=make_pair(mini[i],0);
         pa[2*i]=make_pair(maxi[i],1);
     }
     sort(pa+1,pa+2*n+1);
     mins=maxs=ans=0;
     for (i=2*n;i>=1;i--)
     if  (pa[i].second==1)
     {
         t=mins;
         p=maxs-sum[pa[i].first]-t;
         q=sum[pa[i].first];
         for (j=0;j<=p&&j+t<a;j++) ans=(ans+1ll*C(p,j)*C(t+q,b-j-1)%mod)%mod;
         maxs++;
         sum[pa[i].first]++;
     }   else mins++;
     printf("%lld\n",ans);

     return 0;
}

#include "bits/stdc++.h"

using namespace std;

inline int read(){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

const int N=5e3+10,M=2e6+10,mod=1e9+7;
typedef long long ll;

struct edges {
    int v;edges *last;
}edge[N*N],*head[N<<1],*ecnt=edge;

inline void push(int u,int v){
    *ecnt=(edges){v,head[u]},head[u]=ecnt++;
}

inline int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}

int bcc_cnt,bccno[N],stk[N],dfn[N],low[N],idx,top,bgcd[N],s[N],n,a,b,instk[N];

inline void tarjan(int x) {
    low[x]=dfn[x]=++idx;
    stk[++top]=x;
    instk[x]=true;
    // printf ("x=%d\n",x);
    for (edges *i=head[x];i;i=i->last)
        if(!dfn[i->v])
            tarjan(i->v),low[x]=min(low[x],low[i->v]);
        else  if(instk[i->v])  low[x]=min(low[x],dfn[i->v]);
    if(dfn[x]==low[x]) {
        bcc_cnt++;int t;
        do instk[t=stk[top--]]=false,bccno[t]=bcc_cnt,bgcd[bcc_cnt]=gcd(bgcd[bcc_cnt],s[t]);while (t!=x);
    }
}

char me[N],gold[M<<1];
int fr[N<<1],in[N],now[N],num[N],mx[N],mn[N];

inline void bfs(){
    static int q[N];
    int l=0,r=0,x;
    for (int i=1;i<=bcc_cnt;++i)    if(!in[i])
        q[r++]=i+n,now[i]=bgcd[i];
    while (l^r) {
        x=q[l++];
        // printf ("x=%d\n",x);
        for (edges *i=head[x];i;i=i->last)  {
            in[i->v-n]--;
            // printf ("int[%d]=%d\n",i->v,in[i->v-n]);
            if (!in[i->v-n])  {
                now[i->v-n]=gcd(now[x-n],bgcd[i->v-n]);
                for (int j=fr[x];j<fr[x+1];++j) if (gold[j])
                    gold[fr[i->v]+(j-fr[x])%now[i->v-n]]=2;
                q[r++]=i->v;
            }
        }
        // for (int j=fr[x];j<fr[x+1];++j) if(gold[j])
            // gold[fr[x]+(j-fr[x])%now[x-n]]=true;
        for (int j=0;j<now[x-n];++j) if (gold[fr[x]+j]==2)
            for (int k=0;k*now[x-n]<bgcd[x-n];++k)
                gold[fr[x]+k*now[x-n]+j]=true;
        for (int j=fr[x];j<fr[x+1];++j)
            num[x-n]+=gold[j];
    }
}

int inv[N],fac[N];

#define C(i,j) ((ll)fac[i]*inv[j]%mod*inv[i-(j)]%mod)

int main(){
    n=read(),a=read(),b=read();
    for (int i=1;i<=n;++i) {
        scanf("%s",me+1);
        for (int j=1;j<=n;++j)  if(me[j]^48)  push(i,j);
    }
    for (int i=1;i<=n;++i)  {
        s[i]=read();
        fr[i]=fr[i-1]+s[i-1];
        scanf("%s",gold+fr[i]);
    }
    // fr[n+1]=fr[n]+s[i];
    // if (head[1])
    for (int i=1;i<=n;++i)  if(!dfn[i])
        tarjan(i);
    bgcd[0]=s[n];
    for (int i=1;i<=bcc_cnt;++i)
        fr[i+n]=fr[i-1+n]+bgcd[i-1];
    fr[n+bcc_cnt+1]=fr[n+bcc_cnt]+bgcd[bcc_cnt];
    for (int i=0;i<fr[n+1];++i)
        gold[i]^=48;
    //printf ("bcc=%d\n",bcc_cnt);
    // printf("%s",gold);
    for (int i=1;i<=n;++i) {
        // printf ("")
        for (edges *j=head[i];j;j=j->last)
            if (bccno[i]!=bccno[j->v])
                push(bccno[i]+n,bccno[j->v]+n),++in[bccno[j->v]];
        for (int j=fr[i];j<fr[i+1];++j)
            if (gold[j])
                gold[fr[bccno[i]+n]+(j-fr[i])%bgcd[bccno[i]]]=true;
    }
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);
    bfs();
    // for (int i=0;i<fr[n+bcc_cnt+1];++i)
        // gold[i]^=48;
    // printf("%s\n",gold);

    for (int i=1;i<=n;++i)  {
        mx[i]=num[bccno[i]]*s[i]/bgcd[bccno[i]];
        for (int j=fr[i];j<fr[i+1];++j)
            mn[i]+=gold[j];
        // printf("mn[%d]=%d mx=%d\n",i,mn[i],mx[i]);
    }
    fac[0]=1;
    for (int i=1;i<=n;++i) fac[i]=(ll)fac[i-1]*i%mod;
    inv[0]=inv[1]=1;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod;
    for (int i=2;i<=n;++i)  inv[i]=(ll)inv[i]*inv[i-1]%mod;
    int ans=0;
    for (int i=1;i<=n;++i) {
        int c1=0,c2=0;
        for (int j=1;j<=n;++j) if (mn[j]>mx[i]) ++c1;
        if (c1>=a) continue;
        for (int j=1;j<=n;++j)
            if (mn[j]<=mx[i]&&(mx[j]>mx[i]||mx[j]==mx[i]&&j>i)) ++c2;
        // printf ("c1=%d c2=%d\n",c1,c2);
        for (int j=min(b-1,min(c2,a-1-c1));~j;--j)
            ans=(ans+C(c2,j)*C(c1,b-j-1)%mod)%mod;
    }
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2e6+10;
const int mod=1e9+7;
typedef pair<int,int> pii;
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define real xzzakhnoi2020

int n,a,b,C[N][N],deg[N],id[N],vis[M],tim,real[N],all[N];
string s[N];
pii p[N];
char E[N];
bool new_scc[N];

int main() {
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>a>>b;
	for(int i=0;i<N;i++) {
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
	}
	for(int i=1,len;i<=n;i++) {
		cin>>(E+1);
		for(int j=1;j<=n;j++) deg[i]+=(E[j]=='1');
	}
	for(int i=1,len;i<=n;i++) {
		cin>>len>>s[i],id[i]=i;
		for(auto c:s[i]) if(c=='1') ++real[i];
	}
	sort(id+1,id+n+1,[&](int a,int b) { return deg[a]>deg[b]; });
	for(int i=n,sdeg=0;i;i--) {
		sdeg+=deg[id[i]];
		if(sdeg==(n-i+1)*(n-i)/2) new_scc[i]=1;
	}
	for(int i=1,j;i<=n;i=j+1) {
		j=i;while(j<n&&!new_scc[j+1]) ++j;
		int gg=0;
		for(int k=i;k<=j;k++) gg=__gcd(gg,sz(s[id[k]]));
		++tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(s[id[k]][l]=='1') vis[l%gg]=tim;
		for(int k=i;k<=j;k++)
			for(int l=0;l<sz(s[id[k]]);l++) if(vis[l%gg]==tim) s[id[k]][l]='1';
		if(j<n) {
			gg=__gcd(sz(s[id[j]]),sz(s[id[j+1]]));
			++tim;
			for(int l=0;l<sz(s[id[j]]);l++) if(s[id[j]][l]=='1') vis[l%gg]=tim;
			for(int l=0;l<sz(s[id[j+1]]);l++) if(vis[l%gg]) s[id[j+1]][l]='1';
		}
	}
	for(int i=1;i<=n;i++) {
		for(auto c:s[i]) if(c=='1') ++all[i];
		p[i]=mp(real[i],all[i]);
	}
	sort(p+1,p+n+1,[&](pii a,pii b) { return a.se<b.se; });
	int ans=0;
	for(int i=1;i<=n;i++) {
		int cntl=0,cntr=0;
		for(int j=1;j<i;j++) if(p[j].fi>p[i].se) ++cntl;
		for(int j=i+1;j<=n;j++) if(p[j].fi>p[i].se) ++cntr;
		if(cntl>a-b) continue;
		for(int i=max(0,cntr-a-b+cntl);i<=cntr&&i<b;i++)
			ans=(ans+1ll*C[cntr][i]*C[n-i-cntr][b-1-i])%mod;
	}
	cout<<ans;
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[M];
char truegold[M];
int gold[M];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=0;i<sum1[n]+sz[n];i++)
        truegold[i]-='0';
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=scnt;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i<j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
vector <int> have_real[5005],have_gold[5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		have_real[i].push_back(0);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			L[i]+=x;
			have_real[i].push_back(x);
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=tot;i++) have_gold[i].resize(siz_new[i]+1);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j+1];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=1ll*C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			if(ans>MOD) ans-=MOD;
			if(ans<0) ans+=MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
bool have_real[5005][5005],have_gold[5005][5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return (fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			if(x) L[i]++,have_real[i][j]=true;
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j+1];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			ans=(ans+MOD)%MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}

#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
const int N = 5001;
int n, a, b;
namespace hamilton_path_for_competition_map{
    vector<vector<bool> > edge;
    vector<int> d;
    bool expand(int x, int n) {
        d.resize(0);
        d.push_back(x);
        for (int i = 0; i < n; i ++)
            if (i != x) {
                if (edge[d[d.size() - 1]][i]) d.push_back(i);
                else {
                    int x = 0;
                    while (edge[d[x]][i])
                        x ++;
                    d.push_back(i);
                    rotate(d.begin() + x, d.end() - 1, d.end());
                }
            }
        if (d.size() == n) return 1;
        return 0;
    }
    vector<int> construct(vector<vector<bool> >_edge, int n) {
        edge = _edge;
        for (int i = 0; i < n; i ++)
            if (expand(i, n)) {
                return d;
            }
        d.resize(0);
        return d;
    }
}
typedef long long ll;
const int mod = 1e9 + 7;
ll calc(ll x, ll y){
    ll z = 1;
    while (y) {
        if (y & 1) z = z * x % mod;
        x = x * x % mod, y /= 2;
    }
    return z;
}
namespace C{
    const int mod = 1e9+7;
    vector<int>a, nia;
    void pre(int n){
        a = vector<int>(n + 1, 1);
        nia = vector<int>(n + 1, 1);
        for (int i = 2; i <= n; i ++)
            a[i] = 1ll * a[i - 1] * i % mod;
        nia[n] = calc(a[n], mod - 2);
        for (int i = n - 1; i >= 2; i --)
            nia[i] = 1ll * nia[i + 1] * (i + 1) % mod;
    }
    ll C(ll x, ll y) {
        if (x < y || y < 0) return 0;
        return 1ll * a[x] * nia[y] % mod * nia[x - y] % mod;
    }
}
namespace count{//�������li��ri��Χ����ǰa������ѡb���Ĳ�ͬ�ļ�����
    const int mod = 1e9+7;
    const int N = 2e6 + 1;
    int gao(vector<pair<int, int> > d, int a, int b) {
        sort(d.begin(), d.end(), [](pair<int, int> a, pair<int, int> b) {
            return a.first < b.first;
        });
        C::pre(d.size());
        if (a == d.size()) {
            return C::C(a, b);
        }
        int ans = 0;
        if (b == 1) {
            vector<bool> bz(d.size(), 0);
            for (int i = 0; i < d.size(); i++) {
                for (int j = 0; j < i; j++)
                    if (d[j].second >= d[i].first) {
                        bz[j] = 1;
                    }
            }
            for (int i = 1; i <= a && i <= d.size(); i ++)
                bz[d.size() - i] = 1;
            for (auto u:bz)
                ans += u;
        } else {
            ans = 1;
            for (int i = 0; i < d.size(); i++) {
                int sum = 0;
                for (int j = 0; j < i; j++)
                    if (d[j].second >= d[i].first) {
                        ++sum;
                    }
                ans = (ans + 1ll * sum * C::C((d.size() - i - 2), b - 2)) % mod;
            }
        }
        return ans;
    }
}
int id[N];
int fa[N], c[2000001];
vector<int>w[N];
int getfa(int x) {
    return fa[x] == x? x : fa[x] = getfa(fa[x]);
}
int main() {
    scanf("%d %d %d", &n, &a, &b);
    vector<vector<bool> > edge(n, vector<bool>(n));
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < n ; j ++) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            if (c =='1') edge[i][j] = 1;
        }
    }
    vector<int>d = hamilton_path_for_competition_map::construct(edge, n);
    for (int i = 0; i < d.size();  i ++)
        id[d[i]] = i, fa[i] = i;
    for (int u = 0; u < n ; u ++) {
        int tmp = u;
        for (int v = 0; v < n; v++)
            if (edge[d[u]][v]) {
                tmp = min(tmp, id[v]);
            }
        for (int i = tmp; i < u; i ++)
            if (getfa(d[i]) != d[u]) {
                fa[getfa(d[i])] = d[u];
            }
    }
    vector<vector<int> > g(n, vector<int>(0));
    for (int i = 0; i < n; i ++)
        g[getfa(i)].push_back(i);
    for (int i = 0; i < n; i ++) {
        int x;
        scanf("%d", &x);
        while (x --) {
            char c;
            while ((c = getchar()) != '0' && c != '1');
            w[i].push_back(c - '0');
        }
    }
    vector<int> dd(0);
    for (auto u:d)
        if (getfa(u) == u)
            dd.push_back(u);
    for (int i = 0; i < dd.size(); i ++) {
        int u = dd[i];
        int gcd = 0;
        for (auto v:g[u]) {
            int tmp = w[v].size();
            gcd = __gcd(tmp, gcd);
        }
        for (int i = 0; i < gcd; i++)
            c[i] = 0;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (w[v][i])
                    c[i % gcd] = 1;
        for (auto v:g[u])
            for (int i = 0; i < w[v].size(); i++)
                if (!w[v][i] && c[i % gcd])
                    w[v][i] = 2;
        if (i != dd.size() - 1) {
            int v = dd[i + 1];
            int tmp = w[v].size();
            int gcd1 = __gcd(tmp, gcd);
            for (int i = 0; i < gcd1; i ++)
                for (int j = 0; j * gcd1 + i < gcd; j ++)
                    c[i] |= c[i + j * gcd1];
            for (int i = 0; i < w[v].size(); i ++)
                if (!w[v][i] && c[i % gcd1])
                    w[v][i] = 2;
        }
    }
    vector<pair<int, int> > f;
    for (int i = 0; i < n; i ++) {
        int l = 0, r = 0;
        for (auto u:w[i])
            if (u == 1) l ++, r ++;
            else
                if (u == 2) r ++;
        f.push_back(make_pair(l, r));
    }
    if (n > 10) return 0;
    printf("%d\n",count::gao(f, a, b));
    return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+5;
const int M=4e6+5;
const int mod=1e9+7;
typedef long long ll;
struct node{
    int v,nxt;
}edge[N*N];
int head[N*2],mcnt;
void add_edge(int u,int v){
    mcnt++;
    edge[mcnt].v=v;
    edge[mcnt].nxt=head[u];
    head[u]=mcnt;
}
int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)
            res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return res;
}
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
int scnt,scc[N],sgcd[N];
int S[N],top;
int dfn[N],low[N],tot;
bool instack[N];
int sz[N];
void Tarjan(int u){
    low[u]=dfn[u]=++tot;
    S[++top]=u;
    instack[u]=1;
    for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scnt++;
        int x;
        do{
            x=S[top--];
            instack[x]=false;
            scc[x]=scnt;
            sgcd[scnt]=gcd(sgcd[scnt],sz[x]);
        }while(x!=u);
    }
}
int fact[N+5],inv[N+5];
void Init(){
    fact[0]=1;
    for(int i=1;i<N;i++)
        fact[i]=1ll*fact[i-1]*i%mod;
    inv[1]=1;
    for(int i=2;i<N;i++)
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    inv[0]=1;
    for(int i=1;i<N;i++)
        inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
int C(int x,int y){
    if(x<0||x<y)
        return 0;
    return 1ll*fact[x]*inv[y]%mod*inv[x-y]%mod;
}
char s[N];
char truegold[N];
int gold[N];
int sum1[N],sum2[N];
int num[N];
int mx[N],mn[N];
int n,a,b;
int main()
{
    Init();
    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++)
            if(s[j]=='1')
                add_edge(i,j);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&sz[i]);
        sum1[i]=sum1[i-1]+sz[i-1];
        scanf("%s",truegold+sum1[i]);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    for(int i=1;i<=n;i++)
        sum2[i]=sum2[i-1]+sgcd[i-1];
    for(int i=1;i<=n;i++){
        for(int j=sum1[i];j<sum1[i+1];j++){
            if(truegold[j]=='1'){
                gold[sum2[scc[i]]+(j-sum1[i])%sgcd[scc[i]]]=true;
            }
        }
    }
    for(int i=scnt;i>1;i--){
        int G=gcd(sgcd[i],sgcd[i-1]);
        for(int j=0;j<sgcd[i];j++)
            if(gold[sum2[i]+j]){
                num[i]++;
                gold[sum2[i-1]+j%G]=true;
            }
    }
    for(int j=0;j<sgcd[1];j++)
        if(gold[j])
            num[1]++;
    for(int i=1;i<=n;i++){
        mx[i]=1ll*num[scc[i]]*sz[i]/sgcd[scc[i]];
        for(int j=sum1[i];j<sum1[i+1];j++)
            mn[i]+=truegold[j]=='1';
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        int c1=0,c2=0;
        for(int j=1;j<=n;j++)
            if(mn[j]>mx[i])
                c1++;
        if(c1>=a)
            continue ;
        for(int j=1;j<=n;j++)
            if(mn[j]<=mx[i]&&(mx[i]<mx[j]||(mx[i]==mx[j]&&i>j)))
                c2++;
        for(int j=max(b-c1-1,0);j<=b-1&&j<=c2&&j<=a-c1-1;j++){
            ans=(ans+1ll*C(c2,j)*C(c1,b-j-1)%mod)%mod;
        }
    }
    printf("%d\n",ans);
}

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXS = 4e6 + 5, MAXN = 4e6 + 5, MAXE = 5005 * 5005 >> 1;

template<typename _T>
_T MIN( const _T a, const _T b )
{
	return a < b ? a : b;
}

struct edge
{
	int to, nxt;
}Graph[MAXE];

int fac[MAXS], ifac[MAXS];
int G[MAXN], GBeg[MAXN], count[MAXN];

int DFN[MAXN], LOW[MAXN], stk[MAXN], top;

char STR[MAXS];
int beg[MAXN], s[MAXN], mn[MAXN], mx[MAXN];
int head[MAXN], bel[MAXN];
int N, A, B, cnt, ID, tot, siz;
bool in[MAXN], bar[MAXS], GBar[MAXS];

bool *BA( const int i ) { return bar + beg[i]; }
bool *GB( const int i ) { return GBar + GBeg[i]; }

void addEdge( const int from, const int to )
{
	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
	head[from] = cnt;
}

int gcd( const int a, const int b ) { return b ? gcd( b, a % b ) : a; }

void Tarjan( const int u )
{
	DFN[u] = LOW[u] = ++ ID;
	in[stk[++ top] = u] = true;
	for( int i = head[u], v ; i ; i = Graph[i].nxt )
	{
		if( ! DFN[v = Graph[i].to] ) Tarjan( v ), LOW[u] = MIN( LOW[u], LOW[v] );
		else if( in[v] ) LOW[u] = MIN( LOW[u], DFN[v] );
	}
	if( LOW[u] == DFN[u] )
	{
		int v; ++ tot;
		do
		{
			in[v = stk[top --]] = false;
			G[tot] = gcd( s[v], G[tot] );
			bel[v] = tot;
		}
		while( v ^ u );
	}
}

int qkpow( int base, int indx )
{
	int ret = 1;
	while( indx )
	{
		if( indx & 1 ) ret = 1ll * ret * base % mod;
		base = 1ll * base * base % mod, indx >>= 1;
	}
	return ret;
}

void init( const int S )
{
	fac[0] = 1;
	for( int i = 1 ; i <= S ; i ++ ) fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[S] = qkpow( fac[S], mod - 2 );
	for( int i = S - 1 ; ~ i ; i -- ) ifac[i] = 1ll * ifac[i + 1] * ( i + 1 ) % mod;
}

int C( const int n, const int m )
{
	if( n < m || m < 0 || n < 0 ) return 0;
	return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main()
{
	scanf( "%d %d %d", &N, &A, &B );
	for( int i = 1 ; i <= N ; i ++ )
	{
		scanf( "%s", STR + 1 );
		for( int j = 1 ; j <= N ; j ++ )
			if( STR[j] == '1' )
				addEdge( i, j );
	}
	for( int i = 1 ; i <= N ; i ++ )
	{
		scanf( "%d%s", &s[i], STR + 1 );
		beg[i] = siz + 1; siz += 2 * s[i];
		for( int j = 0 ; j < s[i] ; j ++ )
			BA( i )[j] = STR[j] - '0', mn[i] += STR[j] - '0';
	}
	init( siz + 5 );

	siz = 1;
	for( int i = 1 ; i <= N ; i ++ ) if( ! DFN[i] ) Tarjan( i );
	for( int i = 1 ; i <= N ; i ++ )
		for( int j = 0 ; j < s[i] ; j ++ )
			GB( bel[i] )[j % G[bel[i]]] |= BA( i )[j];
	for( int i = tot ; i > 1 ; i -- )
	{
		int d = gcd( G[i], G[i - 1] );
		for( int j = 0 ; j < G[i] ; j ++ )
			GB( i - 1 )[j % d] |= GB( i )[j];
	}

	for( int i = 1 ; i <= tot ; i ++ )
		for( int k = 0 ; k < G[i] ; k ++ )
			count[i] += GB( i )[k];
	for( int i = 1 ; i <= N ; i ++ )
		mx[i] = 1ll * s[i] * count[bel[i]] / G[bel[i]];

	int ans = 0, cnt1, cnt2;
	for( int i = 1 ; i <= N ; i ++ )
	{
		cnt1 = cnt2 = 0;
		for( int j = 1 ; j <= N ; j ++ )
			if( i ^ j )
			{
				if( mn[j] > mx[i] ) cnt1 ++;
				else if( mx[j] > mx[i] || ( mx[j] == mx[i] && j < i ) ) cnt2 ++;
			}
		if( cnt1 > A - 1 ) continue;
		for( int j = MIN( B, MIN( A - 1 - cnt1, cnt2 ) ) ; j + cnt1 + 1 >= B ; -- j )
			ans = ( ans + 1ll * C( cnt2, j ) * C( cnt1, B - j - 1 ) % mod ) % mod;
	}
	printf( "%d\n", ans );
	return 0;
}

#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD=1e9+7,MAXM=2e6+5;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
vector <int> G[5005];
bool have_real[5005][5005],have_gold[5005][5005];
int n,a,b,siz[5005],all_gold[5005],L[5005],R[5005];
int siz_new[5005],pos[5005],dfn[5005],low[5005],have_last[5005],times,tot;/*Tarjan 用*/
int in[5005];/*Top sort 用*/
int inv[2000005],fac[2000005];/*数学用*/
stack <int> s;
int qpow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=1ll*ret*a%MOD;
		b>>=1;
		a=1ll*a*a%MOD;
	}
	return ret;
}
void Tarjan(int u)
{
	low[u]=dfn[u]=++times;
	s.push(u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(!pos[v]) low[u]=min(low[u],low[v]);
	}
	if(dfn[u]==low[u])
	{
		int t=-1;
		tot++;
		while(t!=u)
		{
			t=s.top();
			s.pop();
			pos[t]=tot;
			siz_new[tot]=gcd(siz[t],siz_new[tot]);
		}
	}
}
int C(int x,int y){
	if (x<y||x<0||y<0) return 0;
	return 1ll*(1ll*fac[x]*inv[y]%MOD)*inv[x-y]%MOD;
}
inline void init(int nn)
{
	fac[0]=1;
	for(int i=1;i<=nn;i++) fac[i]=1ll*fac[i-1]*i%MOD;
	inv[nn]=qpow(fac[nn],MOD-2);
	for(int i=nn;i;i--) inv[i-1]=1ll*inv[i]*i%MOD;
}
int main() {
	init(MAXM-5);
	int x,ans=0;
	scanf("%d %d %d",&n,&a,&b);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&x);
			if(x) G[i].push_back(j);
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&siz[i]);
		for(int j=1;j<=siz[i];j++)
		{
			scanf("%1d",&x);
			if(x) L[i]++,have_real[i][j]=true;
		}
	}
	/*==========Part 1  Begin==========*/
	for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<siz[i];j++) have_gold[pos[i]][j%siz_new[pos[i]]]|=have_real[i][j+1];
	}
	for(int i=tot;i>=2;i--)
	{
		int g=gcd(siz_new[i],siz_new[i-1]);
		for(int j=0;j<siz_new[i];j++)
		{
			have_gold[i-1][j%g]|=have_gold[i][j];
			all_gold[i]+=have_gold[i][j];
		}
	}
	for(int i=0;i<siz[1];i++) all_gold[1]+=have_gold[1][i];
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=siz[i];j++) printf("%d",have_gold[pos[i]][j]);
//		putchar('\n');
//	}
	for(int i=1;i<=n;i++) R[i]=all_gold[pos[i]]*siz[i]/siz_new[pos[i]];
//	for(int i=1;i<=n;i++) printf("%d %d\n",L[i],R[i]);
	/*==========Part 1  End==========*/

	/*==========Part 2  Begin==========*/
//	for(int i=1;i<=n;i++) printf("%d ",inv[i]);
	for(int i=1;i<=n;i++)
	{
		int cnt1=0,cnt2=0;
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			if(L[j]>R[i]) cnt1++;
			else if(R[i]<R[j]||(R[i]==R[j]&&j<i)) cnt2++;
		}
		if(cnt1>a-1) continue;
		for(int j=min(b,min(cnt2,a-1-cnt1));j+cnt1+1>=b;j--)
		{
			ans+=C(cnt2,j)*C(cnt1,b-j-1)%MOD;
			ans=(ans+MOD)%MOD;
//			printf("%d %d\n",C(cnt2,j),C(cnt1,b-j-1));
		}
	}
	printf("%d\n",ans);
	return 0;
}