/*
JAVA program for ACORN
Summary: The program can be modeled as finding the longest path in a graph,
this is solved using dynamic programming. Complexity is O(TH).
*/

import java.util.*;

class ACORN {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
        int numCases = sc.nextInt();
        assert numCases > 0;
        while (numCases-- > 0) {
            ACORNs solver = new ACORNs();
            solver.solve(sc);
        }
        assert sc.nextInt() == 0;
    }	
}

class ACORNs {
	//C[i][j] is the number of acorns on tree i at height j
	int[][] C = new int[2000][2000];
	
	//M[i][j] is the maximum number of acorns that can be collected ending at tree i and height j
	int[][] M = new int[2000][2000];
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
        ACORNs solver = new ACORNs();
        solver.solve(sc);
	}

    void solve(Scanner sc) {
		int T = sc.nextInt();
		int H = sc.nextInt();
		int F = sc.nextInt();
		
		assert T >= 1 && T <= 2000;
		assert H >= 1 && H <= 2000;
		assert F >= 1 && F <= 500;
		
		//read in the input heights
		for (int i = 0; i < T; i++) {
			int q = sc.nextInt();
            assert q >= 0 && q <= 2000;
            for (int j = 0; j < q; j++) {
                int h = sc.nextInt();
				assert h >= 1 && h <= H;
				C[i][h]++;
			}
		}
		
		//compute the maximum acorns that can be collected using dynamic programming
		
		//initialization
		for (int t = 0; t < T; t++) {
			M[t][0] = C[t][0];
		}
		
		//recurrence, compute in increasing height
		for (int h = 1; h <= H; h++) {
			int maxLower = 0;
			for (int j = 0; j < T; j++) {
				int lower = (h - F >= 0) ? M[j][h - F] : 0;
				maxLower = Math.max(maxLower, lower);
			}
			
			for (int t = 0; t < T; t++) {
				// climb down
				M[t][h] = C[t][h] + Math.max(M[t][h - 1], maxLower);				
			}
		}		
		
		int maxNuts = 0;
		for (int t = 0; t < T; t++) {
			maxNuts = Math.max(maxNuts, M[t][H]);
		}
		
		System.out.println(maxNuts);
    }
}
		
