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++: #include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>

using namespace std;


struct Treasure
{

  int value;
  int weight;

  Treasure()
  {
    value = 0;
    weight = 0;
  }

  void operator()( Treasure t)
  {

    cout << t.value << "," << t.weight << endl;

  }

  Treasure& operator+=(const Treasure& t )
  {

    this->value += t.value;
    this->weight += t.weight;
    return *this;

  }

  Treasure operator+(const Treasure& t)
  {
    Treasure tmp;
    tmp.value = this->value + t.value;
    tmp.weight = this->weight + t.weight;
    return tmp;
  }

  Treasure operator-(const Treasure& t)
  {
    Treasure tmp;
    tmp.value = this->value - t.value;
    tmp.weight = this->weight - t.weight;
    return tmp;
  }

};

/*
Treasure max(Treasure t1,Treasure t2)
{

  if(t1.value == t2.value)
    {
      return (t1.weight < t2.weight) ? t1 : t2;
    }
  else
    {
      return (t1.value > t2.value) ? t1 : t2;
    }

}
*/
int N,W;

//Treasure memo[1000][1000];

//Treasure tmp;

vector<Treasure> treasure(1000);

int dp[1000][1000];

/*
Treasure Knapsack(int currentWeight,int currentCount)
{

  Treasure t1,t2,f;

  if(memo[currentWeight][currentCount].weight)
    {
      return memo[currentWeight][currentCount];
    }
  else if(N == currentCount)
    {
      return tmp;
    }
  else{

    t1 = Knapsack(currentWeight,currentCount + 1);

    if( W >= currentWeight + treasure[currentCount].weight)
      {
        t2 = Knapsack(currentWeight + treasure[currentCount].weight,currentCount + 1) + treasure[currentCount];
      }
    else
      {
        t2 = Knapsack(currentWeight,currentCount + 1);
      }

    memo[currentWeight][currentCount] = max(t1,t2);

    return max(t1,t2);

  }

}

*/

int main()
{

  int caseNumber = 0;

 while(cin >> W && W != 0)
   {

     cin >> N;

     for(int i = 0; i < N; ++i)
       { scanf("%d,%d",&treasure[i].value,&treasure[i].weight); }
     /*
     Treasure result = Knapsack(0,0);

     memset(memo,0,sizeof(memo));

     treasure.erase(treasure.begin(),treasure.end());

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

     cout << result.value << endl << result.weight << endl;
     */
     //////////////////////////////////////////////////////////////

     for(int i = 0; i < W; ++i)
       {
         for(int j = 0; j < N; ++j)
           {
                dp[i][j] = 0;
           }
       }

     for(int i = 1; i <= W; ++i)
       {
         for(int j = 1; j <= N; ++j)
           {
             if(i - treasure[j - 1].weight >= 0)
               {
                 dp[i][j] = max(dp[i][j - 1],dp[i - treasure[j - 1].weight][j - 1] + treasure[j - 1].value);
               }
             else
               {
                 dp[i][j] = dp[i][j - 1];
               }
           }

       }

     bool flag = false;

     int i;

     for(i = 0; i <= W && !flag; ++i)
       {
         for(int j = 1; j <= N && !flag; ++j)
           {
             if(dp[W][N] == dp[i][j])
               {
                 flag = true;
               }
           }
       }




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

     cout << dp[W][N] << endl << i - 1  << 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;
int dp[1001][1001];

void dfs(int weight, int value, int index){
	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);
		fill_n(*dp, 1001*1001, -1);

		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<bits/stdc++.h>
using namespace std;
#define all(vec) vec.begin(),vec.end()
typedef long long int ll;
typedef pair<int,int> P;
const ll MOD=1234567;
const ll INF=1000000010;
const ll LINF=1000000000000000010LL;
const int MAX=10000010;
const double EPS=1e-3;
int dx[4]={0,1,0,1};
int dy[4]={0,0,1,1};
int dp[1010][1010];
int main(){
	int W;
	int c=0;
	while(cin>>W,W){
		int n;cin>>n;
		int v[1010],w[1010];
		memset(dp,0,sizeof(dp));
		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+1][j],dp[i][j]);
				if(j+w[i]<=W){
					dp[i+1][j+w[i]]=max(dp[i+1][j+w[i]],dp[i][j]+v[i]);
				}
			}
		}
		int ans=0;
		int m=0;
		for(int i=0;i<=W;i++){
			if(ans<dp[n][i]){
				ans=dp[n][i];
				m=i;
			}
		}
		cout<<"Case "<<c<<":"<<endl;
		cout<<ans<<endl;
		cout<<m<<endl;
		c++;
	}
}

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[1010] = {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;
}