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<vector>
#include<string.h>
using namespace std;

int main(){
    int w,n,va,we;
    int dp[10000];
    char c;
    vector<pair<int,int> >vec;
    int cas=0;
    while(cin>>w>>n,w){
        for(int i=0;i<n;i++){
            cin>>va>>c>>we;
            vec.push_back(make_pair(va, we));
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++){
            int tv=vec[i].first, tw=vec[i].second;
            for(int j=w;j>=0;j--){
                if(tw+j<=w){
                    dp[tw+j]=max(dp[tw+j],dp[j]+tv);
                }
            }
        }
        int aw=0,av=0;
        for(int i=0;i<=w;i++) {
            if(dp[i]>av){
                aw=i;
                av=dp[i];
            }
        }
        cout<<"Case "<<(++cas)<<":"<<endl<<av<<endl<<aw<<endl;
        vec.clear();
    }
}

C++: #include <cstdio>
#include <utility>
#include <vector>
using namespace std;

#define gcu getchar_unlocked
int in(int c){int n=0;bool m=false;if(c=='-')m=true,c=gcu();
	do{n=10*n+(c-'0'),c=gcu();}while(c>='0');return m?-n:n;}
int in() {return in(gcu());}
bool scan(int &n){int c=gcu();return c==EOF?false:(n=in(c),true);}
bool scan(char &c){c=gcu();gcu();return c!=EOF;}
//bool scan(string &s){int c;s="";
//	for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=c;}}
#define pcu putchar_unlocked
#define vo inline void out
template <typename T>
vo(T n){static char buf[20];char *p=buf;
	if(n<0)pcu('-'),n*=-1;if(!n)*p++='0';else while(n)*p++=n%10+'0',n/=10;
	while (p!=buf)pcu(*--p);}
vo(const char *s){while(*s)pcu(*s++);}
vo(char c){pcu(c);}
//vo(string &s){for (char c: s) pcu(c);}
template <typename head, typename... tail> vo(head&& h, tail&&... t){out(h);out(move(t)...);}
//template <typename T> vo(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);out('\n');}
#undef vo

struct T {int v, w;};

int main() {
	for (int w, n, i = 1; (w = in()) && (n = in()); i++) {
		out("Case ", i, ":\n");
		vector<T> ts(n);
		vector<vector<T>> m(n + 1, vector<T>(w + 1, {0, 0}));
		for (auto &t: ts) {
			int v = in();
			t = {v, in()};
		}
		for (int i = n - 1; i >= 0; i--)
			for (int j = 0; j <= w; j++)
				if (j < ts[i].w)
					m[i][j] = m[i + 1][j];
				else {
					T a = m[i + 1][j], b = m[i + 1][j - ts[i].w];
					b = {b.v + ts[i].v, b.w + ts[i].w};
					m[i][j] = (a.v >= b.v) ? a : b;
				}
		T r = m[0][w];
		out(r.v, '\n', r.w, '\n');
	}
}

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

#pragma warning(disable:4996)

#define MAX_N 1200
#define MAX_W 1200

int dp[MAX_N][MAX_W];
int W, N, v[MAX_N], w[MAX_N], cnt;

int main() {
	while (true) {
		cnt++;
		memset(dp, 0, sizeof(dp));
		cin >> W;
		if (W == 0) { break; }
		cin >> N;
		for (int i = 0; i < N; i++)
		{
			scanf("%d,%d", &v[i], &w[i]);
		}
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j <= W; j++)
			{
				dp[i + 1][j] = max(dp[i][j], dp[i + 1][j]);
				if (j + w[i] <= W)
				{
					dp[i + 1][j + w[i]] = max(dp[i][j] + v[i], dp[i + 1][j + w[i]]);
				}
			}
		}
		cout << "Case " << cnt << ":" << endl;
		int maxn = 0, maxid = 0;
		for (int j = 0; j <= W; j++)
		{
			if (maxn < dp[N][j])
			{
				maxn = dp[N][j];
				maxid = j;
			}
			else if (maxn == dp[N][j])
			{
				maxid = min(maxid, j);
			}
		}
		cout << maxn << endl;
		cout << maxid << endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <cstdio>

using namespace std;

#define price first
#define weight second

int main(){
	int W;
	int cnt = 1;
	while (cin >> W, W) {
		int N; cin >> N;
		vector<pair<int, int> > tres(N);
		for (int i = 0; i < N; i++) {
			scanf("%d,%d", &tres[i].price, &tres[i].weight);
		}
		vector<int> dp(W+1);
		for (int i = 0; i < W+1; i++) { dp[i] = -1; }
		dp[0] = 0;
		for (int i = 0; i < N; i++) {
			for (int j = W; j >= 0; j--) {
				if (dp[j] == -1) { continue; }
				if (j+tres[i].weight <= W) {
					dp[j+tres[i].weight] = max(dp[j]+tres[i].price, dp[j+tres[i].weight]);
				}
			}
		}
		int PRICE = 0;
		int WEIGHT = 0;
		for (int i = W; i >= 0; i--) {
			if (PRICE <= dp[i]) {
				PRICE = dp[i];
				WEIGHT = i;
			}
		}

		cout << "Case " << cnt << ":" << endl;
		cout << PRICE << endl;
		cout << WEIGHT << endl;
		cnt++;
	}
}

C++: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <cctype>
#include <numeric>
using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); ++(i))
#define foreach(c,i) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)

int N, W, v[1002], w[1002]; // v[i],w[i] := iツ氾板姪堋づ個品ツ閉ィツづ個可ソツ値ツ、ツ重ツつウ
int dp[1002][1002]; // dp[i][j] := iツ氾板姪堋づ個品ツ閉ィツづ慊づ考ツ猟カツつオツつスツ篠楪づ個、ツ重ツつウjツづ可つィツつッツづゥツ催妥・ツづ個可ソツ値
void solve() {
  memset(dp, 0, sizeof dp);
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j <= W; ++j) {
      if (j + w[i] <= W)
        dp[i+1][j+w[i]] = max(dp[i][j+w[i]], max(dp[i][j]+v[i], dp[i+1][j+w[i]]));
      else
        dp[i+1][j+w[i]] = max(dp[i][j+w[i]], dp[i+1][j+w[i]]);
    }
  }
  int *itr = max_element(dp[N], dp[N]+W+1);
  printf("%d\n%d\n", *itr, itr - dp[N]);
}

int main() {
  int z = 1;
  while (scanf("%d",&W),W) {
    scanf("%d",&N);
    rep(i,N) scanf("%d,%d",v+i,w+i);
    printf("Case %d:\n", z);
    solve();
    ++z;
  }
  return 0; 
}

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 = 10000;
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;	
}