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 <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef double db;

#define fr first
#define sc second
#define pb push_back
#define rep(i,x) for(ll i=0;i<x;i++)
#define rep1(i,x) for(ll i=1;i<=x;i++)
#define rrep(i,x) for(ll i=x-1;i>=0;i--)
#define rrep1(i,x) for(ll i=x;i>0;i--)

ll n,m;
ll p[1000];
vector<ll> v;
int main()
{while(1){
	v.clear();
	cin>>n>>m;
	if(!n) break;
	p[0]=0;
	rep1(i,n) cin>>p[i];
	rep(i,n+1) rep(j,n+1){
		v.pb(p[i]+p[j]);
	}
	sort(v.begin(),v.end());
	ll ans;
	ans=0;
	//ans=v[upper_bound(v.begin(),v.end(),m)-v.begin()-1];
	rep(i,n+1) rep(j,n+1){
		if(p[i]+p[j]<=m) ans=max(ans,v[upper_bound(v.begin(),v.end(),m-p[i]-p[j])-v.begin()-1]+p[i]+p[j]);
	}
	//for(ll i=n/2;i<n;i++) if(p[i]<=m) ans=max(ans,v[upper_bound(v.begin(),v.end(),m-p[i])-v.begin()-1]+p[i]);
	//for(ll i=n/2;i<n;i++) for(ll j=i+1;j<n;j++) if(p[i]+p[j]<=m) ans=max(ans,v[upper_bound(v.begin(),v.end(),m-p[i]-p[j])-v.begin()-1]+p[i]+p[j]);
	cout<<ans<<endl;
}}

C++: #include<stdio.h>
#include<iostream>
#include<algorithm>
int main(){
while(1){
int i,n,j,m,s=0,l,k;
static int p[1001]={0};
scanf("%d%d",&n,&m);
if(n==0&&m==0)return 0;
for(i=1;i<=n;i++)scanf("%d",&p[i]);
for(i=0;i<=n;i++){
for(j=0;j<=n;j++){
for(l=0;l<=n;l++){
for(k=0;k<=n;k++){
if(p[i]+p[j]+p[l]+p[k]<=m&&p[i]+p[k]+p[j]+p[l]>s)s=p[i]+p[j]+p[l]+p[k];
}
}
}
}
printf("%d\n",s);
}
return 0;
}

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

using namespace std;

int main() {
	int n, m;

	while (cin >> n >> m, n && m) {
		vector<int> point(n + 1);
		vector<int> sum;
		for (int i = 0; i < n; i++) {
			cin >> point[i];
		}
		for (int i = 0; i < n + 1; i++) {
			for (int j = i; j < n + 1; j++) {
				sum.push_back(point[i] + point[j]);
			}
		}
		sort(sum.begin(), sum.end());

		int ans = 0;
		for (int i = 0; i < sum.size(); i++) {
			int t = m - sum[i];
			cout << "t = " << t << endl;
			vector<int>::iterator it = upper_bound(sum.begin(), sum.end(), t);
			if (it != sum.begin()) {
				ans = max(ans, sum[i] + * (it - 1));
			}
		}
		cout << ans << endl;
	}
}

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

using namespace std;

int m,n;
int a[1002];

int ans,Max;

void bin_search(int *aa,int x){
	int l=0,r=n*n;
	Max=0;
	
	while (l<=r) {
		int i=(l+r)/2;
		if (aa[i]<x&&aa[i]>Max) {
			Max=aa[i];
		}
		if(aa[i]<x)l=i+1;
		else r=i-1;
	}
}

void solve(){
	int aa[1002*1002]={0};
	for(int c=0;c<n;c++){
		for (int d=0; d<n; d++) {
			aa[c*n+d]=a[c]+a[d];
		}
	}
	sort(aa,aa+n*n);
	
	for (int i=0; i<n; i++) {
		for (int j=0; j<n; j++) {
			if (m-a[i]-a[i]>=0) {
				bin_search(aa,m-a[i]-a[j]);
				if (Max+a[i]+a[j]>ans) {
					ans=Max+a[i]+a[j];
				}
			}
		}
	}
	
}

int main(){
	
	while (1) {
		cin>>n>>m;
		ans=0;
		if (n==0&&m==0) {
			break;
		}
		for (int i=0; i<n; i++) {
			cin>>a[i];
		}
		a[n]=0;
		n++;
		solve();
		cout << ans << endl;
	}
	
	
}

C++: #include <bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	while(true){
		cin>>n>>m;
		if(n==0)	return 0;
		vector<int> p(n);
		for(int i=0;i<n;i++)	cin>>p[i];
		p.push_back(0);	n++;
		vector<int> s;
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++)	if(p[i]+p[j]<m)	s.push_back(p[i]+p[j]);
		}
		sort(s.begin(),s.end());
		int ans=0,fw=0,en=s.size()-1;
		while(true){
			if(s[fw]+s[en]>ans&&s[fw]+s[en]<=m)	ans=s[fw]+s[en];
			if(s[fw]+s[en]<=m)	fw++;
			else 	en--;
			if(fw>en)	break;
		}
		cout<<ans<<endl;
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	while(true){
		cin>>n>>m;
		if(n==0)	return 0;
		vector<int> p(n);
		for(int i=0;i<n;i++)	cin>>p[i];
		p.push_back(0);	n++;
		set<int> s;
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++)	s.insert(p[i]+p[j]);
		}
		int ans=0;
		set<int>::iterator prev=s.end();
		for(set<int>::iterator it=s.begin();it!=s.end();it++){
			if(*it>=m)	break;
			set<int>::iterator it2=s.lower_bound(m-*it);
			if(it2!=s.begin())	it2--;
			if(it==s.begin())	prev=it2;
			ans=max(ans,*it+*it2);
			if(prev==it)	break;
		}
		cout<<ans<<endl;
	}
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()
#define DEBUG 0

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
string FILE_NAME = "testcase.dart";
string NAME;
string itos (int n )
{
	stringstream ss;
	ss << n;

	return ss.str();
}

/*
	解法３ O(n^2log(n))
	
	3本の矢を投げて、残りの矢を２分探索する
*/
int n, m, k;
int p[1005];
int s[1005];

bool query (int c, int sum )
{
	return (sum + s[c] <= m );
}

int solve (int sum )
{
	int L = 0;
	int R = k;
	while( R-L > 1 ){
		int C = (L+R)/2;
		(query(C, sum ) ? L : R ) = C;
	} // end while

	return sum + s[L]; 
}
int main()
{
//	cut here before submit 
#if DEBUG
	NAME = FILE_NAME;
	int CNT = 1;
	NAME += itos (CNT );
	while (freopen (NAME.c_str() , "r", stdin ) != NULL ) {
#endif
	while (scanf ("%d %d", &n, &m ), n, m ){
		memset (p, 0, sizeof (p ) );
		memset (s, 0, sizeof (s ) );
		for (int i = 1; i <= n; i++ )	scanf ("%d", &p[i] );
		sort (p, p+n+1 );
		k = 0;
		for (int a = 0; a <= n; a++ ){
			for (int b = 0; b <= n; b++ ){
				if (p[a] + p[b] > m ) continue;
				s[k++] = p[a] + p[b];
			} // end for
		} // end for

		sort (s, s+k );

		int res = 0;
		rep (i, k ){
			int curr = solve (s[i] );	
			res = max (res, curr );
		} // end rep

		printf ("%d\n", res );
	} // end while
#if DEBUG
	CNT++;	// cut here before submit
	NAME = FILE_NAME;
	NAME += itos (CNT );
	} // end loop; cut here before submit
#endif			
	return 0;
}