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

		rep(i, N + 1) rep(j, i + 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 <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> *points;
vector<int> *twice;

void deldup(vector<int> *vec) {
    vector<int>::iterator it = vec->begin();
    bool is_straight = false;
    int save = -1;

    while (it != vec->end()) {
        if (*it == save) {
            vec->erase(it++);
            is_straight = true;
            continue;
        } else {
            save = *it;
            if (is_straight) {
                vec->erase(it++);
                is_straight = false;
                continue;
            }
            is_straight = false;
        }
        it++;
    }
}

int search(vector<int> *target, int standard) {
    int ind;
    int min = 0;
    int max = target->size() - 1;

    while (1) {
        ind = (min + max)/2;

        if (max - min <= 1) return target->at(min);

        if (target->at(ind) <= standard) {
            min = ind;
        } else {
            max = ind;
        }
    }
}

int main() {
    while (1) {
        int i;
        int n, m;
        int max = 0;

        scanf("%d %d", &n, &m);
        if (n == 0 && m == 0) return 0;

        points = new vector<int>();
        twice = new vector<int>();

        points->push_back(0);
        for (i=0;i<n;i++) {
            int k;
            scanf("%d", &k);
            points->push_back(k);
        }

        vector<int>::iterator it1 = points->begin();
        while (it1 != points->end()) {
            vector<int>::iterator it2 = points->begin();
            while (it2 != points->end()) {
                twice->push_back(*it1 + *it2);
                it2++;
            }
            it1++;
        }

        sort(points->begin(), points->end());
        sort(twice->begin(), twice->end());

        vector<int>::reverse_iterator rit1 = twice->rbegin();
        while (rit1 != twice->rend()) {
            if (*rit1 <= m) {
                int got = *rit1 + search(twice, m - *rit1);
                if (max < got) max = got;
            }
            rit1++;
        }

        printf("%d\n", max);
    }
}

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