In Isart people don't die. There are n gangs of criminals. The i-th gang contains si evil people numerated from 0 to si - 1. Some of these people took part in a big mine robbery and picked one gold bullion each (these people are given in the input). That happened 10100 years ago and then all of the gangs escaped to a remote area, far from towns.During the years, they were copying some gold bullions according to an organized plan in order to not get arrested. They constructed a tournament directed graph (a graph where there is exactly one directed edge between every pair of vertices) of gangs (the graph is given in the input). In this graph an edge from u to v means that in the i-th hour the person  of the gang u can send a fake gold bullion to person  of gang v. He sends it if he has some bullion (real or fake), while the receiver doesn't have any. Thus, at any moment each of the gangsters has zero or one gold bullion. Some of them have real bullions, and some of them have fake ones.In the beginning of this year, the police has finally found the gangs, but they couldn't catch them, as usual. The police decided to open a jewelry store so that the gangsters would sell the bullions. Thus, every gangster that has a bullion (fake or real) will try to sell it. If he has a real gold bullion, he sells it without problems, but if he has a fake one, there is a choice of two events that can happen:   The person sells the gold bullion successfully.  The person is arrested by police. The power of a gang is the number of people in it that successfully sold their bullion. After all selling is done, the police arrests b gangs out of top gangs. Sort the gangs by powers, we call the first a gang top gangs(you can sort the equal powers in each order). Consider all possible results of selling fake gold bullions and all possible choice of b gangs among the top gangs. Count the number of different sets of these b gangs modulo 109 + 7. Two sets X and Y are considered different if some gang is in X and isn't in Y.

The first line contains four integers n, a and b (1 ≤ b ≤ a ≤ n ≤ 5·103) — the number of gangs, the constants a and b from the statement. Then n lines follow, each line contains a string of size n consisting of zeros and ones. The j-th character in the i-th of these lines is equal to 1, then the vertex i have a directed edge to the vertex j. It is guaranteed that aii = 0 and aij + aji = 1 if i ≠ j. Then n lines follow, each line starts with the integer si (1 ≤ si ≤ 2·106) — the number of gangsters in the i-th gang, and then contains a string of zeros and ones with length si. The j-th character is 0 if the j-th person of the i-th gang had a real gold bullion initially, otherwise it is 1. It is guaranteed that the sum of si does not exceed 2·106.

Print single integer: the number of different sets of b gangs the police can arrest modulo 109 + 7.

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

#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<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 <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 <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<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>
#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比它大的元素
*/

#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

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

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

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

//   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 <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 <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 <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<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"

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

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

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

/*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 <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<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;
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 <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<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 <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<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
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<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<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 <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<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 <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<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>
#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 <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<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 "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<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>
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 <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 <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>

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

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

//   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<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<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;

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>
#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 <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<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 <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<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

#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>

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

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