#include #include #include #include #include #include #include #include #include #include #include #include using namespace std; int N, Len, Use[14], CP[400]; vector Team[3]; struct Num{ int v, n; }; vector Vect; bool check_connection_point(){ int a = Team[0].size(), b = Team[1].size(), c = Team[2].size(); if(!(a >= 2 && b >= 2 && c >= 2)){ return false; } int index[3][11]; bool ok; for(int i = 0;i < 11;i++){ index[0][i] = index[1][i] = index[2][i] = i; } do{ do{ do{ ok = true; memset(CP, 0, sizeof(CP)); for(int i = 0;i < 3 && ok;i++){ vector& T = Team[i]; int length = 0; for(int s = 0;s < (int)T.size();s++){ int v = T[index[i][s]]; if(length != 0){ if(CP[length] == 0){ CP[length] = 1; } else{ ok = false; break; } } length += v; } } if(ok) return true; }while(next_permutation(index[2], index[2] + c)); for(int i = 0;i < 11;i++){ index[2][i] = i; } }while(next_permutation(index[1], index[1] + b)); for(int i = 0;i < 11;i++){ index[1][i] = i; } }while(next_permutation(index[0], index[0] + a)); return false; } int dfs(int team, int len, int num){ if(len == Len){ if(team == 2){ if(check_connection_point()){ return 1; } else{ return 0; } } else{ return dfs(team + 1, 0, 0); } } int newLen, length, ret, size = Vect.size(); for(int n = num;n < size;){ length = Vect[n].v; if(Vect[n].n > 0){ newLen = len + length; if(newLen > Len){ n++; continue; } else{ Vect[n].n--; Team[team].push_back(length); ret = dfs(team, newLen, n); if(ret == 1){ return 1; } else{ Vect[n].n++; Team[team].pop_back(); n++; continue; } } } else{ n++; continue; } } return 0; } void _print(){ for(int i = 0;i < 3;i++){ for(int j = 0;j < (int)Team[i].size();j++){ printf("%d ", Team[i][j]); } puts(""); } } int main(){ int re = 1, Stick[13], val; int sumLen, maxLen, minLen, ok; while(scanf("%d", &N) && N != 0){ sumLen = ok = 0; Team[0].clear(); Team[1].clear(); Team[2].clear(); Vect.clear(); memset(Use, 0, sizeof(Use)); for(int i = 0;i < N;i++){ scanf("%d", &val); Stick[i] = val; sumLen += val; } sort(Stick, Stick + N, greater()); int prev = 0; for(int i = 0;i < N;i++){ val = Stick[i]; if(val != prev){ Num num; num.v = val; num.n = 1; Vect.push_back(num); prev = val; } else{ Vect[Vect.size() - 1].n++; } } maxLen = sumLen / 3; minLen = Stick[N - 1] + Stick[N - 2]; for(Len = maxLen;Len >= minLen;Len--){ if(dfs(0, 0, 0)){ ok = 1; //_print(); printf("Case %d: %d\n", re++, Len); break; } } if(ok == 0){ printf("Case %d: %d\n", re++, 0); } } return 0; }