#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <functional>
#include <queue>
using namespace std;
const int MAX_V = 100010;
typedef int Capacity;
typedef int Cost;
const int inf = 1 << 28;

struct Edge {
	int dst;
	Capacity cap, cap_orig;
	Cost cost;
	int revEdge; bool isRev;
	Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
		:dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {
	}
};


struct PrimalDual {
	int n;
	vector<vector<Edge> > g;
	vector<int> top;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // ?????????
		g[src].push_back(Edge{ dst, cap, cost, (int)g[dst].size(), false });
		g[dst].push_back(Edge{ src, 0, -cost, (int)g[src].size() - 1, true });
	}
	Cost solve(int s, int t, int f) {
		Cost res = 0;
		static Cost h[MAX_V], dist[MAX_V];
		static int prevv[MAX_V], preve[MAX_V];

		fill(h, h + n, 0);
		if(top.size()) {
			assert(top.size() == n);
			for(int i = 0; i < n; i++) {
				int v = top[i];
				for(int i = 0; i < g[v].size(); i++) {
					Edge& e = g[v][i];
					if(e.cap == 0) continue;
					int u = e.dst;
					h[u] = min(h[u], h[v] + e.cost);
				}
			}
		}

		while(f > 0) {
			typedef pair<Cost, int> pcv;
			priority_queue<pcv, vector<pcv>, greater<pcv> > q;
			for(int i = 0; i < n; i++) {
				dist[i] = inf;
			}
			dist[s] = 0;
			q.push(pcv(0, s));
			while(q.size()) {
				pcv p = q.top(); q.pop();
				int v = p.second;
				if(dist[v] < p.first) continue;
				for(int i = 0; i < g[v].size(); i++) {
					Edge &e = g[v][i];
					if(e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.push(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(dist[t] == inf) {
				return -1;
			}
			for(int v = 0; v < n; v++) {
				h[v] += dist[v];
			}
			// s-t ????????????????????£??????????????????
			int 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.revEdge].cap += d;
			}
		}
		return res;
	}
	// ??????????????????=???????????????-?????¨??????????????¨???
	void view() {
		for(int i = 0; i < g.size(); i++) {
			for(int j = 0; j < g[i].size(); j++) {
				if(!g[i][j].isRev) {
					Edge& e = g[i][j];
					printf("%3d->%3d (flow:%d)\n", i, e.dst, e.cap_orig - e.cap);
				}
			}
		}
	}
};



const int INF = 1 << 28;
int cost[8][8];
int req[200][8];
int bag[200][8];
int dp[9][6562][9];
int sum[6562];

vector<int> f(int n) {
	vector<int> ret(8);
	for(int i = 0; i < 8; i++) {
		ret[i] = n % 3;
		n /= 3;
	}
	return ret;
}

int g(vector<int> n) {
	int ret = 0;
	for(int i = 7; i >= 0; i--) {
		ret = ret * 3 + n[i];
	}
	return ret;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int D, K, L, M, N, P;
	while(cin >> D >> K >> L, D | K | L) {
		for(int i = 0; i < D; i++) {
			for(int j = 0; j < K; j++) {
				cin >> cost[i][j];
			}
		}
		cin >> M >> N >> P;
		for(int i = 0; i < M; i++) {
			for(int j = 0; j < K; j++) {
				cin >> req[i][j];
			}
		}
		for(int i = 0; i < P; i++) {
			for(int j = 0; j < K; j++) {
				cin >> bag[i][j];
			}
		}

		fill((int*)begin(dp), (int*)end(dp), INF);
		dp[0][0][0] = 0;
		for(int i = 0; i < D; i++) {// ?????\???
			if(i != 0) {
				for(int j = 0; j < 6561; j++) {// ??¶???
					for(int k = 0; k <= L; k++) {
						dp[i][j][0] = min(dp[i][j][0], dp[i - 1][j][k]);
					}
				}
			}
			for(int j = 0; j < 6561; j++) {// ??¶???
				vector<int> s = f(j);
				for(int k = 0; k <= L; k++) { // ???????????£???
					if(dp[i][j][k] == INF) continue;
					for(int l = 0; l < K; l++) { // ????????¨???
						for(int m = 1; k + m <= L; m++) {// ????????????
							if(s[l] + m > 2) continue;
							s[l] += m;
							int nj = g(s);
							dp[i][nj][k + m] = min(dp[i][nj][k + m], dp[i][j][k] + cost[i][l] * m);
							s[l] -= m;
						}
					}
				}
			}
		}

		fill((int*)begin(sum), (int*)end(sum), INF);
		for(int i = 0; i < D; i++) {
			for(int j = 0; j < 6561; j++) {
				for(int k = 0; k <= L; k++) {
					sum[j] = min(sum[j], dp[i][j][k]);
				}
			}
		}

		PrimalDual pd(M + P + 1 + 2);
		int S = M + P + 1, T = S + 1;
		for(int m = 0; m < M; m++) {
			for(int p = 0; p < P; p++) {
				bool flag = true;
				vector<int> s(8);
				for(int k = 0; k < K; k++) {
					s[k] = req[m][k] - bag[p][k];
					if(s[k] < 0) {
						flag = false;
						break;
					}
				}
				if(flag) {
					int c = sum[g(s)];
					pd.add_edge(m, M + p, 1, c);
				}
			}
			vector<int> s(8);
			for(int k = 0; k < K; k++) {
				s[k] = req[m][k];
			}
			if(sum[g(s)] != INF) {
				pd.add_edge(m, M + P, 1000000, sum[g(s)]);
			}
			pd.add_edge(S, m, 1, 0);
		}
		for(int p = 0; p < P; p++) {
			pd.add_edge(M + p, T, 1, 0);
		}
		pd.add_edge(M + P, T, 1000000, 0);
		cout << pd.solve(S, T, N) << endl;
	}
}

Measured memory_bytes: 7604