Go: package main

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

const MaxW = 1000
const MaxN = 1000

type Tuple struct {
	Value  int
	Weight int
}

func nextLine(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func solve(w int, n int, vws []Tuple) Tuple {
	var dp [MaxN + 1][MaxW + 1]int

	for i := 0; i < n; i++ {
		for j:= w; j > 0; j-- {
			if j < vws[i].Weight {
				dp[i + 1][j] = dp[i][j]
			} else {
				dp[i + 1][j] = int(math.Max(float64(dp[i][j]), float64(dp[i][j - vws[i].Weight] + vws[i].Value)))
			}
		}
	}

	maxValue := dp[n][w]
	minWeight := w

	for j := w - 1; j > 0; j-- {
		if maxValue == dp[n][j] {
			minWeight = j
		} else {
			break
		}
	}

	return Tuple{Value: maxValue, Weight: minWeight}
}

func main() {
	var sc = bufio.NewScanner(os.Stdin)
	index := 1
	for {
		var w, n int
		w, _ = strconv.Atoi(nextLine(sc))
		if w == 0 {
			return
		}
		n, _ = strconv.Atoi(nextLine(sc))

		vws := make([]Tuple, n, n)
		for i := 0; i < n; i++ {
			array := strings.Split(nextLine(sc), ",")
			v, _ := strconv.Atoi(array[0])
			w, _ := strconv.Atoi(array[1])
			vws[i] = Tuple{Value: v, Weight: w}
		}

		t := solve(w, n, vws)
		fmt.Printf("Case %d:\n", index)
		fmt.Println(t.Value)
		fmt.Println(t.Weight)
		index++
	}
}

C++: #include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <cmath>
#include <cstring>

using namespace std;

#define pb push_back
#define rep(i,n) for(int i=0;i<(n);i++)
#define REP(i,j,k) for(int i=j;i<(k);i++)
#define foreach(T,c,i) for(T::iterator i=c.begin();i!=c.end();i++)
typedef vector<int> Array;
typedef vector<Array> Mat;
const int INF = 99999999;
int N,W,a,b,ans_num=0;
const int MAX_N = 1000;
const int MAX_W = 1000;
int dp[MAX_N+1][MAX_W+1];
Array v,w;

void solve()
{
	rep(i,N) rep(j,W){
		if(j<w[i]){
			dp[i+1][j] = dp[i][j];
		}else{
			dp[i+1][j] = max(dp[i][j],dp[i][j-w[i]]+v[i]);
		}
	}
	cout << dp[N][W-1] << endl;
	int MIN = INF;
	rep(i,N+1)rep(j,W){
		if(dp[i][j]==dp[N][W-1]) MIN = min(MIN,j);
	}
	cout << MIN << endl;
	
}

		
int main(){
	while(1){
		cin >> W >> N;
		if(W==0) return 0;
		ans_num++;
		memset(dp,0,sizeof(dp));
		v.clear();
		w.clear();
		rep(i,N){
			scanf("%d,%d",&a,&b);
			v.pb(a);
			w.pb(b);
		}


		cout << "Case " << ans_num << ":" << endl;
		solve();

	}	
	return 0;	
}

C++: 
//include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>

using namespace std;

//conversion
//------------------------------------------
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

//math
//-------------------------------------------
template<class T> inline T sqr(T x) {return x*x;}

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

//repetition
//------------------------------------------
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int DX[] = {0, 1, 0, -1};
const int DY[] = {-1, 0, 1, 0};


//clear memory
#define CLR(a) memset((a), 0 ,sizeof(a))

//debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

int main(int argc, char const *argv[])
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	int w, n;
	int index = 1;
	while(true){
		cin >> w;
		if(w == 0) break;
		cin >> n;
		VVI dp(n + 1, VI(w + 1));
		char comma;
		VI values(n);
		VI weights(n);
		REP(i, n){
			cin >> values[i] >> comma >> weights[i];
		}
		REP(i, n){
			REP(j, w + 1){
				if(j + weights[i] <= w){
					int &value = dp[i + 1][j + weights[i]];
					 value = max(value, values[i] + dp[i][j]);
				}
				dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]);
			}
		}
		int weight = max_element(ALL(dp[n])) - dp[n].begin();
		int value_sum = dp[n][weight]; 
		cout << "Case " << index << ":" << endl;
		cout << value_sum << endl;
		cout << weight << endl;

		index++;
	}



	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <cmath>
#include <random>
using namespace std;

#define REP(i,n) for(int (i)=0; (i)<(n); (i)++)
#define FOR(i,a,b) for(int (i)=(a); (i)<(b); (i)++)

int caseId = 1;

void solve42(int W) {
    cout << "Case " << caseId << ":" << endl;
    int N;
    cin >> N;
    int dp[1001] = {0}; // dp[i]: maxvalue under weight i
    REP(i,N) {
        int v, w;
        scanf("%d,%d", &v, &w);
        for(int j = W; j >= w; j--) {
            dp[j] = max(dp[j], dp[j-w] + v);
        }
    }
    int value = 0, weight = 0;
    REP(i,W) {
        if (value < dp[i]) {
            value = dp[i];
            weight = i;
        }
    }
    cout << value << endl << weight << endl;
}

int main() {
    int W;
    while (cin >> W, W) {
        solve42(W);
        caseId++;
    }
    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main(){
	int W,N;
	int C=0;
	while(cin>>W){
		if(!W)break;
		cin>>N;
		int v[1000],w[1000],SUMW;
		for(int i=0;i<N;++i) scanf("%d,%d",&v[i],&w[i]);
		short DP[1001][1001];
		for(int i=0;i<=N;++i) DP[0][i]=0;
		for(int i=1;i<=N;++i){
			for(int j=0;j<=W;++j){
				if(w[i]>j){//入らない時
					DP[i][j]=DP[i-1][j];
				}else{//入る時
					DP[i][j]=max((int)(DP[i-1][j]),(int)(DP[i-1][j-w[i]]+v[i]));
				}
			}
		}
		SUMW=W;
		for(int j=W;j>=1;--j) for(int i=N;i>=1;--i) if(DP[N][W]==DP[i][j])SUMW=j;
		cout<<"case "<<++C<<"\n";
		cout<<DP[N][W]<<"\n"<<SUMW<<"\n";
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct treasure{
	int value;
	int weight;
};
bool comp(treasure t1, treasure t2){
	if(t1.weight <= t2.weight) return true;
	else return false;
}

int main(){
	int w;
	const int maxw = 1000;
	int count = 1;
	while(cin >> w){
		if(w == 0) break;
		int n;
		int cost[maxw + 1];
		int best[maxw + 1];
		for(int i = 0; i <= maxw; i++){
			cost[i] = 0;
			best[i] = 0;
		}
		vector<treasure> treasures;
		cin >> n;
		for(int i = 0; i < n; i++){
			treasure t;
			char c;
			cin >> t.value >> c >> t.weight;
			treasures.push_back(t);
		}
		sort(treasures.begin(), treasures.end(), comp);
		for(int j = 0; j < n; j++){
			for(int k = 1; k <= w; k++)
				if(k >= treasures[j].weight)
					if(cost[k] < cost[k - treasures[j].weight] + treasures[j].value)
					{
						cost[k] = cost[k - treasures[j].weight] + treasures[j].value;
						best[k] = j;
					}
		}
		cout << "Case" << " " << count++ << ":" << endl;
		for(;(w>0) && (cost[w] == cost[w-1]); w--);
		cout << cost[w] << endl;
		int total = 0;
		for(int l = w; l - treasures[best[l]].weight >= 0;){
			if(l - treasures[best[l]].weight >= 0){
				total += treasures[best[l]].weight;
				l -= treasures[best[l]].weight;
			}
		}
		cout << total << endl;
	}
	return 0;
}