#include <iostream>
#include <numeric>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <memory>
#include <string>
#include <vector>
#include <cctype>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <math.h>

using namespace std;

#define VI vector<int>
#define VS vector<string>
#define int64 long long
#define INF 1000000000
#define PB push_back
#define SZ(a) (int)a.size()
#define FOR(i, n) for (int i = 0; i < (int)(n); i++)
#define FORR(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define ALL(a) a.begin(), a.end()
#define MP make_pair
#define PII pair<int, int>
#define PII64 pair<int64, int64>

int ri(){ int t; scanf("%d", &t); return t;};

int n;

int X, Y, Z;

int xo[64], yo[64], zo[64];
int xl[64], yl[64], zl[64];
int xu[64], yu[64], zu[64];

int64 res;

inline int insideXYZ(int x, int y, int z)
{
	return
		x >= 0 && x <= X &&
		y >= 0 && y <= Y &&
		z >= 0 && z <= Z;
}

inline int insideK(int x, int y, int z, int k)
{
	return
		x >= xl[k] && x <= xu[k] &&
		y >= yl[k] && y <= yu[k] &&
		z >= zl[k] && z <= zu[k];
}

inline int inside(int x, int y, int z)
{
	if (!insideXYZ(x, y, z))
		return 1;
	FOR(i, n)
		if (insideK(x, y, z, i))
			return 1;
	return 0;
}

int checkPoint(int x, int y, int z)
{
	//for (int dx = -1; dx <= 1; dx++)
		//for (int dy = -1; dy <= 1; dy++)
			//for (int dz = -1; dz <= 1; dz++)
				//if (!inside(x + dx, y + dy, z + dz))
					//return 0;
	if (!inside(x + 1, y + 1, z + 1))
		return 0;
	if (!inside(x + 1, y + 1, z - 1))
		return 0;
	if (!inside(x + 1, y - 1, z + 1))
		return 0;
	if (!inside(x + 1, y - 1, z - 1))
		return 0;
	if (!inside(x - 1, y + 1, z + 1))
		return 0;
	if (!inside(x - 1, y + 1, z - 1))
		return 0;
	if (!inside(x - 1, y - 1, z + 1))
		return 0;
	if (!inside(x - 1, y - 1, z - 1))
		return 0;
	return 1;
}

int checkCuboid(int xl, int yl, int zl, int xu, int yu, int zu)
{
	if (!checkPoint(xl, yl, zl))
		return 0;
	if (!checkPoint(xl, yl, zu))
		return 0;
	if (!checkPoint(xl, yu, zl))
		return 0;
	if (!checkPoint(xl, yu, zu))
		return 0;
	if (!checkPoint(xu, yl, zl))
		return 0;
	if (!checkPoint(xu, yl, zu))
		return 0;
	if (!checkPoint(xu, yu, zl))
		return 0;
	if (!checkPoint(xu, yu, zu))
		return 0;
	return 1;
}

int can(int64 R)
{
	FOR(i, n)
	{
		xl[i] = max(xo[i] - R, 0LL);
		yl[i] = max(yo[i] - R, 0LL);
		zl[i] = max(zo[i] - R, 0LL);
		xu[i] = min(xo[i] + R, (int64)X);
		yu[i] = min(yo[i] + R, (int64)Y);
		zu[i] = min(zo[i] + R, (int64)Z);
	}
	if (!checkCuboid(0, 0, 0, X, Y, Z))
		return 0;
	FOR(i, n)
		if (!checkCuboid(xl[i], yl[i], zl[i], xu[i], yu[i], zu[i]))
			return 0;
	FOR(i, n) FOR(j, n)
	{
		int xL = max(xl[i], xl[j]);
		int xR = min(xu[i], xu[j]);
		if (xL > xR)
			continue;
		int yL = max(yl[i], yl[j]);
		int yR = min(yu[i], yu[j]);
		if (yL > yR)
			continue;
		int zL = max(zl[i], zl[j]);
		int zR = min(zu[i], zu[j]);
		if (zL > zR)
			continue;
		if (!checkCuboid(xL, yL, zL, xR, yR, zR))
			return 0;
	}
	return 1;
}

void solve()
{
	int64 L = 1, R = max(max(X, Y), Z);
	while (R - L > 1)
	{
		int64 M = (R + L) / 2;
		if (can(M))
			R = M;
		else
			L = M + 1;
	}
	L = min(L, R);
	while (!can(L)) L++;
	res = L;
}

int main()
{

	//freopen("/home/alt/1", "r", stdin);

	int nt = 0;
	while (n = ri())
	{
		X = ri();
		Y = ri();
		Z = ri();
		X *= 2;
		Y *= 2;
		Z *= 2;
		FOR(i, n)
		{
			xo[i] = ri() * 2;
			yo[i] = ri() * 2;
			zo[i] = ri() * 2;
		}
		solve();
		printf("%d. %lld\n", ++nt, res);
	}
	return 0;
}

