#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <bitset>
#include <algorithm>
#define _min(_a_,_b_) ((_a_)<(_b_)?(_a_):(_b_))
#ifdef ONLINE_JUDGE
char __B[1<<15],*__S=__B,*__T=__B;
#define getchar() (__S==__T&&(__T=(__S=__B)+fread(__B,1,1<<15,stdin),__S==__T)?EOF:*__S++)
#endif
inline int getnum()
{
register char c=0;
register bool neg=false;
while(!(c>='0' && c<='9'))
c=getchar(),neg|=(c=='-');
register int a=0;
while(c>='0' && c<='9')
{
a*=10;a+=c-'0';
c=getchar();
}
return (neg?-1:1)*a;
}
inline void PrintNum(register int a)
{
static int buf[32];buf[0]=0;
register int lb=0;
while(a>9)
buf[++lb]=a%10,a/=10;
buf[++lb]=a;
for(register int i=lb;i>=1;i--)
putchar('0'+buf[i]);
putchar('\n');
}
int M,N,K;
int x[10][200001],_y[10][200001],y[10][200001],yb[10][451];
int idx[10][200001];
int _k;
struct _comp
{
bool operator ()(const int&a,const int&b)const
{
if(_y[_k][a]!=_y[_k][b])
return _y[_k][a]<_y[_k][b];
return a<b;
}
};
int f[305050];
#define _lowbit(_o_) ((_o_)&-(_o_))
inline void update(register int o,const int&val)
{
while(o<=N+M)
{
f[o]+=val;
o+=_lowbit(o);
}
}
inline int query(register int o)
{
register int ans=0;
while(o)
{
ans+=f[o];
o-=_lowbit(o);
}
return ans;
}
struct _res
{
int y1,y2,y3,idx;
bool operator < (const _res&o)const
{
if(y1!=o.y1)
return y1<o.y1;
return idx>o.idx;
}
}res[305050],tres[305050];
struct _compy2
{
bool operator()(const _res&a,const _res&b)const
{
if(a.y2!=b.y2)
return a.y2<b.y2;
return a.idx>b.idx;
}
};
int ans[155050];
void CDQ_Divide(register int l,register int r)
{
if(l==r)
return;
register int mid=(l+r)>>1,tl=l,tr=mid+1;
CDQ_Divide(l,mid),CDQ_Divide(mid+1,r);
register int j=l;
for(register int i=mid+1;i<=r;i++)
{
while(j<=mid && res[j].y3<res[i].y3)
{
if(!res[j].idx)
update(res[j].y2,1);
j++;
}
if(res[i].idx)
ans[res[i].idx]+=query(res[i].y2-1);
}
for(register int i=l;i<j;i++)
if(!res[i].idx)
update(res[i].y2,-1);
for(register int i=l;i<=r;i++)
if(tr>r || (tl<=mid && res[tl].y3<res[tr].y3))
tres[i]=res[tl++];
else
tres[i]=res[tr++];
for(register int i=l;i<=r;i++)
res[i]=tres[i];
}
inline void PreAKT()
{
for(register int i=1;i<=N;i++)
res[i]=(_res){y[0][i],y[1][i],y[2][i],0};
for(register int i=1;i<=M;i++)
res[N+i]=(_res){x[0][i],x[1][i],x[2][i],i};
std::sort(&res[1],&res[N+M+1],_compy2());
register int ly2=0;
for(register int i=1;i<=N+M;i++)
if(res[i].y2 != res[i-1].y2)
res[i].y2=++ly2;
else
res[i].y2=res[i-1].y2;
std::sort(&res[1],&res[N+M+1]);
}
//
#pragma GCC optimize(3)
__attribute__((optimize("-O3"))) int main()
{
M=getnum(),N=getnum(),K=getnum();
for(register int i=1;i<=M;i++)
for(register int k=0;k<K;k++)
x[k][i]=getnum();
for(register int i=1;i<=N;i++)
for(register int k=0;k<K;k++)
y[k][i]=_y[k][i]=getnum();
if(N>20000)
if(N>100000)
if(N>150000)
{
std::sort(&y[0][1],&y[0][N+1]);
for(register int i=1;i<=M;i++)
if(x[0][i]-1<y[0][1])
PrintNum(0);
else
PrintNum(std::upper_bound(&y[0][1],&y[0][N+1],x[0][i]-1)-&y[0][1]);
}
else
{
PreAKT();
register int j=1;
for(register int i=1;i<=N+M;i++)
{
if(!res[i].idx)
continue;
while(j<=N+M && res[j].y1<res[i].y1)
{
if(!res[j].idx)
update(res[j].y2,1);
j++;
}
ans[res[i].idx]=query(res[i].y2-1);
}
for(register int i=1;i<=M;i++)
PrintNum(ans[i]);
}
else
{
PreAKT();
CDQ_Divide(1,N+M);
for(register int i=1;i<=M;i++)
PrintNum(ans[i]);
}
else
{
register int BlockSize=__builtin_sqrt(N),BlockNum=N/BlockSize+(N%BlockSize!=0);
static int _bpos[105050],_bleft[350],_bright[350];
#define GetBlockPos(_p_) (_bpos[_p_])
#define GetBlockLeft(_w_) (_bleft[_w_])
#define GetBlockRight(_w_) (_bright[_w_])
_bleft[1]=1,_bright[BlockNum]=N;
for(register int i=1,tb=1;i<=N+1;i++)
{
_bpos[i]=tb;
if(i%BlockSize == 0)
_bright[tb++]=i,_bleft[tb]=i+1;
}
_bpos[0]=1,_bleft[0]=N+1,_bright[BlockNum+1]=-1;
static std::bitset<20001>ans[10][151];
static std::bitset<20001>tans,tsans;
for(register int k=0;k<K;k++)
{
for(register int i=1;i<=N;i++)
idx[k][i]=i;
_k=k,std::sort(&idx[k][1],&idx[k][N+1],_comp());
ans[k][0].reset(),ans[k][1].reset();
for(register int i=1;i<=N;i++)
{
y[k][i]=_y[k][idx[k][i]];
register int tbi=GetBlockPos(i),tbp=GetBlockPos(i-1);
yb[k][tbi]=_y[k][idx[k][i]];
if(tbi != tbp)
ans[k][tbi]=ans[k][tbp];
ans[k][tbi].set(idx[k][i]);
}
}
for(register int j=1;j<=M;j++)
{
for(register int k=0;k<K;k++)
{
register int tbpos=std::upper_bound(&yb[k][1],&yb[k][BlockNum+1],x[k][j]-1)-&yb[k][0];
tsans=ans[k][tbpos-1];
register int lpos=GetBlockLeft(tbpos),rpos=GetBlockRight(tbpos);
for(register int i=lpos;y[k][i]<x[k][j] && i<=rpos;i++)
tsans.set(idx[k][i]);
if(!k)
tans=tsans;
else
tans&=tsans;
}
PrintNum(tans.count());
}
}
return 0;
}