import java.io.*;
import java.util.*;

public class contest_pk_wa {

	class Edge {
		int from, to, c, f;
		Edge rev;

		public Edge(int from, int to, int c, int f) {
			this.from = from;
			this.to = to;
			this.c = c;
			this.f = f;
		}
	}

	void solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		int t = nextInt();
		int l = nextInt();

		int vCount = 1 + n + m + 1;
		@SuppressWarnings("unchecked")
		ArrayList<Edge>[] e = new ArrayList[vCount];
		for (int i = 0; i < vCount; i++) {
			e[i] = new ArrayList<contest_pk_wa.Edge>();
		}
		for (int i = 0; i < n; i++) {
			int k = nextInt();
			for (int j = 0; j < k; j++) {
				int to = nextInt() - 1;
				Edge a = new Edge(1 + i, 1 + n + to, 1, 0);
				e[1 + i].add(a);
				Edge b = new Edge(1 + n + to, 1 + i, 0, 0);
				e[1 + n + to].add(b);
				a.rev = b;
				b.rev = a;
			}
		}
		for (int i = 0; i < n; i++) {
			Edge a = new Edge(0, 1 + i, t / l, 0);
			Edge b = new Edge(1 + i, 0, 0, 0);
			e[0].add(a);
			e[1 + i].add(b);
			a.rev = b;
			b.rev = a;
		}
		for (int i = 0; i < m; i++) {
			Edge a = new Edge(1 + n + i, 1 + n + m, 1, 0);
			Edge b = new Edge(1 + n + m, 1 + n + i, 0, 0);
			e[1 + n + i].add(a);
			e[1 + n + m].add(b);
			a.rev = b;
			b.rev = a;
		}

		for (int i = 0; i < 1; i++) {
			while (dfs(0, e, new boolean[vCount]))
				;
			for (int j = 0; j < n; j++) {
				e[0].get(j).c++;
			}
		}

		int cTasks = 0;
		long fair = 0;
		for (int i = 0; i < n; i++) {
			cTasks += e[0].get(i).f;
			fair = fair + e[0].get(i).f * (e[0].get(i).f + 1) / 2 * l;
		}
		out.println(cTasks + " " + fair);
	}

	private boolean dfs(int v, ArrayList<Edge>[] e, boolean[] was) {
		if (was[v]) {
			return false;
		}
		was[v] = true;
		if (v == e.length - 1) {
			return true;
		}
		for (int i = 0; i < e[v].size(); i++) {
			if (e[v].get(i).f < e[v].get(i).c) {
				e[v].get(i).f++;
				e[v].get(i).rev.f--;

				if (dfs(e[v].get(i).to, e, was))
					return true;

				e[v].get(i).f--;
				e[v].get(i).rev.f++;
			}
		}
		return false;
	}

	BufferedReader br;
	StringTokenizer st;
	PrintWriter out;

	void run() {
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			br = new BufferedReader(new FileReader(new File("contest.in")));
			out = new PrintWriter("contest.out");
			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new contest_pk_wa().run();
	}

	String nextToken() throws IOException {
		while ((st == null) || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextToken());
	}

	double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(nextToken());
	}

	long nextLong() throws NumberFormatException, IOException {
		return Long.parseLong(nextToken());
	}
}
