package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var pkgWeights []int64

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		pkgWeights = append(pkgWeights, int64(mustAtoi(strings.ToLower(scanner.Text()))))
	}
	// Sort the weights, in the case of our input, no need.
	totalWeight := weighPackages(pkgWeights)
	// For Part 1:
	//splitWeight := totalWeight / 3
	// For Part 2:
	splitWeight := totalWeight / 4
	fmt.Printf("Balanced at %d\n", splitWeight)
	// Now find the fewest number of packages that are that weight
	result := tryPackages([]int64{}, pkgWeights, splitWeight)
	fmt.Println("*** RESULT ***")
	//result = makeUnique(result)
	lowestQE := int64(-1)
	shortest := -1
	for i := range result {
		if len(result[i]) <= shortest || shortest == -1 {
			fmt.Print(result[i])
			fmt.Printf(" L:%d", len(result[i]))
			fmt.Printf(" QE:%d\n", getQE(result[i]))
			shortest = len(result[i])
			if getQE(result[i]) < lowestQE || lowestQE == -1 {
				lowestQE = getQE(result[i])
			}
		}
	}
	fmt.Println()
	fmt.Printf("%d\n", lowestQE)
}

func tryPackages(pkgs []int64, rem []int64, targ int64) [][]int64 {
	// Go through all packages in 'rem' and find the combination
	// That results in the least total number of packages
	var findRet [][]int64
	fewest := -1
	if len(pkgs) > fewest && fewest != -1 {
		return findRet
	}
	for i := len(rem) - 1; i >= 0; i-- {
		t := targ - weighPackages(pkgs)
		if rem[i] <= t {
			tryPkgs := append(pkgs, rem[i])
			if weighPackages(tryPkgs) == targ {
				//if len(tryPkgs) <= fewest || fewest == -1 {
				findRet = append(findRet, tryPkgs)
				//	fewest = len(tryPkgs)
				//}
			}
			// Not there yet... Recurse
			rem = rem[:i]
			res := tryPackages(tryPkgs, rem, targ)
			for i := range res {
				if weighPackages(res[i]) == targ {
					//if len(res[i]) <= fewest || fewest == -1 {
					findRet = append(findRet, res[i])
					//	fewest = len(res[i])
					//}
				}
			}
		}
	}
	return findRet
}

func getQE(pkgs []int64) int64 {
	var totalQE int64
	for i := range pkgs {
		if totalQE == 0 {
			totalQE = int64(pkgs[i])
		} else {
			totalQE = totalQE * int64(pkgs[i])
		}
	}
	return totalQE
}

func weighPackages(pkgs []int64) int64 {
	var totalWeight int64
	for i := range pkgs {
		totalWeight += pkgs[i]
	}
	return totalWeight
}

func makeUnique(s [][]int64) [][]int64 {
	var ret [][]int64
	for i := range s {
		var found bool
		// Check if s[i] is already in ret
		for j := range ret {
			if isSame(ret[j], s[i]) {
				found = true
				break
			}
		}
		if !found {
			ret = append(ret, s[i])
		}
	}
	return ret
}

func isSame(s1 []int64, s2 []int64) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i := range s1 {
		if s1[i] != s2[i] {
			return false
		}
	}
	return true
}

func itoa(i int) string {
	return strconv.Itoa(i)
}

func mustAtoi(s string) int {
	var i int
	var err error
	if i, err = strconv.Atoi(s); err != nil {
		fmt.Println("Tried to atoi " + s)
		os.Exit(1)
	}
	return i
}
