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
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <fstream>
#include <complex>
#include <math.h>

using namespace std;

//conversion
//------------------------------------------
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

//math
//-------------------------------------------
template<class T> inline T sqr(T x) {return x*x;}

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long, long> PLL;
typedef long long LL;
//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

//repetition
//------------------------------------------
#define FOR(i,a,b) for(long i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

//constant
//--------------------------------------------

//clear memory
#define CLR(a) memset((a), 0 ,sizeof(a))

const long double EPS = 1e-12;
const LL INF = 1e18;


int dp[1002][1001];
int w[1001],v[1001];


int main(){
	int maxw,N;
	int cnt=1;
	while(cin>>maxw){
		if(maxw==0)break;
		cin>>N;
		CLR(dp);
		char c;
		REP(i,N)cin>>v[i]>>c>>w[i];
		int res1=-1,res2=0;
		REP(i,N){
			REP(j,maxw){
				if(j+w[i]<=maxw){
					dp[i+1][j+w[i]]=max(dp[i+1][j+w[i]],dp[i][j]+v[i]);
					if(dp[i+1][j+w[i]]>res1){
						res1=dp[i+1][j+w[i]];
						res2=j+w[i];
					}else if(dp[i+1][j+w[i]]==res1){
						res2=min(res2,(int)j+w[i]);
					}
				}
			}
		}
		cout<<"Case "<<cnt<<":"<<endl;
		cout<<res1<<endl;
		cout<<res2<<endl;
	}
	return 0;
}
/*

*/

C++: #include <iostream>
#include <vector>
#include <utility>
#define rep(i,k,n) for(int i=k;i<n;i++)
using namespace std;
typedef pair<int,int> takara;
//cost,weight
class napsack{
private:
  vector<takara> pack;
  int lim;
public:
  napsack(){
  };
  void push(takara a){
    takara tmp;
    int flag;
    int forend=pack.size();
    rep(i,0,forend){
      tmp=make_pair(a.first+pack[i].first,a.second+pack[i].second);
      // cout<<tmp.first<<" "<<tmp.second<<endl;  
      if(tmp.second>=lim) continue;
      flag=1;
     
      rep(j,0,forend)
	{
	if(pack[j].second>=tmp.second)
	  if(pack[j].first<tmp.first){
	    if(flag){flag--;
	      pack[j]=tmp;}
	    else{ pack.erase(pack.begin()+j);
	      forend--;}
	    }
      }
  
      rep(j,0,pack.size())
	if(pack[j].first>=tmp.first) {flag=355;break;}
      if(flag!=355) pack.push_back(tmp);
    }
  }
  void test(){
    rep(i,0,pack.size()){
      cout<<pack[i].first<<" "<<pack[i].second<<endl;
    }
  }
  void max(int uuu){
    takara tmp=make_pair(0,0);
    rep(i,0,pack.size()){
      if(tmp.first==pack[i].first)
	if(tmp.second>pack[i].second)
	  tmp=pack[i];
      if(tmp.first<pack[i].first)
	tmp=pack[i];	
    }
    cout <<"case "<<uuu<<":"<<endl<<tmp.first<<endl<<tmp.second<<endl;
  }
  void reset(int i){
    lim=i;
    pack.resize(1,make_pair(0,0));
  }

};

 
int main(){
  int w,n,a,b,count;
  napsack sack;
  char th;  
  count=0;
  while(1){
    count++;
    cin >>w;
    if(w==0) break;
    cin >>n;
    sack.reset(w);
    rep(i,0,n){
      cin>>a>>th>>b;
      sack.push(make_pair(a,b));
    }
    // sack.test();
    sack.max(count);
  }
  return 0;
}

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

using namespace std;

int main() {
    for(int CASE = 1; ; ++CASE) {
        int W;
        cin >> W;
        if(!W) break;

        int N;
        cin >> N;
        vector<pair<int, int> > v;
        for(int i = 0; i < N; ++i) {
            int val, w;
            char comma;
            cin >> val >> comma >> w;
            v.push_back(make_pair(val, w));
        }

        vector<vector<int> > dp(2, vector<int>(W+1, 0));
        int vn = 0;
        int mv = 0;
        for(int i = 0; i < N; ++i) {
            vector<int> &vec = dp[vn];
            vector<int> &prev = dp[1-vn];

            for(int w = 0; w <= W; ++w) {
                int pw = w - v[i].second;
                vec[w] = prev[w];
                if(pw >= 0) {
                    vec[w] = max(vec[w], prev[pw] + v[i].first);
                    mv = max(mv, vec[w]);
                }
            }
            vn = 1-vn;
        }

        cout << "Case " << CASE << ":" << endl;
        for(int w = 0; w <= W; ++w) {
            if(dp[1-vn][w] == mv) {
                cout << mv << endl;
                cout << w << endl;
                break;
            }
        }
    }
    return 0;
}

C++: #include<iostream>
#include<string.h>
#include<math.h>
using namespace std;
void vmax(int,int,int[],int[]);
int sum_w[1001][1001];
int sum_v[1001][1001];
int main(){
	int count=0;
	while(1){
		int i,j,lim=0,N=0,v[1001],w[1001],k=0,l=0;
		count++;
		cin>>lim;
		if(lim==0)break;
		cin>>N;
		for(i=0;i<N;i++){
			scanf("%d,%d",&v[i],&w[i]);
		}
		for(i=0;i<N;i++){
			for(j=0;j<=lim;j++){
				vmax(i,j,v,w);
			}
		}
		for(i=0;i<N;i++){
			if(k<sum_v[N-1][i]){
				k=sum_v[N-1][i];
				l=i;
			}
		}
		cout<<"Case"<<count<<endl;
		cout<<sum_v[N-1][l]<<endl;
		cout<<sum_w[N-1][l]<<endl;

	}
	
	return 0;
}
void vmax(int i,int j,int v[],int w[]){
	if(sum_v[i-1][j]<sum_v[i-1][j-w[i]]+v[i]){
		sum_v[i][j]=sum_v[i-1][j-w[i]]+v[i];
		sum_w[i][j]=sum_w[i-1][j-w[i]]+w[i];
	}
}