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 <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];
        }
        vector<int> arr2;
        for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) if (arr[j] + arr[k] <= M) {
            arr2.push_back(arr[j] + arr[k]);
        }
        sort(begin(arr2), end(arr2));
        const int NN = arr2.size();

        int ans = 0, r = NN-1;
        for (int j = 0; j < NN; ++j) {
            while (r > 0 && arr2[j] + arr2[r] > M) --r;
            if (arr2[j] + arr2[r] <= M) {
                ans = max(ans, arr2[j] + arr2[r]);
            }
        }

        cout << ans << endl;
    }
    return 0;
}

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

int main(){
while(1){
	int n,m,a,ans=0;
	vector<int> p,pp;
	scanf("%d%d",&n,&m);
	if(n==0&&m==0)break;
	p.push_back(0);
	for(int i=0;i<n;i++){
		scanf("%d",&a);
		p.push_back(a);
	}
	sort(p.begin(),p.end());
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			if(p[i]+p[j]>m)break;
			pp.push_back(p[i]+p[j]);
		}
	}
	sort(pp.begin(),pp.end());
	int s=pp.size()-1;
	for(int i=0;i<=s;i++){
		while(pp[i]+pp[s]>m)s--;
		if(ans<pp[i]+pp[s])ans=pp[i]+pp[s];
	}
	printf("%d\n",ans);
}
}

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

using namespace std;
int sum[1002010],p[1010];
int main(){
	
	int n,m;
	
	while(cin>>n>>m,n){
		for(int i=0;i<n;i++)scanf("%d",&p[i]);
		p[n++]=0;//ここで0点分を作っておくことで
		int size=0;
		for(int i=0;i<n;i++)for(int j=0;j<n;j++)sum[size++]=p[i]+p[j];//ここでひとつ分も保存される
		sort(sum,sum+size);
		int ans=0;
		for(int i=0;i<size;i++){
			int rem=m-sum[i];
			if(rem<0)continue;
			int left=0,right=size;
			while(left<right){
				int center=(left+right)/2;
				if(rem>sum[center])left=center+1;
				else if(rem<sum[center])right=center;
				else break;
			}
			ans=max(ans,sum[i]+sum[right-1]);
			
		}
		printf("%d\n",ans);
		
	}
	
	
	return 0;
}

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

#define rep(i, n) for(int i = 0; i < (n); i++)

using namespace std;

typedef pair<int, int> P;
typedef long long ll;

const int MAX_N = 1005;
int a[MAX_N*MAX_N];
int b[MAX_N*MAX_N];

int main(){
	int n, m;
	while(cin >> n >> m, n|m){
		vector<ll> v(n+1);
		rep(i, n) cin >> v[i];
		n++;
		rep(i, n){
			rep(j, n){
				a[i*n+j] = b[i*n+j] = v[i]+v[j];
			}
		}
		sort(b, b+n*n);
		int ans = 0;
		rep(i, n*n){
			if(m-a[i] >= 0) ans = max(ans, a[i] + *(upper_bound(b, b+n*n, m-a[i])-1));
		}
		cout << ans << endl;
	}

	return 0;
}

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;
    }
}