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 <math.h>
#include <utility>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int s = 0;
int M = 0;
vector<int> p;

int kansu(int b,int e,int c,int d) {	//b〜eの範囲を調べる cが残りの得点 dが残りのダーツ数(自身含む)
	int x = b;
	int y = e;
	while(true) {
		int k = ( x + y + 1 ) / 2;
		if ( k == y ) {
			break;
		}
		double l = c / d;
		if ( p[k] < l ) {
			s = max( s , ( M - c ) + p[k] * d);
			x = k;
			continue;
		}else if ( p[k] == l ) {
			s = M;
			return 1;
		}else {
			y = k;
			continue;
		}
	}
	for ( int i = x; i <= e; i++ ) {
		if ( p[i] > c ) {
			s = max( s, M-c );
			return 0;
		}else if ( p[i] == c ) {
			s = M;
			return 1;
		}else {
			if ( d == 1 ) {
				s = max( s, (M-c) + p[i] );
			}else {
				if ( kansu( 0, i, c-p[i], d-1 ) == 1 ) return 1;
			}
		}
	}
	return 0;
}

int main(){
	int n;
	while(true) {
		cin >> n >> M;
		if ( n == 0 ) break;
		p.clear();
		int k;
		for ( int i = 0; i < n; i++ ) {
			cin >> k;
			p.push_back(k);
		}
		sort(p.begin(),p.end());
		s = 0;
		kansu( 0, n-1, M, 4 );
		cout << s << endl;
	}
	return 0;
}

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

#define MAX_N 1001

using namespace std;

int main(void){
	while( 1 ){
		int n, m;
		int V[MAX_N] = {0,};
		int D[MAX_N][4] = {0,{0,}};
		int Max = 0;

		cin >> n >> m;

		if( n == 0 && m == 0 ){
			break;
		}

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

		sort(V, V + n);
		reverse(V, V + n);

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				D[i][j] = V[i];
				if( j > 0 ){
					int thisMax = 0;
					for(int k = 0; k <= i; k++){
						int tmp = D[i][j] + D[k][j - 1];
						thisMax = max(thisMax, tmp > m ? 0 : tmp);
					}
					if( thisMax > D[i][j] ){
						D[i][j] = thisMax;
					}
				}
			}
		}

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				//cout << D[i][j] << ' ';
				if( D[i][j] <= m ){
					if( Max < D[i][j] ){
						Max = D[i][j];
					}
				}
			}
			//cout << '\n';
		}

		cout << Max << '\n';
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;

int main(){
    int n;
    ll m;
    while(cin >> n >> m, n){
        n++;
        vector<ll> p(n,0);
        for(int i = 1; i < n; i++)  cin >> p[i];
        vector<ll> a;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                a.push_back(p[i]+p[j]);
            }
        }
        sort(a.begin(), a.end());
        ll ans = 0;
        for(int i = 0; i < n*n; i++){
            if(a[i] > m)    break;
            ans = max(ans, a[i] + *(--upper_bound(a.begin(),a.end(),m-a[i])));
        }
        cout << ans << endl;
    }
    return 0;
}

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

#define N 1000
#define M 200000000

typedef long long ll;

#define max(a,b) (a>b?a:b)

int main() {
	ll dp[N+1][5], ans;
	ll n, m, a[N+1];
	while(1) {
		cin >> n >> m;
		if(!n&&!m) break;
		for(int i=1; i<=n; ++i) cin >> a[i];
		for(int i=0; i<=n; ++i) {
			for(int j=0; j<5; ++j) dp[i][j] = 0;
		}
		ans = 0;
		for(int i=1; i<=n; ++i) {
			for(int j=1; j<5; ++j) {
				dp[i][j] = dp[i-1][j];
				for(int k=1; k<=j; ++k) {
					if(dp[i-1][j-k]+a[i]*k<=m) {
						dp[i][j] = max(dp[i][j], dp[i-1][j-k]+a[i]*k);
					}
				}
			}
		}
		for(int i=0; i<5; ++i) ans = max(ans, dp[n][i]);
		cout << ans << endl;
	}
	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; ++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++: int main(){
 return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
    int N;
    long long M;
    while(cin>>N>>M&&N+M){
        vector<int> line(N+1);
        for(int i=0;i<N;++i){
            cin>>line[i];
        }
        line[N]=0;
        vector<int> data;
        for(int i=0;i<=N;++i){
            for(int j=0;j<=N;++j){
                data.push_back(line[i]+line[j]);
            }
        }
        sort(data.begin(),data.end());
        int right = data.size()-1;
        int ans = 0;
        for(int left = 0;left<data.size();++left){
            while(right>0&&(long long)data[right]+data[left]>M){
                --right;
            }
            if((long long)data[right]+data[left]<=M){
                ans = max(ans,data[right]+data[left]);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

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

int N,M;
int NN;
int *dd;
int *d;

int search(int var)
{
	int i = 0, j = NN-1;
	int cut;

	while(i != j){
		cut = (i+j)/2;
		if(dd[cut] + var > M){
			j = cut;
		}
		else if(dd[cut] + var < M){
			i = cut+1;
		}
		else
			return dd[cut] + var;

	}

	if(var + dd[cut] <= M)
		return dd[cut] + var;

	return -1;
}
int main(void)
{


	while(	cin >> N >> M, N && M){

	NN = (N+1) * (N+1);
	d = new int [N+1];
	dd = new int [NN];

	d[0] = 0;

	for(int i = 1; i <= N; i++)
		cin >> d[i];

	int c = 0;
	for(int i = 0; i <= N; i++)
		for(int j = 0; j <= N; j++,c++)
			dd[c] = d[i] + d[j];

	sort(dd,dd+NN);

	c = 0;
	int num = 0;
	int MAX = 0;

	for(int i = 0; i < NN; i++){
		if(dd[i] > M)
			break;

		num = search(dd[i]);

		if(num > MAX)
			MAX = num;
	}
	cout << MAX << endl;
		

	delete [] d;
	delete [] dd;
	}
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;
int n,m;
int num[1001];
long long sum[1000005];
int main(){
	while(1){
	scanf("%d %d",&n,&m);
	if(!n) break;
	for(int i=0;i<n;i++){
		scanf("%d",&num[i]);
	}
	int ro=0;
	for(int i=0;i<n;i++){
		for(int j=i;j<n;j++){
			sum[ro]=num[i]+num[j];
			ro++;
		}
	}
	long long ans=0;
	sort(sum,sum+ro);
	for(int i=0;i<ro;i++){
		if(sum[i]>m){ break;}
		int rp=lower_bound(sum,sum+ro,m-sum[i])-sum;
		if(!rp){
			ans=max(ans,sum[i]);
		}else{
			rp--;
			ans=max(ans,sum[i]+sum[rp]);
		}
	}
	printf("%d\n",ans);
}
	return 0;
}