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<iostream>
#include<string>
#include<vector>
#include<cstdio>
#include<map>
#include<algorithm>
#include<stack>
#define P pair<int,int>
using namespace std;

int g[1000005];
int main() {
	int a, b, c[1001];
	while (scanf("%d%d", &a, &b), a | b) {
		for (int d = 0; d < a; d++)scanf("%d", &c[d+1]);
		c[0] = 0;
		int sum = 0;
		for (int e = 0; e <= a; e++) {
			for (int f = e; f <= a; f++) {
				g[sum] = c[e] + c[f];
				sum++;
			}
		}
		sort(g, g + sum);
		int MAX = 0;
		for (int l = 0; l < sum; l++) {
			auto x = upper_bound(g, g + sum, b - g[l]);
			x--;
			if(g[l]<=b)MAX = max(MAX, g[l] + *x);
		}
		cout << MAX << endl;
	}
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<climits>

using namespace std;

int main() {
	long long   m[10], t[10][1000]{ 0 }, a[1000];
	int n[10], i = 0;
	while (1) {
		cin >> n[i] >> m[i];
		if (n[i] == 0)break;
		for (int j = 0; j < n[i]; j++)cin >> t[i][j];
		i++;
	}
	for (int k = 0; k < i; k++) {
		long long ans = 0;
		for (int j = 0; j < n[k]; j++)a[j] = t[k][j];
		sort(a, a + n[k]);
		for (int p = n[k] - 1; p >= 0; p--) {
			if (a[p] > m[k])continue;
			else if (a[p] == m[k]) {
				ans = m[k];
				goto ANS;
			}
			else if (ans > a[p] * 4)goto ANS;
			else {
				ans = max(ans, a[p]);
				if (m[k] < a[p] + a[0])break;
				for (int q = p; q >= 0; q--) {
					if (a[p] + a[q] > m[k])continue;
					else if (a[p] + a[q] == m[k]) {
						ans = m[k];
						goto ANS;
					}
					else if (ans > a[p] + a[q] * 3)break;
					else {
						ans = max(ans, a[p] + a[q]);
						if (m[k] < a[p] + a[q] + a[0])break;
						for (int r = q; r >= 0; r--) {
							if (a[p] + a[q] + a[r] > m[k])continue;
							else if (a[p] + a[q] + a[r] == m[k]) {
								ans = m[k];
								goto ANS;
							}
							else if (ans > a[p] + a[q] + a[r] * 2)break;
							else {
								ans = max(ans, a[p] + a[q] + a[r]);
								if (m[k] < a[p] + a[q] + a[r] + a[0])break;
								for (int s = r; s >= 0; s--) {
									if (a[p] + a[q] + a[r] + a[s] > m[k])continue;
									else if (a[p] + a[q] + a[r] + a[s] == m[k]) {
										ans = m[k];
										goto ANS;
									}
									else if (ans > a[p] + a[q] + a[r] + a[s])break;
									else ans= a[p] + a[q] + a[r] + a[s];
								}
							}
						}
					}
				}
			}
		}
	ANS:
		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==0&&m==0)){
		int scores[1001];
		vector<int> comb;
		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.push_back(sum);
			}
		}
		sort(comb.begin(),comb.end());
		comb.erase(unique(comb.begin(),comb.end()),comb.end());

		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){
					vector<int>::iterator it = lower_bound(comb.begin(),comb.end(),m-left);
					if(it==comb.end()){
						maxNum=max(maxNum,comb[comb.size()-1]+left);
					}
					else{
						if(*it==(m-left)){
							maxNum=m;
						}
						else{
							it--;
							maxNum=max(maxNum,*it+left);
						}
					}
				}
			}
		}
		cout<<maxNum<<endl;
	}

	return 0;
}

C++: #include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<queue>
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) for(int i=0;i<(n);i++)
using namespace std;
typedef long long ll;


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	
	int N;
	ll M;
	cin >> N >> M;
	if (N == 0 && M == 0) return 0;
	vector<ll> P(N + 1);
	REP(i, N) cin >> P[i];
	P[N] = 0;
	vector<ll> sum((N + 1) * (N + 1));
	REP(i, N + 1)REP(j, N + 1) sum[(N + 1) * i + j] = P[i] + P[j];
	sort(sum.begin(),sum.end());
	ll res = 0;
	REP(i, N + 1)REP(j, N + 1) {
		if (sum[(N + 1) * i + j] <= M) {
			int n = upper_bound(sum.begin(), sum.end(), M - sum[(N + 1) * i + j]) - sum.begin() - 1;
			res = max(res, sum[(N + 1) * i + j] + sum[n]);
		}
	}
	cout << res << "\n";

	return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using int64 = int64_t;

constexpr int64 MOD = 1000000007;

int N, M, arr[1000];

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    while (true) {
        cin >> N >> M;
        if (N == 0 && M == 0) break;
        arr[0] = 0; ++N;
        for (int j = 1; j < N; ++j) {
            cin >> arr[j];
        }
        int arr2[1002*1002];
        for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
            arr2[N*j+k] = arr[j] + arr[k];
        }
        sort(arr2, arr2+N*N);

        int ans = 0;
        for (int j = 0; j < N*N; ++j) {
            if (arr2[j] > M) break;
            ans = max(ans, arr2[j] + *(upper_bound(arr2, arr2+N*N, M-arr2[j])-1));
        }
        cout << ans << endl;
    }
    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 P[1001];
INT Q[1002001];

INT solve( int N, INT M ) {
    INT answer = 0;
    for ( int i = 0; i < N; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = N;
        INT m = M - q;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t <= M ) 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;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P[i] = p;
        }
        P[n] = 0;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q[i * ( n + 1 ) + j] = P[i] + P[j];
            }
        }
        int length = ( n + 1 ) * ( n + 1 );
        sort( Q, Q + length );
        cout << solve( length, m ) << endl;
    }
    return 0;
}