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+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 <iostream>
#include <algorithm>
#define INF 200000000
using namespace std;


int point2[500500];

int search(int a[], int n, int key) {
	int left = 0;
	int right = n;
	int mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (a[mid] == key) return a[mid];
		else if (a[mid] < key) left = mid + 1;
		else right = mid;
	}
	return a[left-1];
}

int main() {
	while (true) {
		int n, m;
		cin >> n >> m;
		if (n == 0 && m == 0) return 0;
		int point[n+1];
		for (int i = 0; i < n; i++) cin >> point[i];
		point[n] = 0;
		int k = 0;
		for (int i = 0; i < n + 1; i++) {
			for (int j = i; j < n + 1; j++) {
				point2[k] = point[i] + point[j];
				k++;	
			}
		}
		int np = k;
		sort(point2, point2 + np);

		int ans = 0;
		for (int i = 0; i < np; i++) {
			if (point2[i] > m) break;
			int s = search(point2, np, m - point2[i]);
			int t = s + point2[i];
			if (t > ans) ans = t;
		}
		cout << ans << endl;
	}
}

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

using namespace std;

#define MAX(a,b) ((a)>(b)?(a):(b))

int main()
{
    int N;
    long long M;

    cin >> N >> M;

    while(N!=0 && M!=0) {
        vector<int> p(N);
        set<long long> st[2];

        long long ans=0;

        for(int i=0; i<N; ++i) {
            cin >> p[i];
        }

        sort(p.begin(),p.begin()+N);

        for(int i=0; i<N; ++i) {
            if(p[i]<M) st[0].insert(p[i]);
            ans=MAX(ans,p[i]);
        }

        for(int k=1; k<4; ++k) {
            for(auto itr=st[(k-1)%2].begin(); itr!=st[(k-1)%2].end(); ++itr) {
                auto p_itr=upper_bound(p.begin(),p.end(),M-*itr);
                if(p_itr==p.begin()) {
                    st[(k-1)%2].clear();
                    break;
                } else {
                    --p_itr;
                }
                ans=MAX(ans,*itr+*p_itr);
                st[k%2].insert(*itr+*p_itr);
            }
        }

        cout << ans << endl;


        cin >> N >> M;
    }
    return 0;
}

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

typedef long long int ll;
using namespace std;

int main() {
	int N, M;
	cin >> N >> M;
	vector<ll> P(N);
	vector<ll> Ps;
	Ps.push_back(0);
	for(int i = 0; i < N; i++) {
		cin >> P[i];
		Ps.push_back(P[i]);
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			Ps.push_back(P[i] + P[j]);
		}
	}
	sort(Ps.begin(), Ps.end());

	ll ans = 0;
	for (int i = 0; i < Ps.size(); i++) {
		if (Ps[i] > M) break;
		int k = std::upper_bound(Ps.begin(), Ps.end(), M - Ps[i]) - 1 - Ps.begin();
		ans = max(ans, Ps[i] + Ps[k]);
	}
	cout << ans << endl;



	return 0;
}

C++: #include<iostream>
using namespace std;
int p[1001],s[1000000];
int main(){
	int n,m;
	cin>>n>>m;
	int top=1;
	p[0]=0,s[0]=0;
	for(int i=1;i<=n;i++){
		cin>>p[i];
		for(int j=0;j<i;j++){
			if(p[i]+p[j]<=m)s[top]=p[i]+p[j];
			top++;
		}
	}
	int ans=0;
	for(int i=0;i<top;i++){
		int left=0,right=top,mid;
		while(true){
			if(left>=right-1)break;
			mid=(left+right)/2;
			if(s[mid]+s[i]<=m){ans=max(ans,s[mid]+s[i]),left=mid;}
			else right=mid;
		}
	}
	cout<<ans<<endl;
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n, m, c[1009], s[510009], t[510009], cnt[32777], sum[32777];
int main() {
	while (scanf("%d%d", &n, &m), n) {
		for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
		sort(c, c + n);
		int b = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = i; j <= n && c[i] + c[j] <= m; j++) {
				s[b++] = c[i] + c[j];
			}
		}
		for (int i = 0; i < 30; i += 15) {
			fill(cnt, cnt + 32768, 0); sum[0] = 0;
			for (int j = 0; j < b; j++) cnt[(s[j] >> i) & 32768]++;
			for (int j = 0; j < 32768; j++) sum[j + 1] = sum[j] + cnt[j];
			for (int j = 0; j < b; j++) t[sum[(s[j] >> i) & 32768]++] = s[j];
			for (int j = 0; j < b; j++) s[j] = t[j];
		}
		int r = b - 1, ret = 0;
		for (int i = 0; i < b && i <= r; i++) {
			while (r > 0 && s[i] + s[r] > m) r--;
			ret = max(ret, s[i] + s[r]);
		}
		printf("%d\n", ret);
	}
	return 0;
}

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;
  while ( cin >> n >> m && n && m ) {
    VI p( n );
    for ( int i = 0; i < n; i++ ) {
      cin >> p[ i ];
    }
    p.push_back( 0 );
    SORT( p );
    set<int> two_selected;
    for ( int i = 0; i < n + 1; i++ ) {
      for ( int j = 0; j < n + 1; j++ ) {
        two_selected.insert( p[ i ] + p[ j ] );
      }
    }
    int ans = 0;
    for ( set<int>::iterator it = two_selected.begin(); it != two_selected.end(); ++it ) {
      set<int>::iterator it2 = two_selected.upper_bound( m - *it );
      if ( it2 != two_selected.begin() ) {
        --it2;
        ans = max( ans, *it + *it2 );
      }
    }
    PRINT( ans );
  }
  return 0;
}