import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class _2112 {
static int T, D, W, K;
static int[][] map;
static int[][] otherMap;
static int min;
static boolean[] isSelected;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
T = Integer.parseInt(br.readLine());
for (int t = 1; t <= T; t++) {
st = new StringTokenizer(br.readLine());
D = Integer.parseInt(st.nextToken());
W = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new int[D][W];
otherMap = new int[D][W];
isSelected = new boolean[D];
for (int i = 0; i < D; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < W; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
otherMap[i][j] = map[i][j];
}
}
min = D;
subSet(0);
System.out.println("#" + t + " " + min);
}
}
private static void subSet(int depth) {
if (depth == D) {
inject(0, 0);
reset();
return;
}
isSelected[depth] = true;
subSet(depth + 1);
isSelected[depth] = false;
subSet(depth + 1);
}
private static void reset() {
for (int i = 0; i < D; i++) {
for (int j = 0; j < W; j++) {
map[i][j] = otherMap[i][j];
}
}
}
private static void inject(int injectionCnt, int idx) {
if (injectionCnt >= min) return;
if (idx == D) {
if (isPassed()) min = injectionCnt;
return;
}
if (isSelected[idx]) {
Arrays.fill(map[idx], 0);
inject(injectionCnt + 1, idx + 1);
Arrays.fill(map[idx], 1);
inject(injectionCnt + 1, idx + 1);
} else {
inject(injectionCnt, idx + 1);
}
}
private static boolean isPassed() {
for (int i = 0; i < W; i++) {
int start = 0, end = 1;
int len = 1;
while (end < D) {
if (map[start][i] == map[end][i]) {
end++;
} else {
start = end;
end++;
}
len = Math.max(len, end - start);
if (len >= K) break;
}
if (len < K) return false;
}
return true;
}
}