Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)
const MAX_WIDTH = 1500000

func main() {
	// 二分探索で探す
	// 二分探索はソート済みの配列に対して、特定の条件を満たす値を
	// 効率よく選択するアルゴリズム
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		m, _ := strconv.Atoi(buf[0])
		n, _ := strconv.Atoi(buf[1])
		if n == 0 && m == 0 {
			break
		}
		books := make([]int, n)
		for i := 0; i < n; i++ {
			scanner.Scan()
			books[i], _ = strconv.Atoi(scanner.Text())
		}
		check := func(width int) bool {
			// widthの幅の本棚に順番にbooksを詰めて行ったら
			// 何段になるのかを確認し、それがmを以下であることを確認する
			shelf_index := 1
			position_in_stage := 0
			for i := 0; i < n; i++ {
				// 入れることができない本がある時点でこのwidthは不採用
				if books[i] > width {
					return false
				}
				// 新たに本を追加することができるかをチェックする
				if position_in_stage + books[i] <= width {
					// 新たに本を入れることができたので、そのステージにおける
					// 現在の本の位置を記録
					position_in_stage += books[i]
				} else {
					// 新たな本を入れることができなかったので、一段下のステージに
					// 入れれば良い
					position_in_stage = books[i]
					shelf_index++ // 本棚のステージ数が増えた
				}
			}
			return shelf_index <= m // 条件を満たすかの確認
		}
		low, high := 0, MAX_WIDTH
		for low < high {
			mid := (low+high)/2
			if check(mid) {
				high = mid
			} else {
				low = mid+1
			}
			// log.Printf("low: %d, high: %d\n", low, high)
		}
		fmt.Println(low)
	}
}

C++: import Control.Monad
import Control.Applicative

main :: IO ()
main = do
  [m, n] <- getInts
  if (m == 0 && n == 0) then return ()
  else do
    ss <- getIntLines n
    print $ rolve m ss
    main

rolve m ss = bin_search (kuwa ss m) 0 1000000

kuwa xs m n = func xs m n n
  where
    func (x:xs) m n l
      | m <= 0 = False
      | m > 0 && xs == [] && n - x >= 0 = True
      | n - x >= 0 = func xs m (n - x) l
      | n - x < 0 = func (x:xs) (m - 1) l l

bin_search func min max
  | (max - min == 1) && (func min) = min
  | (max - min == 1) && (func max) = max
  | func center = bin_search func min center
  | not (func center) = bin_search func center max
  where
    center = div (min + max) 2
---

getInt :: IO Integer
getInt = read <$> getLine

getInts :: IO [Integer]
getInts = map read . words <$> getLine

getIntLines :: Integral a => a -> IO [Integer]
getIntLines n = replicateM (fromIntegral n :: Int) getInt

C++: #include <iostream>
#include <climits>

using namespace std;

int jagde( int *book, int ix, int n, int m )
{
	int hoge[101];
	int j;

	for( int i = 0;i < 101;i++ ) hoge[i] = ix;

	j = 0;
	for( int i = 0;i < n;i++ ){
		hoge[j] -= book[i];
		while( hoge[j] < 0 ){
			j++;
			if( j >= m ) return -1;
			hoge[j] -= book[i];
		}
		if( j >= m ) return -1;
	}
	ix--;
	for( int i = 0;i < 101;i++ ) hoge[i] = ix;

	j = 0;
	for( int i = 0;i < n;i++ ){
		hoge[j] -= book[i];
		while( hoge[j] < 0 ){
			j++;
			if( j >= m ) return 0;
			hoge[j] -= book[i];
		}
		if( j >= m ) return 0;
	}

	return 1;
}


int answer( int m, int n, int *book )
{
	int low,high;
	int sum[101];

	sum[0] = book[0];
	for( int i = 1;i < n;i++ ){
		sum[i] = sum[i - 1] + book[i];
	}

	low = 0;
	high = sum[n - 1];

	while( true ){
		int ix = (low + high) / 2;
		int answer = jagde( book, ix, n, m );

		if( answer == -1 ){
			low = ix;
		} else if( answer == 0 ) {
			return ix;
		} else if( answer == 1 ) {
			high = ix;
		}
	}
	return -1;

}

int main(int argc, char const* argv[])
{
	int m,n;
	int book[101];

	while( cin >> m >> n && m != 0 ){
		for( int i = 0;i < n;i++ ) cin >> book[i];

		cout << answer( m, n, book ) << endl;
	}
	return 0;
}

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

#define INF (1<<28)
#define MAX_N 100
#define MAX_M (20+1)

int m, n;
int book[MAX_N];
int length[MAX_N];

int len(int from, int to) { // [from, to)
    return length[to] - length[from];
}

int dp[MAX_N][MAX_M];
int solve(int index, int rem) {
    if (rem == 1) return len(index, n);
    if (index == n) return 0;
    if (dp[index][rem] >= 0) return dp[index][rem];
    int min_len = INF;
    for (int i = index+1; i <= n; i++) {
        min_len = min(min_len, max(solve(i, rem-1), len(index, i)));
    }
    return dp[index][rem] = min_len;
}

void init() {
    for (int i = 0; i < n; i++) scanf("%d", &book[i]);
    length[0] = 0;
    for (int i = 1; i <= n; i++) 
        length[i] = length[i-1] + book[i-1];
    memset(dp, -1, sizeof(dp));
}

int main() {
    while (scanf("%d %d", &m, &n), m || n) {
        init();
        printf("%d\n", solve(0, m));
    }
    return 0;
}

C++: #include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int Width[100];
int M, N;


bool solve(int limit) {
	int nowWidth, nowSumShelf;

	nowWidth = 0;
	nowSumShelf = 1;
	for (int i = 0; i < N; ++i) {
		if (nowWidth + Width[i] <= limit) {
			nowWidth += Width[i];
			continue;
		}
		nowWidth = 0;
		--i;
		++nowSumShelf;
		if (nowSumShelf > M) {
			return false;
		}
	}
	return true;
}

int main() {
	int left, right, mid;

	while (cin >> M >> N, M) {
		for (int i = 0; i < N; ++i) {
			cin >> Width[i];
		}

		left = 0;
		right = 1500001;
		while (left < right) {
			mid = (left + right) / 2;
			//cout << "left:" << left << "  mid:"<<mid<<"  right:" << right << endl;
			if (solve(mid)) {
				right = mid;
			}
			else {
				left = mid + 1;
			}
		}
		cout <<left << endl;
	}

	return 0;
}

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

int m, n;
int w[110];

bool judge(ll x) {
    int cnt = 1;
    ll acc = 0;
    
    for (int i=0; i<n; i++) {
        if (acc+w[i]>x) {
            cnt++;
            if (w[i]>x) return false;
            else acc = w[i];
        }
        else acc += w[i];
    }
    
    return cnt<=m;
}

ll binary_search() {
    ll l=0, r=1000000*n;
    
    while (l<=r) {
        ll mid = (l+r)/2;
        
        if (judge(mid)) r = mid-1;
        else l = mid+1;
    }
    
    return l;
}

int main() {
    while (true) {
        cin >> m >> n;
        if (m==0) break;
        for (int i=0; i<n; i++) cin >> w[i];
        cout << binary_search() << endl;
    }
}

C++: #include<cstdio>
#include<algorithm>
using namespace std;
int main(){
  int m,n,w[101],ma,sum,cnt,dan,ans;
  while(scanf("%d %d",&m,&n),m!=0||n!=0){
    ma = 0;
    ans = 0;
    for(int i=0;i<n;i++){
      scanf("%d",&w[i]);
      ma = max(ma,w[i]);
      ans += w[i];
    }
    sum = 0;
    for(int i=0;i<n-1;i++){
      cnt = 0;
      dan = 2;
      sum += w[i];
      if(ma > sum) continue;
      for(int j=i+1;j<n;j++){
	if(cnt+w[j] > sum){
	  cnt = 0;
	  dan++;
	}
	cnt += w[j];
      }
      if(dan <= m) ans = min(ans,sum);
    }
    printf("%d\n",ans);
  }
  return(0);
}

C++: #include<iostream>

using namespace std;


int main(){
	
	int n,m;
	cin>>n>>m;
	
	int hon[100];
	for(int i=0;i<m;i++){
		cin>>hon[i];
	}
	
	int reft=0;
	int right=0;
	for(int i=0;i<m;i++){
		right+=hon[i];
	}
	
	while(1){
		double h = (double)(reft+right)/2;
		
		int now=0;
		int cont=1;
		for(int i=0;i<m;i++){
			if(cont>n){
				break;
			}
			if(now+hon[i]>h){
				now=0;
				cont++;
				i--;
				continue;
			}
			now+=hon[i];
		}
		
		if(cont>n){
			reft=h;
		}else{
			right=h+0.5;
		}
		
		if(reft+1==right){
			break;
		}
	}
	printf("%d\n",right);
}