Go: ///
// File:  0529.go
// Author: ymiyamoto
//
// Created on Wed Feb 28 20:39:28 2018
//
package main

import (
	"fmt"
	"sort"
)

func max(n, m int) int {
	if n < m {
		return m
	} else {
		return n
	}
}

func main() {
	for {
		var N, M int
		fmt.Scan(&N, &M)
		if N == 0 && M == 0 {
			break
		}

		arr := make([]int, N+1)
		for i := 1; i <= N; i++ {
			fmt.Scan(&arr[i])
		}
		sort.Ints(arr)

		sums := make([]int, 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.Ints(sums)

		m := 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>

#define MAX_N 1001

using namespace std;

class CNum{
public:
	vector<int> v;
};

bool Find(vector<int> &v, int search){
	for(unsigned int i = 0; i < v.size(); i++){
		if( v[i] == search ){
			return true;
		}
	}
	return false;
}

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

		cin >> n >> m;

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

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

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

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				if( j == 0 ){
					D[i][j].v.push_back( V[i] );
				}else if( j > 0 ){
					for(int k = 0; k <= i; k++){
						for(unsigned int l = 0; l < D[k][j - 1].v.size() > 0 ? 1 : 0; l++ ){
							int tmp = V[i] + D[k][j - 1].v[l];
							if( tmp <= m){
								if( !Find(D[i][j].v, tmp) ){
									D[i][j].v.push_back( tmp );
								}
							}
						}
					}
				}
			}
		}

		for(int i = 0; i < n; i++){
			//cout << i << '\n';
			for(int j = 0; j < 4; j++){
				//cout << " " << j << ":" << '\n';
				for(unsigned int k = 0; k < D[i][j].v.size(); k++ ){
					//cout << D[i][j].v[k] << ' ';
					int tmp = D[i][j].v[k];
					if( tmp <= m && Max < tmp){
						Max = tmp;
					}
				}
				//cout << '\n';
			}
		}
		cout << Max << '\n';
	}
	return 0;
}

C++: #include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(b) - 1;i>=(a);i--)
#define REP(i,n) for(int i=0;i<(n);i++)
#define RREP(i,n) for(int i=n-1;i>=0;i--)

#define PB push_back
#define INF (1<<29)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define CLR(a) memset(a,0,sizeof(a))
const int dx[] = {-1,0,0,1},dy[] = {0,1,-1,0};

typedef long long int ll;

using namespace std;
int main(){
    while(true){
	ll n,m;
	cin >> n >> m;
	if(n == 0 && m == 0) break;
	n++;
	vector<ll> a(n);
	a[0] = 0;
	FOR(i,1,n){
	    cin >> a[i];
	}
	ll ans = 0;
	sort(ALL(a));
	FOR(i,0,n)FOR(j,i,n)FOR(k,j,n){
	    ll	p = m - (a[i]+a[j]+a[k]);
	    int h,mm,l;
	    h = n+1;
	    l = 0;
	    mm = (h+l)/2;
	    while(h-l>1){
		if(a[mm] > p) h = mm;
		else if(a[mm] < p)l = mm;
		else h = mm;
		mm = (h+l)/2;
	    }
	    if(a[i]+a[j]+a[k]+a[mm] <= m) ans = max(ans,a[i]+a[j]+a[k]+a[mm]);
	}
	cout << ans << endl;
    }
    return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
	while(1){
	int n,m,p,q=0,r=0,l=0,s=0,e=0,ans=0;
	cin>>n>>m;
		if(n==0 && m==0)
			break;
	vector<int> a,x;
	a.push_back(0);
	for(int i=0;i<n;i++){
		cin>>p;
		a.push_back(p);
	}
	q=n+1;
	//cout<<q<<endl;
	for(int i=0;i<q;i++){
		for(int j=0;j<q;j++){
			x.push_back(a[i]+a[j]);
		}
	}
	sort(x.begin(),x.end());
	//for(int i=0;i<q*q;i++)
	//cout<<x[i]<<' ';
	//cout<<endl;
	for(int i=0;i<q*q;i++){
		r=m-x[i];
		//cout<<r<<"を探します"<<endl;
		s=0;
		e=q*q;
		while(1){
			l=(s+e)/2;
			//cout<<"l="<<l<<endl;
			if(x[l]>r){
				e=l-1;
			}else if(x[l]<r){
				s=l+1;
			}
			if(s>=e || x[l]==r){
				if(x[i]+x[l]<=m)
				ans=max(ans,x[i]+x[l]);
				break;
			}
		}
	}
		cout<<ans<<endl;
	}
	return 0;
}

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 t = 0;
		long long sum = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j <= n; j++) {
				b[i*n + j] = a[i] + a[j];
				t++;
			}
		}
		for (int i = 0; i < t; i++) {
			for (int j = 0; j < t; j++) {
				if (b[i] + b[j] <= m) sum = max(sum, b[i] + b[j]);
			}
		}
		cout << sum << endl;
	}
}

C++: #include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef vector<int> VI;
typedef vector<vector<int> > VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;

int binary_search(int tmp_m, VI second) {
    if (tmp_m <= 0) {
        return 0;
    }
    int left = 0;
    int right = second.size() - 1;
    int mid = (left + right) / 2 + 1;
    while(1) {
        if (right - left <= 1) {
            return second[left];
        }
        mid = (left + right) / 2;
        if (second[mid] <= tmp_m) {
            left = mid;
        } else {
            right = mid;
        }
    }
    return 0;
}

int main(void) {
    while (1) {
        int n;
        int m;
        cin >> n >> m;
        if (n == 0 && m == 0) {
            break;
        }
        VI table(n + 1);
        VI first((n + 1) * (n + 1));
        VI second((n + 1) * (n + 1));

        table[0] = 0;
        for (int i = 0; i < n; i++) {
            cin >> table[i + 1];
        }
        sort(table.begin(), table.end());

        for (int i = 0; i < n + 1; i++) {
            for (int j = 0; j < n + 1; j++) {
                first[i * (n + 1) + j] = table[i] + table[j];
                second[i * (n + 1) + j] = table[i] + table[j];
            }
        }

        sort(first.begin(), first.end());
        sort(second.begin(), second.end());

        int ans = 0;
        for (int i = 0; i < (int)(first.size()); i++) {
            int total = first[i] + binary_search(m - first[i], second);
            /*
            cout << "START" << endl;
            cout << first[i] << " " << total << endl;
            cout << "TOTAL = " <<  total << endl;
            */
            if (total <= m) {
                ans = max(ans, total);
            }
            //cout << "END" << endl << endl;
        }
        //cout << "ANS = " <<  ans << endl;
        cout << ans << endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        ll N, M;
        cin >> N >> M;
        if (N == 0 && M == 0) break;
        vector<ll> P(N + 1);
        P.at(0) = 0;
        for (int i = 1; i <= N; ++i) {
            cin >> P.at(i);
        }
        vector<ll> V;
        for (int i = 0; i <= N; ++i) {
            for (int j = 0; j <= N; ++j) {
                V.push_back(P.at(i) + P.at(j));
            }
        }
        sort(V.begin(), V.end());

        ll ans = 0;
        for (int i = 0; i < V.size(); ++i) {
            auto itr = upper_bound(V.begin(), V.end(), M - V.at(i));
            if (itr == V.begin()) continue;
            ans = max(ans, V.at(i) + *(itr - 1));
        }
        cout << ans << endl;
    }

    return 0;
}