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 <bits/stdc++.h>
using namespace std;
#define FOR(i, s, n) for(int i = s; i < (int)n; ++i)
#define per(i, n) for(int i = n; i >= 0; i--)
#define ROF(i, s, n) for(int i = s; i >= (int)n; i--)
#define FORIT(i, A) for (auto i : A)
#define PRINT(x) cout << (x) << "\n"
#define SCAN(x) cin >> x
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define MP make_pair
#define PB push_back
#define EACH(i, n) for (__typeof((n).begin()) i = (n).begin(); i != (n).end(); ++i)
#define SZ(a) int((a).size())
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define CLR(a) memset((a), 0 ,sizeof(a))
#define NCLR(a) memset((a), -1 ,sizeof(a))
#define sq(n) (n) * (n)
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef complex<long double> P;
typedef long long LL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef priority_queue<int> maxpq;
typedef priority_queue< int, vector<int>, greater<int> > minpq;
typedef complex<double> Point;
static const double EPS = 1e-10;
static const double PI = acos( -1.0 );
static const int mod = 1000000007;
static const int INF = 1 << 29;
static const LL LL_INF = 1ll << 60;
static const int dx[] = { -1, 0, 1, 0, 1, -1, 1, -1 };
static const int dy[] = { 0, -1, 0, 1, 1, 1, -1, -1 };

#ifdef WIN32
#define dump(x) cerr << #x << " = " << (x) << "\n"
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << "\n"
#else
#define dump(x)
#define debug(x)
#endif

template<class T> ostream &operator<<( ostream &os, vector<T> &v ) {
	for ( int i = 0; i < v.size(); i++ ) {
		if ( i ) os << " ";
		os << v[ i ];
	}
	return os;
}

int main() {
	ios::sync_with_stdio( false );
	cin.tie( 0 );
	int n, m;
  set<int>::iterator it, it2, it3;
  while ( cin >> n >> m && n && m ) {
    set<int> p;
    for ( int i = 0; i < n; i++ ) {
      int num;
      cin >> num;
      p.insert( num );
    }
    p.insert( 0 );
    set<int> two_selected;
    for ( it = p.begin(); it != p.end() ; ++it ) {
      for ( it2 = p.begin(); it2 != p.end(); ++it2 ) {
        two_selected.insert( *it +*it2 );
      }
    }
    int ans = 0;
    for ( it = p.begin(); it != p.end(); ++it ) {
      for ( it2 = p.begin(); it2 != p.end(); ++it2 ) {
        it3 = two_selected.upper_bound( m - ( *it + *it2 ) );
        if ( it3 != two_selected.begin() ) {
          --it3;
          ans = max( ans, *it + *it2 + *it3 );
        }
      }
    }
    PRINT( ans );
  }
	return 0;
}

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

int main() {

	int N, M;
	
	while(cin >> N >> M, N + M > 0) {
	
		int P[1111];
		vector<int> PP;
		
		for(int i= 0; i < N; i++) {
			cin >> P[i];
		}
		
		P[N++] = 0;
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				PP.push_back(P[i] + P[j]);
			}
		}
		
		sort(PP.begin(), PP.end());
		
		int ans = 0;;
		
		for(int i = 0, m; i < PP.size(); i++) {
			m = M - PP[i];
			if(m < 0) continue;
			int it = *(upper_bound(PP.begin(), PP.end(), m) - 1);
			ans = max(ans, PP[i] + it );
			//cout << PP[i] << " " << it << endl;
		}
		
		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];
        }
        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;
}