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+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++: #include<algorithm>

#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 + 1;
	int n2 = r - q;
	int *L = (int *)malloc(sizeof(int)*n1);
	int *R = (int *)malloc(sizeof(int)*n2);

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

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

	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++;
			}
		}
	}

	free(L);
	free(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 < 10 ){
			InsertionSort(a + p, r + 1 - p);
			return ;
		}
		int q = (p + r) / 2;
		MergeSort(a, p, q);
		MergeSort(a, q + 1, 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];
			}
		}

		sort(Q, Q+N*N);
		//0, N * N - 1);

		for(int i = 0; i < N * N; i++){
			if( prevQ == Q[i] ){
				continue;
			}else{
				prevQ = Q[i];
			}
			int optim = BinSearch(Q, N*N, M - Q[i]);
			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 <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 solve( VI Q, INT M ) {
    INT answer = 0;
    int n = Q.size();
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        if ( q + Q[R-1] < answer ) continue;
        if ( q + Q[R-1] > M ) continue;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t > M ) t = 0;
            answer = max( answer, t );
            if ( Q[p] > m ) {
                R = p - 1;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        VI P;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P.push_back( p );
        }
        P.push_back( 0 );
        SI Q_;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q_.insert( ( P[i] + P[j] > m ? 0 : P[i] + P[j] ) );
            }
        }
        cout << 0 << endl;
        // VI Q( Q_.begin(), Q_.end() );
        // cout << solve( Q, m ) << endl;
    }
    return 0;
}

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;

		rep(i, A.size()) {
			int tmp;

			int pos = upper_bound(all(A), M - A[i]) - A.begin();

			if (pos == A.size()) {
				tmp = A.back();
			} else if (pos - 1 == -1) {
				tmp = 0;
			} else {
				tmp = A[pos - 1];
			}

			if (A[i] + tmp <= M) {
				ma = max(ma, A[i] + tmp);
			}
		}

		cout << ma << endl;
	}
}

C++: #include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <iomanip>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;

int N,M;
int main() {
while(1){
	cin >> N >> M;
	if(N==0&&M==0)return 0;
	vector<int> in;
	for(int i=0;i<N;i++){
		int a;
		cin >> a;
		in.push_back(a);
	}
	in.push_back(0);
	vector<int> p;
	for(int i=0;i<in.size();i++){
		for(int j=i;j<in.size();j++){
			p.push_back(in[i]+in[j]);
		}
	}
	int s=0,t=p.size()-1;
	sort(p.begin(),p.end());
	int ret=0;
	while(s<=t){
		int v=p[s]+p[t];
		if(v<=M){
			ret=max(ret,v);
			s++;
		}
		else{
			t--;
		}
	}
	cout << ret << endl;
}
}