// Arup Guha
// Solution to 2010 Arab Collegiate Programming Contest Problem F: World of Cubes
// Finished on 10/7/2013 (started on 9/24)

import java.util.*;

public class f {

	public static long[][] boxes;
	public static int n;
	public static long[] max;
	public static int[] mapMax;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		// Read in dimensions.
		n = stdin.nextInt();
		max = new long[3];
		for (int i=0; i<3; i++)
			max[i] = 2L*stdin.nextLong();
		int loop = 1;

		// Go through each case.
		while (n != 0) {

			// Get boxes.
			boxes = new long[n][3];
			for (int i=0; i<n; i++)
				for (int j=0; j<3; j++)
					boxes[i][j] = 2*stdin.nextLong();

			// Solve and output.
			mapMax = new int[3];
			System.out.println(loop+". "+solve());

			// Get next case.
			n = stdin.nextInt();
			for (int i=0; i<3; i++)
				max[i] = 2L*stdin.nextLong();
			loop++;
		}
	}

	// Run binary search from here.
	public static long solve() {

		long low = 2;
		long high = 2L*Math.max(max[0], Math.max(max[1], max[2]));

		while (low < high-2) {

			// We only want to try even mids...
			long mid = (low+high)/2;
			if (mid%2 == 1) mid++;

			// Typical binary search.
			if (canSolve(mid))
				high = mid;
			else
				low = mid+1;

		}

		// Since we cut out early, try this.
		while (!canSolve(low)) low++;
		return low/2L;
	}

	// Determines if setting the side length to side is good enough.
	public static boolean canSolve(long side) {

		int[][][] mapBoxes = getMapped(side);

		// Iterate through all distinct boxes on the x-y plane.
		for (int i=0; i<mapMax[0]-1; i++) {
			for (int j=0; j<mapMax[1]-1; j++) {

				// For each box in range, add in its z coverage.
				ArrayList<pair> zRanges = new ArrayList<pair>();
				for (int k=0; k<n; k++)
					if (in(mapBoxes[k], i, j))
						zRanges.add(new pair(mapBoxes[k][2][0], mapBoxes[k][2][1]));

				// Sort these.
				int len = zRanges.size()-1;
				Collections.sort(zRanges);

				if (zRanges.size() == 0) return false;

				// Not covering edges.
				if (zRanges.get(0).low > 0) return false;
				if (zRanges.get(len).high < mapMax[2]-1) return false;

				// Look for any gaps.
				for (int k=0; k<zRanges.size()-1; k++)
					if (zRanges.get(k).high < zRanges.get(k+1).low)
						return false;
			}
		}

		// Okay, if we get here.
		return true;
	}

	public static boolean in(int[][] array, int x, int y) {
		return array[0][0] <= x && array[0][1] > x && array[1][0] <= y && array[1][1] > y;
	}

	public static int[][][] getMapped(long side) {

		// Stores limits of boxes - with remapped coordinates.
		int[][][] ans = new int[n][3][2];

		// Get al mappings.
		HashMap[] map = new HashMap[3];
		for (int i=0; i<3; i++)
			map[i] = (HashMap<Long,Integer>)getMap(i, side);

		// Store remapped coordinates.
		for (int i=0; i<n; i++) {
			for (int j=0; j<3; j++) {
				ans[i][j][0] = (Integer)map[j].get(Math.max(boxes[i][j]-side/2L, 0L));
				ans[i][j][1] = (Integer)map[j].get(Math.min(boxes[i][j]+side/2L, max[j]));
			}
		}

		return ans;
	}

	public static HashMap<Long,Integer> getMap(int dim, long side) {

		ArrayList<Long> list = new ArrayList<Long>();
		HashSet<Long> chosen = new HashSet<Long>();

		// Must add in ends of the big box.
		list.add(0L);
		chosen.add(0L);
		list.add(max[dim]);
		chosen.add(max[dim]);

		// Go through each box.
		for (int i=0; i<n; i++) {

			// Add a new low boundary, if necessary.
			long low = boxes[i][dim] - side/2L;
			if (low < 0) low = 0;
			if (!chosen.contains(low)) {
				chosen.add(low);
				list.add(low);
			}

			// Add a new high boundary, if necessary.
			long high = boxes[i][dim] + side/2L;
			if (high > max[dim]) high = max[dim];
			if (!chosen.contains(high)) {
				chosen.add(high);
				list.add(high);
			}
		}

		// Sort.
		Collections.sort(list);

		// Store lookup table (reverse mapping).
		mapMax[dim] = list.size();
		HashMap<Long,Integer> map = new HashMap<Long,Integer>();
		for (int i=0; i<list.size(); i++)
			map.put(list.get(i), i);

		return map;
	}
}

class pair implements Comparable<pair> {

	public int low;
	public int high;

	public pair(int a, int b) {
		low = a;
		high = b;
	}

	// Important to break ties so we can sort a whole range properly.
	public int compareTo(pair other) {
		if (this.low != other.low)
			return this.low - other.low;
		return this.high - other.high;
	}
}