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 <iostream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

int main() {
	int n;
	long long int m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		long long int b;
		vector<long long int> ss;
		ss.push_back(0);
		for (int i = 0; i < n; i++) {
			cin >> b;
			if (b <= m) {
				ss.push_back(b);
			}
		}
		vector<long long int> ss2;
		for (vector<long long int>::iterator ite = ss.begin(); ite != ss.end(); ite++) {
			ss2.push_back(*(ite));
			for (vector<long long int>::iterator ite2 = ite; ite2 != ss.end(); ite2++) {
				if (*(ite)+*(ite2) <= m) {
					ss2.push_back(*(ite)+*(ite2));
				} else {
					break;
				}
			}
		}
		sort(ss2.begin(), ss2.end());
		long long int a = m;
		for (long long int i = 0; i < 4; i++) {
			vector<long long int>::iterator ite = upper_bound(ss2.begin(), ss2.end(), a);
			ite--;
			a -= *(ite);
		}
		cout << m-a << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
#define loop(i,n) for (int i = 0; i < n; i++)
#define INF 100000000
int points = 0, max_point = 0;
vector<int> possible_points(0, 0);
int main()
{
	cin >> points >> max_point;
	vector<int> point(points);
	loop(i, points)cin >> point[i];
	point.push_back(0);
	loop(i, point.size())loop(j, point.size())
	{
		int x = point[i] + point[j];
		possible_points.push_back(x);
	}
	sort(possible_points.begin(), possible_points.end());
	ll  ans = -1;
	loop(i, possible_points.size())
	{
		auto t = upper_bound(possible_points.begin(), possible_points.end(), max_point - possible_points[i]) - 1;
		if (*t > 0)ans = max(ans, (possible_points[i] + (ll)*t));
	}
	cout << ans << endl;
	return 0;
}

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)continue;
            
            int pos = rev_lower_bound(right,m-num);
            
            maxi = max<ll>(maxi,num+right[pos]);
        }
        cout<<maxi<<endl;
    }
}

C++: #include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
//#include <utility>
#include <set>
#include <iostream>
//#include <memory>
#include <string>
#include <vector>
#include <algorithm>
//#include <functional>
#include <sstream>
//#include <deque>
#include <complex>
#include <stack>
#include <queue>
#include <cstdio>
//#include <cctype>
#include <cstring>
//#include <ctime>
#include <iterator>
#include <bitset>
//#include <numeric>
//#include <list>
//#include <iomanip>

#if __cplusplus >= 201103L
#include <array>
#include <tuple>
#include <initializer_list>
#include <unordered_set>
#include <unordered_map>
#include <forward_list>

#define cauto const auto&
#else

#endif

using namespace std;


namespace{
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef vector<int> vint;
typedef vector<vector<int> > vvint;
typedef vector<long long> vll, vLL;
typedef vector<vector<long long> > vvll, vvLL;

#define VV(T) vector<vector< T > >

template <class T>
void initvv(vector<vector<T> > &v, int a, int b, const T &t = T()){
    v.assign(a, vector<T>(b, t));
}

template <class F, class T>
void convert(const F &f, T &t){
    stringstream ss;
    ss << f;
    ss >> t;
}


#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define F first
#define S second
#define mkp make_pair
#define RALL(v) (v).rbegin(),(v).rend()


#define MOD 1000000007LL
#define EPS 1e-8
static const int INF=1<<24;

void mainmain(){
	int n,m;
	while(cin>>n>>m,n||m){
		// cout<<n<<" "<<m<<endl;
		vint v(n);
		rep(i,n){
			cin>>v[i];
		}
		v.PB(0);
		// set<int> se;
		vint se;
		rep(i,n+1){
			rep(j,n+1){
				// se.insert(v[i]+v[j]);
				se.PB(v[i]+v[j]);
			}
		}
		sort(ALL(se));
		se.erase(unique(ALL(se)),se.end());
		// cout<<(int)se.size()<<endl;
		// se.insert(0);
		int ans=0;
		for(auto i:se){
			if(i>m) break;
			auto it=upper_bound(ALL(se),m-i);
			it--;
			ans=max(ans,i+*it);
		}
		cout<<ans<<endl;
	}
}



}
main() try{
    mainmain();
}
catch(...){
}

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

using namespace std;

const int MAX_N=1000;

int N,M;
int P[MAX_N];

int comb[MAX_N*MAX_N];

vector<int> out;

int main(){
	do{
		scanf("%d %d",&N,&M);
		if (N!=0 || M!=0){
			int i,j;
			for (i=0;i<N;i++){
				scanf("%d",&P[i]);
			}
			for (i=0;i<N;i++){
				for (j=0;j<N;j++){
					comb[i*N+j]=P[i]+P[j];
				}
			}
			sort(comb,comb+N*N);
			int ma=0;
			//???????????´???
			for (i=0;i<N;i++){
				if (P[i]<=M){
					ma=max(ma,P[i]);
				}
			}
			//???????????´???
			int *p;
			p=upper_bound(comb,comb+N*N,M);
			if (p!=comb){
				ma=max(ma,*(p-1));
			}
			//???????????´???
			for (i=0;i<N;i++){
				p=upper_bound(comb,comb+N*N,M-P[i]);
				if (p!=comb){
					ma=max(ma,P[i]+*(p-1));
				}
			}
			//???????????´???
			for (i=0;i<N;i++){
				for (j=0;j<N;j++){
					p=upper_bound(comb,comb+N*N,M-P[i]-P[j]);
					if (p!=comb){
						ma=max(ma,P[i]+P[j]+*(p-1));
					}
				}
			}
			out.push_back(ma);
		}
	}while (N!=0 || M!=0);
	for (int i=0;i<out.size();i++){
		printf("%d\n",out[i]);
	}
	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;
	}
}