Go: ///
// File:  0529.go
// Author: ymiyamoto
//
// Created on Wed Feb 28 20:39:28 2018
//
package main

import (
	"fmt"
	"sort"
)

func max(n, m int64) int64 {
	if n < m {
		return m
	} else {
		return n
	}
}

func main() {
	for {
		var N int
		var M int64
		fmt.Scan(&N, &M)
		if N == 0 && M == 0 {
			break
		}

		arr := make([]int64, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })

		sums := make([]int64, len(arr)*len(arr))
		for i := 0; i < len(arr); i++ {
			for j := 0; j < len(arr); j++ {
				sums[i*len(arr)+j] = arr[i] + arr[j]
			}
		}

		sort.Slice(sums, func(i, j int) bool { return sums[i] < sums[j] })

		var m int64 = 0
		for i := 0; i < len(sums); i++ {
			rem := M - sums[i]
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, sums[i]+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: //Solution for AOJ 0529: Darts
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_N = 1000, MAX_M = 200000000;
int n, m;
int p[MAX_N + 1], p2[MAX_N*MAX_N], ans, roop, s, mid;
void search(int end, int start){
	if ((end + start) % 2)
		mid = (end + start) / 2 + 1;
	else
		mid = (end + start) / 2;
	if (p2[mid] == s)
		return;
	if (p2[mid] < s){
		if (end - mid == 1){
			if (p2[end]<s)
				mid++;
			return;
		}
		search(end, mid);
	}
	else{
		if (mid - start == 1){
			mid--;
			return;
		}
		search(mid, start);
	}
}
int main(){
	while (cin >> n >> m){
		ans = 0;
		if (!n&&!m)
			return 0;
		for (int i = 1; i <= n; i++){
			cin >> p[i];
		}
		roop = 0;
		for (int i = 0; i <= n; i++){
			for (int j = i; j <= n; j++){
				if (p[i] + p[j] <= m){
					p2[roop] = p[i] + p[j];
					roop++;
				}
			}
		}
		sort(p2, p2 + roop);
		for (int i = 0; i < roop; i++){
			s = m - p2[i];
			search(roop - 1, 0);
			ans = max(ans, p2[i] + p2[mid]);
			if (ans == m)
				break;
		}
		cout << ans << endl;
	}
}

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

#define MAX_N 1000
int P[MAX_N + 1];
int N, M;
int table[5][MAX_N + 1];

int dfs(int a, int b, int c){
	if(c > M) return P[b] * -1;
	if(a == 0) return P[b];
	if(table[a][b] >= 0) return table[a][b];
	
	int cho = b;
	while(cho <= N){
		int d = dfs(a - 1, cho, c + P[b]) + P[b];
		table[a][b] = max(table[a][b], (d > M)? 0 : d);
		cho++;
	}
	
	return table[a][b];
}

int main(){
	ifstream ifs("input.txt");
	
	for(int i = 0; i < 5; i++){
		for(int j = 0; j <= MAX_N; j++){
			table[i][j] = -1;
		}
	}
	
	ifs >> N >> M;
	
	P[0] = 0;
	for(int i = 1; i <= N; i++) ifs >> P[i];
	
	printf("%d\n", dfs(4, 0, 0));
	
	return 0;
}

C++: #define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;

//#define int long long
#define DBG 0
#define dump(o) if(DBG){cerr<<#o<<" "<<o<<endl;}
#define dumpc(o) if(DBG){cerr<<#o; for(auto &e:(o))cerr<<" "<<e;cerr<<endl;}
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define each(it,c) for(auto it=(c).begin();it!=(c).end();it++)
#define all(c) c.begin(),c.end()
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9 + 7);
const double EPS = 1e-10;

signed main() {
	int n, m;
	while (cin >> n >> m, n || m) {
		vector<int>v(n + 1, 0), Q; rep(i, 1, n + 1)cin >> v[i];
		rep(i, 0, n + 1) {
			rep(j, i, n + 1) {

				if (v[i] + v[j] <= m)Q.push_back(v[i] + v[j]);
			}
		}
		sort(all(Q));
		dumpc(Q);
		int ans(0);
		rep(i, 0, Q.size()) {
			int l = 0, r = Q.size();
			while (r - l > 1) {
				int mid = (l + r) / 2;
				if (Q[mid] > m - Q[i])r = mid;
				else l = mid;
			}
			if (Q[i] + Q[l] <= m)ans = max(ans, Q[i] + Q[l]);
			dump(ans);
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long in;
typedef pair<in,in> ii;
#define F first
#define S second
#define sqr(x) (x)*(x)
#define pb(x) push_back(x)
#define sz(x) (in)x.size()
#define mp(x,y) make_pair(x,y)
#define all(x) (x).begin(),(x).end()
#define rep(i,x,y) for(in i=x;i<(y);++i)
#define IOS ios_base::sync_with_stdio(0);cin.tie(0)
/* start */

int main(){
    IOS;
    in n,m;
    while(cin >> n >> m and (n+m)){
        in ans = 0;
        vector<in> a,comb;
        a.pb(0);
        rep(i,0,n){
            in x;
            cin >> x;
            a.pb(x);
        }
        rep(i,0,sz(a)){
            rep(j,i,sz(a)){
                comb.pb(a[i]+a[j]);
            }
        }
        sort(all(comb));
        rep(i,0,sz(comb)){
            auto it = upper_bound(all(comb),m-comb[i]);
            if(it != comb.begin()){
                it--;
                ans = max(ans,*it+comb[i]);
            }
        }
        cout << ans << "\n";
    }
}

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

using namespace std;

typedef vector<int> vi;

#define PB push_back
#define rep(i,x) for(int i=0;i<(x);++i)
#define rep1(i,x) for(int i=1;i<=(x);++i)
#define all(a) a.begin(),a.end()

int P[1001];

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int N, M;
	
	while (cin >> N >> M, N || M) {
		rep1(i, N) cin >> P[i];

		vi A;

		A.PB(0);

		rep(i, N + 1) rep(j, N + 1) if (P[i] + P[j] <= M) A.PB(P[i] + P[j]);

		sort(all(A));

		int ma = 0;

        int l = 0, r = A.size() - 1;

        while (l < r) {
            while (A[l] + A[r] > M) r--;
            ma = max(ma, A[l] + A[r]);
            l++;
        }

		cout << ma << endl;
	}
}

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

int N = 0, M = 0;
int points[1001];
int scores[1002001];

bool check(int a, int c){
    if(a >= (N + 2) * (N + 1) / 2 - 1){
        return true;
    }
    return (scores[a] <= c && scores[a + 1] > c);
}

int search2(int a, int b, int c){
    int pib = a + b - b / 2;
    if(check(pib, c)){
        return pib;
    }else if(scores[pib] < c){
        return search2(pib, b / 2, c);
    }else{
        return search2(a, b / 2, c);
    }
}

int main(){
    for(;;){
        for(int i = 0; i < 1001; i++){
            points[i] = 0;
        }
        for(int i = 0; i < 1002001; i++){
            scores[i] = 0;
        }
        if(cin >> N){
            if(N == 0){
                break;
            }
            cin >> M;
            for(int i = 1; i <= N; i++){
                cin >> points[i];
            }
            for(int i = 0; i <= N; i++){
                for(int j = i; j <= N; j++){
                    scores[(2 * N - i + 1) * i / 2 + j] = points[i] + points[j];
                }
            }
            int mxsco = 0;
            sort(scores, scores + ((N + 2) * (N + 1)) / 2);
            for(int i = 0; i < (N + 2) * (N + 1) / 2; i++){
                if(scores[i] > M){
                    break;
                }
                cout << scores[i] << " ";
                int ll = search2(0, (N + 2) * (N + 1) / 2, M - scores[i]);
                cout << ll << " ";
                cout << scores[ll] << " ";
                int nosco = scores[i] + scores[search2(0, (N + 2) * (N + 1) / 2, M - scores[i])];
                cout << "now score is.." << nosco << endl;
                if(nosco >= mxsco &&  nosco <= M){
                    mxsco = nosco;
                }
            }
            cout << mxsco;
        }else{
            break;
        }
    }
    return 0;
}