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 _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef vector<int>V;
void I(V&v)
{
	v.push_back(0);
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
}
V::const_iterator F(const V&v,int m)
{
	return upper_bound(v.begin(),v.end(),m)-1;
}
int main()
{
	int n,m,i,j,r;
	V v,w;
	v.reserve(1001);
	w.reserve(502000);
	while(scanf("%d%d",&n,&m),n)
	{
		v.clear();
		w.clear();
		for(i=0;i<n;++i)
		{
			scanf("%d",&r);
			v.push_back(r);
		}
		I(v);
		for(i=1;i<v.size();++i)for(j=i;j<v.size();++j)w.push_back(v[i]+v[j]);
		I(w);
		r=*F(v,m);
		r=max(r,*F(w,m));
		for(i=1;i<v.size();++i)
			if(m-v[i]>=0)r=max(r,v[i]+*F(w,m-v[i]));
		for(i=j=F(w,m/2)-w.begin();0<=i&&j<w.size();)
		{
			if(w[i]+w[j]>m)--i;
			else r=max(r,w[i]+w[j]),++j;
		}
		printf("%d\n",r);
	}
	return 0;
}

C++: #include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT solve( const VI& Q, INT M ) {
    INT answer = 0;
    int n = Q.size();
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t > M ) t = 0;
            answer = max( answer, t );
            if ( Q[p] > m ) {
                R = p;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        VI P;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P.push_back( p );
        }
        P.push_back( 0 );
        VI Q;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q.push_back( P[i] + P[j] );
            }
        }
        sort( Q.begin(), Q.end() );
        cout << solve( Q, m ) << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>

using namespace std;
using lint = long long;

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> P(N);
    for (int i = 0; i < N; i++) {
        cin >> P[i];
    }
    P.emplace_back(0);
    ++N;
    vector<int> P2(N*N);
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            P2[i*N+j] = P[i] + P[j];
        }
    }
    sort(P2.begin(), P2.end());
    int ans = 0;
    for (int i = 0; i < N*N; i++) {
        const int index = upper_bound(P2.begin(), P2.end(), M - P2[i]) - P2.begin();
        if (index == 0) continue;
        ans = max(ans, P2[i] + P2[index-1]);
    }
    cout << ans << endl;
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()

using namespace std;

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

int main()
{
//	cut here before submit 
//	freopen ("testcase.darts", "r", stdin );
	int n, m;
	while (cin >> n >> m && n && m ){
		vector<int> p (n, 0 );
		rep (i, n ){
			cin >> p[i];
		} // end rep
		sort (ALL (p ), greater<int>() );
		int curr = 0;
		rep (i, n ){
			while (curr <= m ){
				curr += p[i];
			} // end while
			while (curr > m ){
				curr -= p[i];
			} // end while
		} // end rep
		cout << curr << endl;
	} // end loop
		
	return 0;
}

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

using namespace std;

int main() {
	int n;
	long long int m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		vector<long long int> data;
		long long int b;
		for (int i = 0; i < n; i++) {
			cin >> b;
			if (b <= m) {
				data.push_back(m);
			}
		}
		sort(data.begin(), data.end());
		vector<long long int> data2;
		for (int i = 0; i < data.size(); i++) {
			for (int j = i; j < data.size(); j++) {
				if (data[i]+data[j] <= m) {
					data2.push_back(data[i]+data[j]);
				} else {
					break;
				}
			}
		}
		sort(data2.begin(), data2.end());
		data.clear();
		for (int i = 0; i < data2.size(); i++) {
			for (int j = i; j < data2.size(); j++) {
				if (data2[i]+data2[j] <= m) {
					data.push_back(data2[i]+data2[j]);
				} else {
					break;
				}
			}
		}
		data2.clear();
		sort(data.begin(), data.end());
		//vector<long long int> data2;
		for (int i = 0; i < data.size(); i++) {
			for (int j = i; j < data.size(); j++) {
				if (data[i]+data[j] <= m) {
					data2.push_back(data[i]+data[j]);
				} else {
					break;
				}
			}
		}
		sort(data2.begin(), data2.end());
		long long int sz = data2.size();
		cout << data2[sz-1] << endl;
	}
	return 0;
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
#define INF (1<<30)
#define INFLL (1ll<<60)
typedef pair<int, int> P;
typedef pair<ll, P> E;
#define MOD (1000000007ll)
#define l_ength size
#define PI 3.14159265358979

void mul_mod(ll& a, ll b){
	a *= b;
	a %= MOD;
}

void add_mod(ll& a, ll b){
	b += MOD;
	a += b;
	a %= MOD;
}

int n,s;
ll m,p[1234567];

ll search(ll x){
	int l,r,mid;
	if(x>m){
		return 0ll;
	}
	l = 0; r = s;
	while((r-l)>1){
		mid = (l+r)/2;
		if(x+p[mid]>m){
			r = mid;
		}else{
			l = mid;
		}
	}
	return ((x+p[r]>m)?(x+p[l]):(x+p[r]));
}

int main(void){
	int i,j;
	ll ans;
	cin >> n >> m;
	while(!(n==0&&m==0ll)){
		ans = 0ll; s = n*n+n+1;
		for(i=0; i<n; ++i){
			cin >> p[i];
		}
		for(i=0; i<n; ++i){
			for(j=0; j<n; ++j){
				p[n+i*n+j] = p[i]+p[j];
			}
		}
		p[s-1] = 0ll;
		sort(p,p+s);
		for(i=0; i<s; ++i){
			ans = max(ans,search(p[i]));
		}
		cout << ans << endl;
		cin >> n >> m;
	}
	return 0;
}