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 <bits/stdc++.h>
using namespace std;
#define int long long

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,int> plli;
typedef pair<int,pii> pipii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;

#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n);i>=0;i--)
#define rrep2(i,a,b) for (int i=(a);i>b;i--)
#define pb push_back
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()

const ll mod = 1e9 + 7;
const ll INF = 1<<30;
const int dx4[4] = {1, 0, -1, 0};
const int dy4[4] = {0, 1, 0, -1};
const int dx8[8] = {1, 1, 1, 0, 0, -1, -1, -1};
const int dy8[8] = {0, 1, -1, 1, -1, 0, 1, -1};
const double pi = 3.141592653589793;

int n, m;

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    while (n != 0) {
        int p[1005] = {};
        rep(i, n) cin >> p[i];
        vector<int> score;
        score.push_back(0);
        rep(i, n) score.push_back(p[i]);
        rep(i, n) rep(j, n) {
            score.push_back(p[i] + p[j]);
        }
        sort(all(score));
        score.erase(unique(all(score)), score.end());
        int ans = 0;
        rep(i, score.size()) {
            if (score[i] > m) break;
            int l = 0;
            int r = score.size() + 1;
            while (r - l > 1) {
                int mid = (r + l) / 2;
                if (score[i] + score[mid] <= m) l = mid;
                else r = mid;
            }
            int idx = l;
            if (score[i] + score[idx] > m) continue;
            ans = max(ans, score[i] + score[idx]);
        }
        cout << ans << endl;
        cin >> n >> m;
    }
}

C++: #include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cassert>
#include <functional>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define RSORT(c) sort((c).rbegin(),(c).rend())
#define CLR(a) memset((a), 0 ,sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = { -1, 0, 1, 0 }; const int dy[] = { 0, 1, 0, -1 };

int main() {
	int n, m;
	cin >> n >> m;
	vector<int> point(n);
	REP(i, n){
		cin >> point[i];
	}
	point.push_back(0);
	vector<int> sum = point;
	REP(i, n + 1){
		REP(j, n + 1){
			if (count(sum.begin(), sum.end(), sum[i] + sum[j]) == 0)
				sum.push_back(sum[i] + sum[j]);
		}
	}
		SORT(sum);
		int ma = 0;
		REP(i, sum.size()){
			int left = 0;
			int right = sum.size() - 1;
			while (left < right){
				if (sum[left + (right - left) / 2] + sum[i] <= m){
					ma = max(ma, sum[left + (right - left) / 2] + sum[i]);
					left = left + (right - left) / 2 + 1;

				}
				else{
					right = left + (right - left) / 2 - 1;
				}
			}
		}
		cout << ma << endl;
	}

C++: #include<iostream>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<functional>
#include<algorithm>
#include<cstdio>
using namespace std;
long long a[1001];
long long b[1000000];
int main() {
	int n, m;
	while (cin >> n >> m&&n != 0 && m != 0) {
		for (int i = 0; i < n; i++) {
			cin >> a[i];
		}
		a[n] = 0;
		int f = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = i; j <= n; j++) {
				b[f] = a[i] + a[j];
				f++;
			}
		}
		long long sum = 0;
		sort(b, b + f);
		for (int i = 0; i <= f; i++) {
			int s = 0, e = f, t;
			long long g = m - b[i];
			while (e - s > 1) {
				t = (e + s) / 2;
				if (b[t] > g) e = t;
				if (b[t] <= g) s = t;
			}
			if (b[i] + b[s] <= m) sum = max(sum, b[i] + b[s]);
			if (b[i] + b[e] <= m) sum = max(sum, b[i] + b[e]);
		}
		cout << sum << endl;
	}
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define vi vector<int>
#define INF 999999999


template<class T>
T rev_lower_bound(vector<ll> &vec,T num){
    ll left=0, right=vec.size()+1, mid=(left+right)/2LL;
    while(left+1<right){
        if(vec[mid]<=num) left = mid;
        else    right= mid;
        mid = (left+right)/2LL;
    }
    return mid;
}


int main(){
    
    int n,m;
    while(cin>>n>>m&&n&&m){
        vi p(n);
        rep(i,n)cin>>p[i];
        
        
        
        set<ll> val;
        val.insert(0);
        rep(i,n)val.insert(p[i]);
        rep(i,n)for(ll j=i;j<n;j++)val.insert(p[i]+p[j]);
        
        vector<ll> left,right;
        
        for(auto &v : val) left.pb(v);
        
        
        sort(all(left));
        right = left;
        
        ll maxi=0;
        rep(i,left.size()){
            ll num = left[i];
            if(num>m)break;
            
            int pos = rev_lower_bound(right,m-num);
            
            maxi = max<ll>(maxi,num+right[pos]);
        }
        cout<<maxi<<endl;
    }
}