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<stdio.h>
#include<stdlib.h>
#include<math.h>

int main()
{
	int ans[4];
	int temp;
	double energy,energy_min,energy_now;
	int M, N;
	int* p;
	int i, j;
	double T=100;
	int ret;
	while (1) {
		scanf("%d%d", &N, &M);
		p = (int*)malloc((N+1) * sizeof(int));
		for (i = 0; i < N; i++) {
			scanf("%d", &p[i]);
		}
		p[N] = 0;
		if (N == M && N == 0) {
			break;
		}
		energy_min = pow(10, 300);
		for (j = 0; j < 4; j++) {
			ans[j] = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
		}
		
		for (T = 1000000; T > 100; T--) {
			for (j = 0; j < 4; j++) {
				temp = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
				for (j = 0; j < 4; j++) {
					ret = ans[0] + ans[1] + ans[2] + ans[3];
					ret += temp - ans[j];
					energy = M - ret;
					if (M < ret)energy += 100000000;

					if (energy < energy_min) {
						energy_min = energy;
						ans[j] = temp;
					}
					else if ((double)(rand() + 1) / (RAND_MAX + 2) < exp((energy_min - energy) / T*10)) {
						energy_min = energy;
						ans[j] = temp;
					}
				}

			}
		}
		ret=ans[0]+ +ans[1] + ans[2] + ans[3];
		printf("%d\n", ret);
	}
    return 0;
}

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

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];
	set<int> S;
	
	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		S.clear();
		S.insert(0);
		for ( int i = 0; i < n; ++i )
		{
			cin >> p[i];
			if ( p[i] < m )
			{
				S.insert(p[i]);
				ans = max( ans, p[i] );
			}
		}
		
		for ( int i = 0; i < n; ++i )
		{
			for ( int j = i; j < n; ++j )
			{
				int x = p[i] + p[j];
				if ( x <= m )
				{
					S.insert(x);
					ans = max( ans, p[i] );
					int y = m - x;
					while ( !S.count(y) && ( ans < (x + y) ) )
					{
						--y;
					}
					ans = max( ans, (x + y) );
				}
			}
		}
		
		if ( S.count(m) )
		{
			cout << m << endl;
			continue;
		}
		
		cout << ans << endl;
	}
	
	return 0;
}

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];
        }
        int arr2[1002*1002];
        for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
            arr2[N*j+k] = arr[j] + arr[k];
        }
        sort(arr2, arr2+N*N);

        int ans = 0, l = 0, r = N*N-1;
        while (l <= r) {
            int cand = arr2[l] + arr2[r];
            if (cand <= M) {
                ans = max(ans, cand);
                ++l;
            } else {
                --r;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C++: #define _USE_MATH_DEFINES
#include<stdio.h>
#include<string>
#include<iostream>
#include<cctype>
#include<cstdio>
#include<vector>
#include <algorithm>
#include<math.h>
#include<set>
#include<map>
#include<iomanip>
using namespace std;


int main(){
	
	int n,m;
	while(1){
		cin>>n>>m;
		if(!n&&!m)break;
		int g[1009]={};
		int w=2000000000;
		for(int i=0;i<n;i++)
		{cin>>g[i];w=min(w,g[i]);}
		sort(g,g+n);
		reverse(g,g+n);
		long long int ans=0,H=0;;
		int y=0;
		int r=3;
		int i=0;
		while(i<4){
			if(ans+g[y]+(r-i)*w<=m){ans+=g[y];i++;}
			else y++;
		}
		y=0;
		H=max(H,ans);
		r=2;i=0;ans=0;
		while(i<3){
			if(ans+g[y]+(r-i)*w<=m){ans+=g[y];i++;}
			else y++;
		}
		
		y=0;
		H=max(H,ans);
		r=1;i=0;ans=0;
		while(i<2){
			if(ans+g[y]+(r-i)*w<=m){ans+=g[y];i++;}
			else y++;
		}
		
		y=0;
		H=max(H,ans);
		r=0;i=0;ans=0;
		while(i<1){
			if(ans+g[y]+(r-i)*w<=m){ans+=g[y];i++;}
			else y++;
		}
		H=max(H,ans);


		cout<<H<<endl;
	}
	


	return 0;
}

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[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);

		if( m >= V[0] * 4 ){
			cout << V[0] * 4 << '\n';
			continue;
		}else if(m < V[n-1] ){
			cout << 0 << '\n';
			continue;
		}else{
			for(int i = 0; i < n; i++){
				for(int j = 0; j < 4; j++){
					if( j == 0 ){
						D[j].v.push_back( V[i] );
					}else if( j > 0 ){
						for(unsigned int l = 0; l < D[j - 1].v.size(); l++ ){
							int tmp = V[i] + D[j - 1].v[l];
							if( m - 4 * V[0] <= tmp && tmp <= m){
								if( !Find(D[j].v, tmp) ){
									D[j].v.push_back( tmp );
								}
							}
						}
					}
				}
			}
		}

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

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

int n, m;
int p[1000];
int ans;
set<int> s;
set<int>::iterator it, ite;

void solve(){
	ans = 0;
	s.clear();
	s.insert(0);
	for(int i = 0; i < n; i++){
		scanf("%d", &p[i]);
		if(p[i] <= m) s.insert(p[i]);
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			if(p[i]+p[j] <= m) s.insert(p[i]+p[j]);
		}
	}
	ite = s.end(); ite--;
	for(it = s.begin(); it != s.end(); it++){
		while(true){
			if((*it)+(*ite) <= m){
				ans = max(ans,(*it)+(*ite));
				break;
			}
			ite--;
		}
		//printf("%d %d\n", *it, *ite);
	}
	printf("%d\n", ans);
}

int main(){
	while(scanf("%d%d", &n, &m),n||m) solve();
}

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

int main() {
    int N, M;
    while(cin >> N >> M, N) {
        vector<int> P(N+1);
        for(int i=0; i<N; ++i) {
            cin >> P[i];
        }
        P[N] = 0;
        vector<int> v;
        for(int i=0; i<N+1; ++i) {
            for(int j=0; j<N+1; ++j) {
                v.push_back(P[i] + P[j]);
            }
        }
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        int res = 0;
        for(int i=0; i<v.size(); ++i) {
            if(v[i] > M) {
                break;
            }
            res = max(res, v[i] + *(upper_bound(v.begin(), v.end(), M-v[i])-1));
        }
        cout << res << endl;
    }
}