#include <stdio.h>
#include <string.h>
#include<functional>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 2005;
const int inf = 1<<30;
int n,cnt;
int dp[maxn];
struct node
{
int x,y,z;
}block[maxn];
bool cmp( node a,node b )
{
if( a.x == b.x )
if( a.y == b.y ) return a.z > b.z;
else return a.y < b.y;
else return a.x < b.x;
}
int GetDp( int n )
{
int ans = -inf;
memset( dp,0,sizeof(dp) );
for( int i = 1; i <= n; i ++ ){
dp[i] = block[i].z;
for( int j = 1; j < i; j ++ ){
if( (block[j].x < block[i].x && block[j].y < block[i].y) )
dp[i] = max( dp[i],dp[j] + block[i].z );
}
ans = max( ans,dp[i] );
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
int cas = 1,x,y,z;
while( scanf("%d",&n) != EOF,n )
{
cnt = 0;
for( int i = 1; i <= n; i ++ ){
scanf("%d%d%d",&x,&y,&z);
if( x >= y ) block[++cnt].x = x,block[cnt].y = y, block[cnt].z = z;
else block[++cnt].x = y,block[cnt].y = x, block[cnt].z = z;
if( y >= z ) block[++cnt].x = y, block[cnt].y = z, block[cnt].z = x;
else block[++cnt].x = z, block[cnt].y = y, block[cnt].z = x;
if( z >= x ) block[++cnt].x = z, block[cnt].y = x, block[cnt].z = y;
else block[++cnt].x = x,block[cnt].y = z, block[cnt].z = y;
}
sort( block+1,block+cnt+1,cmp );
int k = 1;
for( int i = 2; i <= cnt; i ++ ){
if( block[i].x != block[i-1].x || block[i].y != block[i-1].y ){
block[++k].x = block[i].x;
block[k].y = block[i].y;
block[k].z = block[i].z;
}
}
printf("Case %d: maximum height = %d\n",cas++,GetDp( k ));
}
return 0;
}