Go: package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	Case := 1
	for {
		scanner.Scan()
		W, _ := strconv.Atoi(scanner.Text())
		if W == 0 {
			break
		}
		scanner.Scan()
		n, _ := strconv.Atoi(scanner.Text())
		w := make([]int, n+1)
		v := make([]int, n+1)
		for i := 1; i <= n; i++ {
			scanner.Scan()
			info := strings.Split(scanner.Text(), ",")
			v[i], _ = strconv.Atoi(info[0])
			w[i], _ = strconv.Atoi(info[1])
		}
		// fmt.Println(v)
		// fmt.Println(w)
		dp := make([][]int, n+1)
		for i := range dp {
			dp[i] = make([]int, W+1)
		}
		maxV := -(1 << 21)
		minW := 1 << 21
		for i := 1; i <= n; i++ {
			for j := 1; j <= W; j++ {
				// fmt.Println(dp)
				if j-w[i] >= 0 {
					dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i])
					if maxV < dp[i][j] {
						maxV = dp[i][j]
						minW = j
					} else if maxV == dp[i][j] {
						minW = min(minW, j)
					}
				} else {
					dp[i][j] = dp[i-1][j]
				}
			}
		}
		fmt.Printf("Case %d:\n", Case)
		Case += 1
		fmt.Println(maxV)
		fmt.Println(minW)
	}
}
func max(x, y int) int {
	if x < y {
		return y
	}
	return x
}
func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

C++: //0042 A Thief
//vñFibvTbNâè

#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;

int main(void)
{

	const int MAX_WEIGHT = 1000;
	const int MAX_OBJECT = 10000;
	const int MAX_SCORE = 1000;

	struct Obj
	{
		int w;
		int score;
	};
	struct Cloth
	{
		int index;
		int totalScore;
	};

	int caseNum = 1;
	while(1)
	{
		//ÇÌd³ÌÆ«àAÅãÉüê½CfbNXA»êÜÅÌ¿lð¶ÝµÈ¢lÉ
		int totalScore[MAX_WEIGHT+1] = {0};
		int intoIndex[MAX_WEIGHT+1];
		memset(intoIndex, 0xffffffff, sizeof(intoIndex)/sizeof(intoIndex[0]));

		//\¢Ì¶áfobOÅl©êÈ¢æI
		//Cloth total[MAX_WEIGHT+1];

		Obj obj[MAX_OBJECT];

		int w, n;
		int i, j;
		char dummy;

		cin >> w;
		if(w == 0)
			break;
		cin >> n;

		for(i = 0; i < n; i++)
		{
			cin >> obj[i].score >> dummy >> obj[i].w;
			
			for(j = w-obj[i].w; j >= 1; j--)
			{
				//·ÅÉ»Ìd³ÜÅÏÜê½àÌª é
				if(totalScore[j])
				{
					//æèæ¢ÂÝûð­©
					if(totalScore[j+ obj[i].w] < totalScore[j] + obj[i].score)
					{
						totalScore[j+ obj[i].w] = totalScore[j] + obj[i].score;
						intoIndex[j+ obj[i].w] = i;
					}
				}
			}
			//ÅÌÍüêÄà¢¢Ìæ
			if(totalScore[obj[i].w] < obj[i].score)
			{
				totalScore[obj[i].w] = obj[i].score;
				intoIndex[obj[i].w] = i;
			}
		}

		cout << "Case " << caseNum << ":" << endl;
		caseNum++;

		//zñÉüÁ½vfÌÅålÆA»ÌCfbNXðT·
		int maxScore = 0;
		int maxIndex = -1;
		for(i = 0; i <= w; i++)
		{
			if(totalScore[i] && maxScore<totalScore[i])
			{
				maxScore = totalScore[i];
				maxIndex = i;
			}
		}
		//½©vfÍüÁÄ½H
		if(maxIndex >= 0)
		{
			cout << totalScore[maxIndex] << endl;

			//d³aÌvZ
			int totalW = 0;
			int index = maxIndex;
			while(index>0)
			{
				totalW += obj[ intoIndex[index] ].w;
				index -= obj[ intoIndex[index] ].w;
			}
			cout << totalW << endl;
		}
		//êÂàüçÈ©Á½H
		else
			cout << "0" << endl << "0" << endl;
	}
	return 0;
}

C++: // AOL Q.0042
// YAMADA Terushige 2013.2.13.

#include<iostream>
#include<algorithm>

using namespace std;

int main(){

  int W,N;
  int nloop=0;
  while(cin >> W >> N){
    if (W == 0) break;
    nloop++;

    int v[N],w[N];
    char c;
    for (int i = 0;i < N;i++)
      cin >> v[i] >> c >> w[i];

    int dp[1001]={0};
    for(int i=0;i<N;i++)
      for(int k=W;k>=w[i];k--)
	dp[k] = max( dp[k] , dp[k-w[i]] + v[i] );

    int k=0;
    while( dp[k] < dp[W] ){
      k++;
    }

    cout << "Case " << nloop << ':' << endl << dp[W] << endl << k << 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 can[1001];
int maxW, maxV;
map<int,int> dp[1001];
 
void dfs(int weight, int value, int index){
	if(can[index] < maxV)return;
    if(weight > W)return;
    if(dp[weight][index]>value)return;
    dp[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);
        ///rep(i,1000)dp[i].clear();
        rep(i,N){
            int n, w;
            scanf("%d,%d", &n, & w);
            tres[i] = n;
            weig[i] = w;
            if(i==0)can[i]=tres[i];
            else can[i] = can[i-1]+tres[i];
        }
 
        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 <bits/stdc++.h>
using namespace std;

#define int				long long
#define FOR( i, m, n )  for( int (i) = (m); (i) < (n); (i)++ )
#define REP( i, n )     FOR( i, 0, n )
#define REPR( i, m )	for( int (i) = (m); (i) >= 0; (i)-- )
#define REPONE( i, n )	FOR( i, 1, n + 1 )
#define ALL( a )        (a).begin(), (a).end()
#define MP				make_pair
#define EB				emplace_back

typedef pair<int, int> P;

template<class T>bool chmax( T& a, const T& b ) { if( a < b ) { a = b; return 1; } return 0; }
template<class T>bool chmin( T& a, const T& b ) { if( a > b ) { a = b; return 1; } return 0; }

const int INF = 1e9;
const int MOD = 1e9 + 7;

int dp[1001][10001];

signed main() {
	int W, N, cnt = 1;
	while( cin >> W, W ) {
		cin >> N;
		fill( dp[0], dp[1001], 0 );

		int w = 0, vmax = 0;
		vector<P> tre( N );
		REP( i, N ) {
			char c;
			cin >> tre[i].first >> c >> tre[i].second;
		}

		REP( i, N ) {
			REP( j, W + 1 ) {
				if( j - tre[i].second >= 0 ) {
					dp[i + 1][j] = max( dp[i][j], dp[i][j - tre[i].second] + tre[i].first );

					if( vmax < dp[i + 1][j] ) {
						vmax = dp[i + 1][j];
						w = j;
					} else if( vmax == dp[i + 1][j] ) {
						chmin( w, j );
					}


				} else {
					dp[i + 1][j] = dp[i][j];
				}
			}
		}

		cout << "Case " << ( cnt++ ) << ":" << endl;
		cout << dp[N][W] << endl << w << endl;

	}
}