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 <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <stack>
#include <string>
#include <functional>
#include <numeric>
#include <cmath>
#include <iomanip>
#include <map>
#include <set>
#include <cstdlib>
#include <stdio.h>
#define INF 100000000
#define INFLL (long long)1e14
#define Loops(i, n) for(int i = 0; i < (int)n; i++)
#define Loops1(i, n) for(int i = 1; i <= (int)n; i++)
int dp[2000][2000];
int w[2000];
int v[2000];
int N;
int W;
int count=1;
int kati=0,omosa=0;
int main(void){
	while(1){
		std::cin>>W;
		if(W==0){
			break;
		}
		std::cin>>N;
		Loops(i,N){
			int vi,wi;
			scanf("%d,%d",&vi,&wi);
			v[i]=vi;
			w[i]=wi;
//			std::cin>>w[i]>>v[i];
		}
		Loops(i,1000){
			Loops(j,1000){
				dp[i][j]=0;
			}
		}
		Loops(i,N){
			Loops(j,W+1){
				if(j-w[i]>=0){
					dp[i+1][j]=std::max(dp[i][j],dp[i][j-w[i]]+v[i]);
				}else {
					dp[i+1][j]=dp[i][j];				
				}
			}
		}
		Loops(i,W+1){
			if(kati<dp[N][i]){
				kati=dp[N][i];
				omosa=i;
			}
		}
		printf("Case %d:\n",count);
		std::cout<<kati<<std::endl;
		std::cout<<omosa<<std::endl;
		count++;
/*	Loops(i,N+1){
		Loops(j,W+1){
			std::cout<<dp[i][j]<<" ";
		}
		std::cout<<std::endl;
	}*/

	}
	return 0;
}

C++: #include<iostream>

using namespace std;

class item
{
public:
	int value;
	int weight;
	bool flag;
	item()
	{
		flag=false;
	}
};

bool input(int *c, int *n, item it[1000])
{
	cin>>*c;
	if(*c==0)
	{
		return false;
	}
	cin>>*n;
	for(int i=0;i<*n;i++)
	{
		char t;
		cin>>it[i].value>>t>>it[i].weight;
	}
	return true;
}

item max(item a, item b)
{
	if(a.value>b.value)
	{
		return a;
	}
	else
	{
		return b;
	}
}

item add(item a, item b)
{
	a.value+=b.value;
	a.weight+=b.weight;
	return a;
}

item solve(int c, int n, item it[1000],item table[1000][1000])
{
	if(table[c][n].flag!=true){
		if(c==0||n==0)
		{
			table[c][n].value=0;
			table[c][n].weight=0;
		}
		else if(c<it[n-1].weight)
		{
			table[c][n]=solve(c,n-1,it,table);
		}
		else
		{
			table[c][n]=max(solve(c,n-1,it,table),add(solve(c-it[n-1].weight,n-1,it,table),it[n-1]));
		}
		table[c][n].flag=true;
	}
	return table[c][n];
}


int main(void)
{
	int c,n;
	item it[1000];
	for(int i=1;input(&c,&n,it);i++)
	{
		item table[1000][1000];
		item ans=solve(c,n,it,table);
		cout<<"Case "<<i<<':'<<endl<<ans.value<<endl<<ans.weight<<endl;
	}
}

C++: #include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <vector>
#include <algorithm>

#define rep(i,n) for(int i=0; i < n;i++)

using namespace std;

int dp[1001][1001];

vector<string> split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

int main()
{
	int count = 0;
	int W,n,ans;
	int w[1001],v[1001];

	while(cin >> W && W)
	{
		count++;
		memset(dp,0,sizeof(dp));
		cin >> n;
		rep(i,n)
		{
			string s;
			cin >> s;
			vector<string> _s = split(s,',');
			v[i] = atoi(_s[0].c_str());
			w[i] = atoi(_s[1].c_str());
		}

		for(int i=0;i< n ;i++)
		{
			for(int j = 0 ; j <= W; j++)
			{
				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]);
				}
			}
		}
		for(int j=0;j <= W ; j++)
		{
			if(dp[n][j] == dp[n][W])
			{
				ans = j;
				break;
			}
		}
		cout << "Case " << count <<  ":" << endl;
		cout << dp[n][W] << endl << ans << endl;
	
	}

	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

vector<int> split(const string &str, char sep) {
  vector<int> v;
  stringstream ss(str);
  string buffer;
  while( getline(ss, buffer, sep) ) {
    v.push_back(stoi(buffer));
  }
  return v;
}

int main() {
  int W;
  int cnt = 0;
  while (cin >> W, W) {
    int N; cin >> N;
    cout << "Case " << ++cnt << ":" << endl;
    auto v = vector<int>(N);
    auto w = vector<int>(N);
    for (int i = 0; i < N; ++i) {
      string s; cin >> s;
      auto tmp = split(s, ',');
      v[i] = tmp[0];
      w[i] = tmp[1];
    }
    auto dp = vector<vector<int>>(N + 1, vector<int>(W + 1, -1));
    auto dp2 = vector<vector<int>>(N + 1, vector<int>(W + 1, 0));
    for (int j = 0; j < W + 1; ++j) dp[0][j] = 0;
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < W + 1; ++j) {
        if (j < w[i]) {
          dp[i + 1][j] = dp[i][j];
          dp2[i + 1][j] = dp2[i][j];
        } else {
          if (dp[i][j] < dp[i][j - w[i]] + v[i]) {
            dp2[i + 1][j] = dp2[i][j - w[i]] + w[i];
          } else {
            dp2[i + 1][j] = dp2[i][j];
          }
          dp[i + 1][j] = max(dp[i][j], dp[i][j - w[i]] + v[i]);
        }
      }
    }
    int m = dp2[N][W];
    for (int j = W - 1; j >= 0; --j) {
      if (dp[N][j] < dp[N][W]) break;
      m = min(m, dp2[N][j]);
    }
    cout << dp[N][W] << endl;
    cout << m << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <cmath>
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, int N) {
    int dp[1001] = {}; // 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 << "Case " << caseId << ":" << endl << value << endl << weight << endl;
}

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