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

import (
	"fmt"
	"sort"
)

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

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

		arr := make([]int, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Ints(arr)

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

		m := 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++: #include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        VI P( n );
        for ( int i = 0; i < n; ++ i ) {
            cin >> P[i];
        }
        SI Q_;
        Q_.insert( 0 );
        for ( int i = 0; i < n; ++ i ) {
            Q_.insert( P[i] );
            for ( int j = 0; j < n; ++ j ) {
                Q_.insert( P[i] + P[j] );
            }
        }
        VI Q( Q_.begin(), Q_.end() );
        INT answer = 0;
        for ( VI ::iterator it_i = Q.begin(); it_i != Q.end(); ++ it_i ) {
            for ( VI ::iterator it_j = Q.begin(); it_j != Q.end(); ++ it_j ) {
                if ( *it_i + *it_j > m ) continue;
                answer = max( answer, *it_i + *it_j );
            }
        }
        cout << answer << endl;
    }
    return 0;
}

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

int n, m, point1[1001], sum, ans;
vector<int> point2;

int solve(int start, int end, int border){
    int mid;
    while(1){
        if((end + start) % 2){
            mid = (end + start) / 2 + 1;
        } else{
            mid = (end + start) / 2;
        }

        if(point2[mid] > border){
            end = mid;
        } else{
            start = mid;
        }

        if(end - start == 1){
            if(point2[end] < border){
                return point2[end];
            } else{
                return point2[start];
            }
        }
    }
}

int main(){
    while(cin >> n >> m && n && m){
        for(int i = 0; i < n; i++){
            cin >> point1[i];
        }
        for(int i = 0; i < n + 1; i++){
            for(int j = 0; j < n + 1; j++){
                point2.push_back(point1[i] + point1[j]);
            }
        }

        sort(point2.begin(), point2.end());

        for(int i = 0; i < n + 1; i++){
            if(point2[i] > m){
                continue;
            }
            ans = max(ans, point2[i] + solve(0, point2.size() - 1, m - point2[i]));
        }

        cout << ans << endl;

        memset(point1, 0, sizeof(point1));
        point2.clear();
        ans = 0;
    }

    return 0;
}

C++: #include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <cmath>
#include <limits>
#include <functional>

#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(i,m,n) for(int i=m;i<n;i++)
#define FORR(i,m,n) for(int i=m;i>=n;i--)
#define pb(x) push_back(x) 
#define SORT(x) sort((x).begin(),(x).end())
#define INF 999999999

using namespace std;

#define int long long

signed main(){
	int n, m;
	cin >> n >> m;
	vector<int> p(n);
	REP(i, n){
		cin >> p[i];
	}
	p.push_back(0);
	sort(p.begin(), p.end());
	n++;
	
	vector<int> v;
	REP(i, n){
		REP(j, n){
			v.push_back(p[i]+p[j]);
		}
	}
	SORT(v);
	
	int l=0, r=v.size()-1, ans=0;
	REP(i, 1000000){
		int k=v[l]+v[r];
		if(k>m){
			if(r>0) r--;
		}
		else if(k<=m){
			ans=max(ans, k);
			if(l<v.size()-1) l++;
		}
	}
	
	cout << ans << endl;
}

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

#define MAX_N 1001

using namespace std;

int BinSearch(int v[], int vsize, int search){
	int l = 0;
	int r = vsize;
	int m = 0;
	if( v[r - 1] < search ){
		return r - 1;
	}else if(v[1] > search ){
		return 0;
	}
	while( r - 1 > l ){
		m = (r + l) / 2;

		if( v[m] > search ){
			r = m;
		}else if(v[m] == search){
			return m;
		}else{
			l = m;
		}
	}
	return m;
}

void Merge(int a[], int p ,int q, int r){
	int i, j;
	int n1 = q - p;
	int n2 = r - q;
	int *L = new int[n1];
	int *R = new int[n2];

	for(i = 0; i < n1; i++)
		L[i] = a[p + i];

	for(j = 0; j < n2; j++)
		R[j] = a[q + j];

	i = 0;
	j = 0;

	for(int k = p; k < r; k++){
		if( i == n1 ){
			while( j < n2 ){
				a[k] = R[j];k++;j++;
			}
			break;
		}else if( j == n2 ){
			while( i < n1 ){
				a[k] = L[i];k++;i++;
			}
			break;
		}else{
			if( L[i] <= R[j] ){
				a[k] = L[i];
				i++;
			}else{
				a[k] = R[j];
				j++;
			}
		}
	}

	delete[] L;
	delete[] R;
}

void InsertionSort(int *a, int n){
	for(int i = 1; i < n; i++){
		int v = a[i], j;
		for(j = i; j > 0; j--)
			if( v < a[j - 1])
				a[j] = a[j - 1];
			else
				break;
		a[j] = v;
	}
}

void MergeSort(int a[], int p, int r){
	if( p < r ){
		if( r - p < 9 ){
			InsertionSort(a + p, r - p);
			return ;
		}
		int q = (p + r) / 2;
		MergeSort(a, p, q);
		MergeSort(a, q, r);
		Merge(a, p, q, r);
	}
}

int main(void){
	while( true ){
		int prevQ = -1;
		int index = 0;
		int Max = 0;
		int N, M;
		int *Q;
		int V[MAX_N];

		cin >> N >> M;
		
		if( N == 0 && M == 0 ){
			break;
		}

		for(int i = 0; i < N; i++){
			cin >> V[i];
		}
		V[N] = 0;
		N++;

		Q = new int[N*N];

		for(int i = 0; i < N; i++){
			for(int j = 0; j < N; j++){
				Q[i * N + j] = V[i] + V[j];
			}
		}
		//cout << "Sorting..." << endl;
		/*for(int i = 0; i < N * N; i++){
			cout << Q[i] << '\n';
		}*/
		
		MergeSort(Q, 0, N * N);
		//stable_sort(Q.begin(), Q.end());

		//cout << "Sorted:" << endl;
		/*for(int i = 0; i < N * N; i++){
			cout << Q[i] << '\n';
		}*/

		//cout << "Uniqing..." << endl;
		//Uniq( Q );

		for(int i = 0; i < N * N; i++){
			//cout << Q[i];
			if( prevQ == Q[i] ){
				continue;
			}else{
				prevQ = Q[i];
			}
			int optim = BinSearch(Q, N*N, M - Q[i]);
			//cout << ' ' << optim << ":" << Q[optim] << '\n';
			if( optim > 0 && Q[i] + Q[optim] > M) optim--;
			Max = max( Max , Q[i] + Q[optim] > M ? 0 : Q[i] + Q[optim]);
		}

		delete[] Q;
		cout << Max << '\n';
	}
	return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<cstdio>
#include<map>
#include<algorithm>
#include<stack>
#define P pair<int,int>
using namespace std;

int g[1000005];
int main() {
	int a, b, c[1001];
	while (scanf("%d%d", &a, &b), a | b) {
		for (int d = 0; d < a; d++)scanf("%d", &c[d+1]);
		c[0] = 0;
		int sum = 0;
		for (int e = 0; e <= a; e++) {
			for (int f = e; f <= a; f++) {
				g[sum] = c[e] + c[f];
				sum++;
			}
		}
		sort(g, g + sum);
		int MAX = 0;
		for (int l = 0; l < sum; l++) {
			auto x = upper_bound(g, g + sum, b - g[l]);
			x--;
			printf("%d %d\n", g[l], *x);
		if(g[l]<=b)	MAX = max(MAX, g[l] + *x);
		}
		cout << MAX << endl;
	}
}