//第一次学会用字典树模板,一开始作比赛的时候,自己写的strstr/kmp都是不停地超时,结果发现用字典树就过了,还是见得太少了
#include<stdio.h>
#include<math.h>
#include<string.h>
char s[10005][35];
char c[35];
double f[10];
int bin[10],flag,zi[30],next[100];
double a,b;
#define MAX 26 //字符集大小
typedef struct TrieNode
{
int nCount; //记录该字符出现次数
struct TrieNode *next[MAX];
}TrieNode;
TrieNode Memory[1000000];
int allocp = 0;
/*初始化*/
void InitTrieRoot(TrieNode **pRoot)
{
*pRoot = NULL;
}
/*创建新结点*/
TrieNode *CreateTrieNode()
{
int i;
TrieNode *p;
p = &Memory[allocp++];
p->nCount = 1;
for(i = 0 ; i < MAX ; i++)
{
p->next[i] = NULL;
}
return p;
}
/*插入*/
void InsertTrie(TrieNode **pRoot , char *s)
{
int i , k;
TrieNode *p;
if(!(p = *pRoot))
{
p = *pRoot = CreateTrieNode();
}
i = 0;
while(s[i])
{
k = s[i++] - 'a'; //确定branch
if(p->next[k])
p->next[k]->nCount++;
else
p->next[k] = CreateTrieNode();
p = p->next[k];
}
}
//查找
int SearchTrie(TrieNode **pRoot , char *s)
{
TrieNode *p;
int i , k;
if(!(p = *pRoot))
{
return 0;
}
i = 0;
while(s[i])
{
k = s[i++] - 'a';
if(p->next[k] == NULL) return 0;
p = p->next[k];
}
return p->nCount;
}
int distant(double p){
double d1,d2;
if(p<0.5*b) return -1;
else if(p>=2*a) return 1;
else if(p>=a&&p<=b) return 0;
else if(0.5*b<p&&p<a){
d1=p-0.5*b;
d2=a-p;
return d1<d2?-1:0;
}
else if(p>b&&p<2*a){
d1=p-b;
d2=2*a-p;
return d1<d2?0:1;
}
}
void encode(){
int i;
for(i=0;i<8;i++){
if(i==0){
a=f[0]/1.05;
b=f[0]/0.95;
bin[0]=0;
}
else{
bin[i]=distant(f[i]);
if(bin[i]<0) flag=1;
}
}
}
int bintoten(){
int i,x=0,y=1;
for(i=7;i>=0;i--){
if(flag) bin[i]++;
x+=bin[i]*y;
y*=2;
}
return x;
}
int main(){
TrieNode *Root = NULL;
int n,m,i,k,j,cont;
// freopen("3.txt","r",stdin);
while(scanf("%d %d",&n,&m)!=EOF){
InitTrieRoot(&Root);
for(i=0;i<n;i++){
scanf("%s",s[i]);
InsertTrie(&Root,s[i]);
}
cont=0;
while(m--){
memset(c,0,sizeof(c));
scanf("%d",&k);
j=0;
while(k--){
for(i=0;i<8;i++){
scanf("%lf",&f[i]);
}
flag=0;
encode();
c[j]=bintoten();
j++;
}
cont+=SearchTrie(&Root,c);
}
printf("%d\n",cont);
}
return 0;
}