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 <iomanip>
#include <cassert>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <map>
#include <bitset>
#include <sstream>
#include <istream>
#include <cmath>
#include <cstdio>

using namespace std;

#define vci vector<int>
#define vcs vector<string>
#define pb push_back
#define sz size()
#define mapii map<int, int>
#define mapci map<char, int>
#define mapsi map<string, int>
#define all(x) x.begin(), x.end()
#define minit(a, i) memset(a, i, sizeof(a));

#define for_(i, a, b) for (int i=(int)a; i<(int)b; i++)
#define for_d(i, a, b) for (int i=(int)a-1; i>=b; i--)
#define for_r(i, a, b, c) for (int i=(int)a; i<(int)b; i += c)
#define for_dr(i, a, b, c) for (int i=(int)a-1; i>=b; i -= c)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

typedef long long ll;

const int iINF = 2147483647;
const ll lINF = 9223372036854775807;

template <class T> inline void dbg(T t) { cout << t << endl; }



int dp[2][10000010];

int main() {
	int casenum = 0;
	int W, n;
	
	while (1) {
		cin >> W;
		if (W==0) break;
		
		casenum++;
		
		cin >> n;
		vci v(n), w(n); char c;
		for_(i, 0, n) cin >> v[i] >> c >> w[i];
		
		minit(dp, 0);
		
		dp[0][w[0]] = v[0];
		for_(i, 1, n) {
			int now = i%2, nxt = (i+1)%2;
			for_(j, 0, W+1) {
				if (j+w[i]<=W) {
					dp[now][j+w[i]] = max(dp[now][j+w[i]], dp[nxt][j] + v[i]);
				}
			}
		}
		
		int maxv = 0, maxw = 0;
		for_(j, 0, W+1) {
			if (maxv < dp[(n+1)%2][j]) {
				maxv = dp[(n+1)%2][j];
				maxw = j;
			}
		}
		
		cout << "Case " << casenum << ":" << endl;
		cout << maxv << endl << maxw << endl;
	}
	
	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define FOR(I,F,N) for(int I = F; I < (int)(N); I++)
#define rep(i, n) FOR(i, 0, n)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 28)

template<typename T>
void remove(vector<T>& vector, unsigned int index){
vector.erase(vector.begin() + index);
}

typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

int W, N;
int tres[1001];
int weig[1001];
int maxW, maxV;
map<P, int> dp;

void dfs(int weight, int value, int index){
	if(weight > W)return;
	if(dp[P(weight,index)]>value)return;
	dp[P(weight,index)] = value;
	if(index == N){
		if(maxV < value){
			maxW = weight;
			maxV = value;
		}else if(maxV == value){
			if(maxW > weight){
				maxW = weight;
				maxV = value;
			}
		}
		return;
	}

	dfs(weight, value, index+1);
	dfs(weight+weig[index], value+tres[index], index+1);
}


int main(void){
	int cnt = 0;
	while(cin >> W, W){
		cnt++;
		cin >> N;
		maxW = 0;
		maxV = 0;
		// fill_n(tres, 1001, 0);
		// fill_n(weig, 1001, 0);
		//fill_n(*dp, 1001*1001, -1);
		dp.clear();

		rep(i,N){
			int n, w;
			scanf("%d,%d", &n, & w);
			tres[i] = n;
			weig[i] = w;
		}

		dfs(0,0,0);
		cout << "Case " << cnt << ":" << endl;
		cout << maxV << endl << maxW << endl;
	}

	return 0;
}



int StrToInt(string s){
	stringstream ss;
	ss << s;
	int val;
	ss >> val;
	return val;
}
string IntToStr(int i){
	stringstream ss;
	ss << i;
	return ss.str();
}

C++: #include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <list>
#include <map>

using namespace std;

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

int maxm;
int supw;
int vs[SUPmaxm];
int wos[SUPmaxm];
int dp[SUPmaxm][SUPsupw]; //m ika no item tukatte, w ika no omomi de, sum v no max
int rev,rew;

void solve(){
	rev=0;
	rew=SUPsupw;
	FOR(m,0,maxm+1) FOR(w,0,supw) dp[m][w]=0;
	FOR(m,1,maxm+1){
		FOR(w,0,supw){
			if(w<wos[m]) dp[m][w] = dp[m-1][w];
			else dp[m][w] = max(dp[m-1][w],dp[m-1][w-wos[m]]+vs[m]);
			if(dp[m][w]>rev||(dp[m][w]==rev&&w>rew)){rev=dp[m][w];rew=w;}
		}
	}
}

int main(){
	for(int casei=1;true;++casei){
		scanf("%d",&supw);			if(!supw) return 0;
		scanf("%d",&maxm);
		FOR(m,1,maxm+1) scanf("%d,%d",vs+m,wos+m);
		solve();
		printf("Case %d:\n%d\n%d\n",casei,rev,rew);
	}
}

C++: #include<bits/stdc++.h>
using namespace std;
int wait[1000],value[1000],Wa=0,wain;
int Power(int n)
{
    int num=1;
    for(int i=0;i<n;i++)num*=10;
    return num;
}
int serch(int n,int maxe,int now,int wai)
{
    int va,val=0;
    if(now==n)return 0;
    for(int i=now;i<n;i++){
        if(wai+wait[i]<maxe){
            Wa=wai+wait[i];
            va=serch(n,maxe,i+1,wai+wait[i])+value[i];
            if(va>val){
                val=va;
                wain=Wa;

            }
            else if(va==val&&Wa<wain)wain=Wa;
        }
        else if(wai+wait[i]==maxe){
            Wa=wai+wait[i];
            return value[i];
        }
    }
    return val;
}
int main()
{
    int n,wa,now=1,point,val=0,wA;
    string str;
    while(cin>>wa&&wa!=0){
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>str;
            wait[i]=0;value[i]=0;
            for(int j=0;;j++){
                if(str[j]==','){
                    for(int k=0;k<j;k++)value[i]+=(str[k]-'0')*Power(j-k-1);
                    point=j;
                }
                if(str[j]=='\0'){
                    for(int k=point+1;k<j;k++)wait[i]+=(str[k]-'0')*Power(j-k-1);
                    break;
                }
            }
        }
        for(int i=0;i<n;i++){
            point=serch(n,wa,i,0);
            if(n==1){
                    point=value[0];
                    wA=wait[0];
            }
            else if(val<point){
                val=point;
                wA=wain;
            }
            else if(point==val&&wA>wain)wA=wain;
        }
        cout<<"Case "<<now<<":\n"<<val<<endl<<wA<<endl;
        now++;val=0;

    }
}