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;
typedef long long ll;
#define F first
#define S second
#define pii pair<int, int>
#define eb emplace_back
#define all(v) v.begin(), v.end()
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep3(i, l, n) for (int i = l; i < (n); ++i)
#define sz(v) (int)v.size()
#define inf (int)(1e9+7)
#define abs(x) (x >= 0 ? x : -(x))
#define ceil(a, b) a / b + !!(a % b)
template<typename T1, typename T2> inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }
template<typename T> T pow(T a, int b) { return b ? pow(a * a, b / 2) * (b % 2 ? a : 1) : 1; }
template<typename T> T gcd(T a, T b) { if (b == 0) return a; return gcd(b, a % b); }




int main() {
    // 所詮4本 -> 2つずつまとめて半分全列挙
    
    int n, m;
    while (cin >> n >> m && n) {
        
        vector<int> p(n);
        rep(i, n) cin >> p[i];
        
        vector<int> v;
        rep(i, n) v.eb(p[i]);
        rep(i, n) rep(j, n) v.eb(p[i] + p[j]);
        
        vector<int> v2;
        rep(i, n) v2.eb(p[i]);
        rep(i, n) rep(j, n) v2.eb(p[i] + p[j]);
        sort(all(v2));
        
        int ans = 0;
        rep(i, sz(v)) {
            int it = (int)(upper_bound(all(v2), m - v[i]) - v2.begin());
            if (it == 0) continue;
            chmax(ans, v[i] + v2[it - 1]);
            // cout << v[i] << " " << v2[it - 1] << endl;
        }
        cout << ans << endl;
    }
}

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

#pragma warning( disable: 4996 )

using namespace std;

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

#define INF 1000000000
#define EPS 1e-10

#define MAX_N 1000

int N, M;
int po[MAX_N];

vector<int> ans_list;

int main(){

	while (true){
		cin >> N >> M;
		if (N == 0 && M == 0)
			break;
		for (int i = 0; i < N; i++){
			cin >> po[i];
		}
		vector<int> A, B;
		A.push_back(0);
		B.push_back(0);

		for (int i = 0; i < N/2; i++){
			A.push_back(po[i]);
		}

		for (int i = N / 2; i < N; i++){
			B.push_back(po[i]);
		}

		for (int i = 0; i < N/2; i++){
			for (int j = i; j < N/2; j++){
				A.push_back(po[i] + po[j]);
			}
		}

		for (int i = N/2; i < N; i++){
			for (int j = i; j < N; j++){
				B.push_back(po[i] + po[j]);
			}
		}

		sort(A.begin(), A.end());
		sort(B.begin(), B.end());

		int ans = 0;

		for (int i = 0; i < A.size(); i++){
			int tmp = A[i];
			int max_tmp = M - tmp;
			if (max_tmp < 0)
				break;
			int lb = 0, ub = B.size();
			while (ub - lb > 1){
				int mid = (ub + lb) / 2;
				if (max_tmp < B[mid])
					ub = mid;
				else
					lb = mid;
			}
			ans = max(ans, M - (max_tmp - B[lb]));
		}
		for (int i = 0; i < A.size(); i++){
			int tmp = A[i];
			int max_tmp = M - tmp;
			if (max_tmp < 0)
				break;
			int lb = 0, ub = A.size();
			while (ub - lb > 1){
				int mid = (ub + lb) / 2;
				if (max_tmp < A[mid])
					ub = mid;
				else
					lb = mid;
			}
			ans = max(ans, M - (max_tmp - A[lb]));
		}
		for (int i = 0; i < B.size(); i++){
			int tmp = B[i];
			int max_tmp = M - tmp;
			if (max_tmp < 0)
				break;
			int lb = 0, ub = B.size();
			while (ub - lb > 1){
				int mid = (ub + lb) / 2;
				if (max_tmp < B[mid])
					ub = mid;
				else
					lb = mid;
			}
			ans = max(ans, M - (max_tmp - B[lb]));
		}
		for (int i = 0; i < B.size(); i++){
			int tmp = B[i];
			int max_tmp = M - tmp;
			if (max_tmp < 0)
				break;
			int lb = 0, ub = A.size();
			while (ub - lb > 1){
				int mid = (ub + lb) / 2;
				if (max_tmp < A[mid])
					ub = mid;
				else
					lb = mid;
			}
			ans = max(ans, M - (max_tmp - A[lb]));
		}

		ans_list.push_back(ans);

	}

	for (int i = 0; i < ans_list.size(); i++){
		cout << ans_list[i] << endl;
	}

}

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

int main(void)
{
    long long n, m;

    while (scanf("%lld %lld", &n, &m), n){
        long long p[1024];

        for (int i = 0; i < n; i++) scanf("%lld", p + i);
        p[n++] = 0;

        vector<long long> score;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                if (!binary_search(score.begin(), score.end(), p[i] + p[j])) score.push_back(p[i] + p[j]);
            }
        }
        sort(score.begin(), score.end());
        score.erase(unique(score.begin(), score.end()), score.end());

        long long maxi = 0;
        for (auto i : score){
            if (i > m) continue;
            maxi = max(maxi, min(*(upper_bound(score.begin(), score.end(), m - i) - 1) + i, m));
        }

        printf("%lld\n", maxi);
    }

    return 0;
}

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]);
				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]);
						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]);
								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 = max(ans, a[p] + a[q] + a[r] + a[s]);
								}
							}
						}
					}
				}
			}
		}
	ANS:
		cout << ans << endl;
	}
	return 0;
}