#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(__typeof((X).begin()) it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)x.size())

using namespace std;

struct timer{
	time_t start;
	timer(){start=clock();}
	~timer(){cerr<<1.*(clock()-start)/CLOCKS_PER_SEC<<" secs"<<endl;}
};

typedef istringstream iss;
typedef long long ll;
typedef pair<int,int> pi;
typedef stringstream sst;
typedef vector<int> vi;

#define MN 10010
struct edge{int to,rev;ll cap,cost;
edge(int to,ll cap,ll cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}};
vector<edge> g[MN];
int V,prevv[MN],preve[MN];
ll h[MN],dist[MN];

void add_edge(int from,int to,ll cap,ll cost){
	g[from].pb(edge(to,cap,cost,sz(g[to])));
	g[to].pb(edge(from,0,-cost,sz(g[from])-1));
};

typedef pair<ll,int> pli;

ll min_cost_flow(int s,int t,ll f){
	ll res=0;
	fill(h,h+V,0);
	while(f>0){
		priority_queue<pli,vector<pli>,greater<pli> > Q;
		fill(dist,dist+V,INF*INF);
		dist[s]=0;
		Q.push(mp(0,s));
		while(sz(Q)){
			pli p=Q.top();
			Q.pop();
			int v=p.second;
			if(dist[v]<p.first)continue;
			rep(i,sz(g[v])){
				edge& e=g[v][i];
				if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
					dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
					prevv[e.to]=v;
					preve[e.to]=i;
					Q.push(mp(dist[e.to],e.to));
				}
			}
		}
		if(dist[t]==INF*INF)return -1;
		rep(v,V)h[v]+=dist[v];
		ll d=f;
		for(int v=t;v!=s;v=prevv[v]){
			d=min(d,g[prevv[v]][preve[v]].cap);
		}
		f-=d;
		res+=d*h[t];
		for(int v=t;v!=s;v=prevv[v]){
			edge& e=g[prevv[v]][preve[v]];
			e.cap-=d;
			g[v][e.rev].cap+=d;
		}
	}
	return res;
}

int D,K,L,M,N,P;
int c[9][9],r[211][9],t[211][9];
int rmask[211],tmask[211];
int pw3[9];
int get[7000][9];
int dp[9][9][9][7000];

int f(int day,int cur,int rest,int mask){
	int& res=dp[day][cur][rest][mask];
	if(res!=-1)return res;
	
	if(mask==0)return res=0;
	if(day==D)return res=INF;
	if(cur==K)return res=f(day+1,0,L,mask);
	res=INF;
	rep(i,min(rest,get[mask][cur])+1){
		res=min(res,i*c[day][cur] + f(day,cur+1,rest-i,mask-i*pw3[cur]));
	}
	return res;
}

int main(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	
	pw3[0]=1;
	rep2(i,1,9)pw3[i]=pw3[i-1]*3;
	rep(i,pw3[8]){
		rep(j,8)get[i][j] = i/pw3[j]%3;
	}
	
	while(cin>>D>>K>>L && D){
		rep(i,D)rep(j,K)cin>>c[i][j];
		cin>>M>>N>>P;
		int S=M+P+1,T=S+1;
		V=T+1;
		rep(i,V)g[i].clear();
		fill(rmask,rmask+M,0);
		fill(tmask,tmask+P,0);
		rep(i,M)rep(j,K){
			cin>>r[i][j];
			rmask[i] += pw3[j]*r[i][j];
		}
		rep(i,P)rep(j,K){
			cin>>t[i][j];
			tmask[i] += pw3[j]*t[i][j];
		}
		
		memset(dp,-1,sizeof(dp));
		rep(i,M) add_edge(S,i,1,0);
		rep(i,P) add_edge(M+i,T,1,0);
		add_edge(M+P,T,INF,0);
		
		rep(i,M)rep(j,P+1){
			if(j==P){
				add_edge(i,M+j,INF,f(0,0,L,rmask[i]));
			}
			else{
				rep(k,K){
					if(r[i][k] < t[j][k]){
						goto fail;
					}
				}
				add_edge(i,M+j,1,f(0,0,L,rmask[i]-tmask[j]));
				fail:;
				/*
				int mask=rmask[i];
				rep(k,K){
					mask -= pw3[k] * min(get[rmask[i]][k],get[tmask[j]][k]);
				}
				add_edge(i,M+j,1,f(0,0,L,mask));
				*/
			}
		}
		ll ans=min_cost_flow(S,T,N);
		cout<<(ans>=INF?-1:ans)<<endl;
	}
}

Measured memory_bytes: 24380