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++: #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 = (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];

	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 - 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 <vector>
#include <algorithm>

using namespace std;

int main(){

	int n,m;
	while(cin>>n>>m&&!(n==0&&m==0)){
		int scores[1001];
		int comb[1000001];
		int cn=0;

		for(int i = 0; i < n; i++)
			cin>>scores[i];
		scores[n]=0;
		for(int i = 0; i < n+1; i++){
			for(int j = 0; j < n+1; j++){
				int sum=scores[i]+scores[j];
				if(sum<=m){
					comb[cn]=sum;
					cn++;
				}
			}
		}
		sort(comb,comb+cn);

		int maxNum=0;
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				int left = (scores[i]+scores[j]);
				if(left<=m&&comb[0]+left<=m){
					int *it = lower_bound(comb,comb+cn,m-left);
					if(it==comb+cn)
						maxNum=max(maxNum,comb[cn-1]+left);
					else{
						if(*it==(m-left))
							maxNum=m;
						else{
							it--;
							maxNum=max(maxNum,*it+left);
						}
					}
				}
			}
		}
		cout<<maxNum<<endl;
	}

	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i, s, n) for(int i = s; i < (int)n; i++)
#define per(i, n) for(int i = n; i >= 0; i--)
#define ROF(i, s, n) for(int i = s; i >= (int)n; i--)
#define FORIT(i, A) for (auto i : A)
#define PRINT(x) cout << (x) << "\n"
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define MP make_pair
#define EACH(i, n) for (__typeof((n).begin()) i = (n).begin(); i != (n).end(); ++i)
#define SZ(a) int((a).size())
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define CLR(a) memset((a), 0 ,sizeof(a))
#define dump(x) cout << #x << " = " << (x) << "\n";
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << "\n";
#define sq(n) (n) * (n)
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef priority_queue<int> maxpq;
typedef priority_queue< int, vector<int>, greater<int> > minpq;
static const double EPS = 1e-10;
static const double PI = acos( -1.0 );
static const int mod = 10007;
static const int INF = 1 << 25;
static const LL LL_INF = 1152921504606846976;
static const int dx[] = { 1, -1, 0,  0 };
static const int dy[] = { 0,  0, 1, -1 };

int n, m, ans;
VI ar;
int solve( int now, int d, int cnt ) {
	if ( now == n || d + ar[ now ] > m || cnt == 4 ) {
		return d;
	}
	return max( solve( now, d + ar[ now ], cnt + 1 ), solve( now + 1, d, cnt ) );
}
int main() {
	while ( ~scanf( "%d %d", &n, &m ) && n && m ) {
		ar.resize( n );
		for ( int i = 0; i < n; i++ ) {
			scanf( "%d", &ar[ i ] );
		}
		sort( ar.begin(), ar.end() );
		ans = solve( 0, 0, 0 );
		printf( "%d\n", ans );
	}
	return 0;
}

C++: //Bokan ga bokka--nn!!
//Daily Lunch Special Tanoshii !!
//これは、頭が悪く競プロが世界で一番できないHIR180が
//IOI2014日本代表になるまでのN日間の記録である。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cassert>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define f first
#define s second
#define rep(i,x) for(int i=0;i<x;i++)
int zip[1005*505],num[1005];
int main()
{
	srand((unsigned int)time(NULL));
	while(1)
	{
		int n,lim;
		scanf("%d%d",&n,&lim); if(!n) return 0;
		int id=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&num[i]);
		}
		num[0]=0;
		for(int i=0;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				zip[id++]=num[i]+num[j];
			}
		}
		sort(zip,zip+id);
		int ret=0;
		for(int i=0;i<id&&lim>=zip[i];i++)
		{
			int x=upper_bound(zip,zip+id,lim-zip[i])-zip;
			if(!x) break;
			ret=max(ret,zip[i]+zip[x-1]);
		}
		printf("%d\n",ret);
	}
}