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

int main(){
    while(true){
        int N,M;
        cin>>N>>M;
        if(N==0 && M==0) break;
        int P[1000];
        for(int i=0;i<N;i++){
            cin>>P[i];
        }
        int PP[1001001];
        int count=0;
        PP[count]=0;
        count++;
        for(int i=0;i<N;i++){
            PP[count]=P[i];
            count++;
        }
        for(int i=0;i<N;i++){
            for(int j=i;j<N;j++){
                PP[count]=P[i]+P[j];
                count++;
            }
        }
        int ans=0;
        sort(PP,PP+count);
        for(int i=0;i<count;i++){
            int searchh = M-PP[i];
            int* pos=lower_bound(PP,PP+count,searchh);
            int z = (int)(pos-PP);
            if(z == count){
                ans = max(ans, PP[i] + PP[z-1]);
            }else{
                if(*pos == searchh){
                    ans=M;
                    break;
                }else{
                    ans = max(ans, PP[i] + PP[z-1]);
                }
                if(PP[i] > PP[z-1]) break;
            }
        }
        cout<<ans<<endl;
    }
    
    return 0;
}

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

int N,M;
int NN;
int *dd;
int *d;

int search(int var)
{
	int i = 0, j = NN-1;
	int cut;

	while(i != j){
		cut = (i+j)/2;
		if(dd[cut] + var > M){
			j = cut-1;
		}
		else if(dd[cut] + var < M){
			i = cut+1;
		}
		else
			return dd[cut] + var;

	}

	if(var + dd[cut] <= M)
		return dd[cut] + var;

	return -1;
}
int main(void)
{


	while(	cin >> N >> M, N && M){

	NN = (N+1) * (N+1);
	d = new int [N+1];
	dd = new int [NN];

	d[0] = 0;

	for(int i = 1; i <= N; i++)
		cin >> d[i];

	int c = 0;
	for(int i = 0; i <= N; i++)
		for(int j = 0; j <= N; j++,c++)
			dd[c] = d[i] + d[j];

	sort(dd,dd+NN);

	c = 0;
	int num = 0;
	int MAX = 0;

	for(int i = 0; i < NN; i++){
		if(dd[i] > M)
			break;

		num = search(dd[i]);

		if(num > MAX)
			MAX = num;
	}
	cout << MAX << endl;
		

	delete [] d;
	delete [] dd;
	}
	return 0;
}

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

int main(){
  int n,m;

  while(cin >> n >> m , n + m){
    vector<int> v;
    int a;

    for(int i = 0 ; i < n ; i++){
      cin >> a;
      v.push_back(a);
    }

    int size = v.size();
    for(int i = 0 ; i < size ; i++){
      for(int j = 0 ; j < size ; j++){
	v.push_back(v[i]+v[j]);
      }
    }
    
    sort(v.begin(),v.end());

    int ans = 0;
    for(int i = 0 ; i < v.size() ; i++){
      int want = m - v[i];
      int l = 0,r = v.size()-1;

      if(want < 0) continue;

      while(r - l > 1){
	int mid = (l+r) /2;
	if(v[mid] >= want){
	  r = mid;
	}
	else{
	  l = mid;
	}
	if(v[l] + v[i] <= m){
	  ans = max(ans,v[l]+v[i]);
	}
      }
    }

    cout << ans << endl;
  }

  return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
#define MAX 1000

int n, L, P[MAX+1], v[(MAX+1)*(MAX+1)];

void compute(){
    int size = 0;
    for ( int i = 0; i < n+1; i++ ){
	for ( int j = i; j < n+1; j++ ){
	    v[size++] = P[i] + P[j];
	}
    }
    sort(v, v + size);
    int maxv = 0;

    for ( int i = 0; i < size; i++ ){
	if ( v[i] > L ) break;
	int first = v[i];
	int target = L - v[i];
	
	int t = distance(v, upper_bound(v, v + size, target));

	if ( v[t] + first <= L && maxv < v[t]+first ) maxv = v[t]+first;
	if ( t+1 <size && v[t+1] + first <= L && maxv < v[t+1]+first ) maxv = v[t+1]+first;
	if ( t-1 >= 0 && v[t-1] + first <= L && maxv < v[t-1]+first ) maxv = v[t-1]+first;
    }
    cout << maxv << endl;
}

main(){
    while( cin >> n >> L && n ){
	P[0] = 0;
	for ( int i = 1; i <= n; i++ ) cin >> P[i];
	compute();
    }
}

C++: #include <cstdio>
#include <algorithm>

using namespace std;

int m,n;
int a[1002];
int aa[1002*1002]={0};

int ans,Max;

void bin_search(int x){
	int l=0,r=n*n;
	Max=0;
	while (l<=r) {
		int i=(l+r)/2;
		if (aa[i]<x&&aa[i]>Max) {
			Max=aa[i];
		}
		if(aa[i]<x)l=i+1;
		else r=i-1;
	}
}

void solve(){
	int size=0;
	for(int c=0;c<n;c++){
		for (int d=0; d<n; d++) {
			aa[size++]=a[c]+a[d];
		}
	}
	sort(aa,aa+size);
	
	for (int i=0; i<n; i++) {
		for (int j=0; j<n; j++) {
			if (m-a[i]-a[i]>=0) {
				bin_search(m-a[i]-a[j]);
				if (Max+a[i]+a[j]>ans) {
					ans=Max+a[i]+a[j];
				}
			}
		}
	}
	
}

int main(){
	
	while (1) {
		scanf("%d%d",&n,&m);
		ans=0;
		if (n==0&&m==0) {
			break;
		}
		for (int i=0; i<n; i++) {
			scanf("%d",&a[i]);
		}
		a[n++]=0;
		solve();
		printf("%d\n",ans);
	}
	
	
}

C++: //http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
//http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<cstdio>
#include<fstream>
#include<cstring>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define P pair<int,int>
#define ll __int64

int n,m;
int t[10000];
const int MA=1000000;
int s1[MA],s2[MA];

int ya[4];

int main(){

while(cin>>n>>m,n||m){
rep(i,MA)s1[i]=s2[i]=0;
rep(i,10000)t[i]=0;

for(int i=1;i<=n;i++)cin>>t[i];
int g=0;

for(int i=0;i<=n;i++){
	for(int j=0;j<=n;j++){
		s1[i*(n+1)+j]=t[i]+t[j];
		//s2[i*(n+1)+j]=t[i]+t[j];	
		g++;
	}
}


sort(s1,s1+g);
rep(i,g)s2[i]=s1[i];
//sort(s2,s2+g);

//rep(i,g)cout<<s1[i]<<" ";cout<<endl;

int ans=0;

for(int i=0;i<g;i++){
	int now=s1[i];

	int l=0;
	int r=g-1;
	int mid=(l+r)/2;
	int x=s2[mid];

	for(int i=0;i<50;i++){
		if(x+now==m)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
	}

	//cout<<" "<<x<<" "<<now<<" "<<x+now<<endl;
	if(x+now<=m)
	ans=max(ans,x+now);
}
cout<<ans<<endl;
}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <cmath>
#include <limits>
#include <functional>

#define REP(i,n) for(int i=0;i<n;i++)
#define FOR(i,m,n) for(int i=m;i<n;i++)
#define FORR(i,m,n) for(int i=m;i>=n;i--)
#define pb(x) push_back(x) 
#define SORT(x) sort((x).begin(),(x).end())
#define INF 999999999

using namespace std;

#define int long long

signed main(){
	int n, m;
	while(1){
		cin >> n >> m;
		if(n==0) break;
		
		vector<int> p(n);
		REP(i, n){
			cin >> p[i];
		}
		p.push_back(0);
		sort(p.begin(), p.end());
		n++;
		
		vector<int> v;
		REP(i, n){
			FOR(j, i, n){
				if(p[i]+p[j]<=m) v.push_back(p[i]+p[j]);
			}
		}
		sort(v.begin(), v.end());
		
		int l=0, r=v.size()-1, ans=0;
		for(; l<=r; l++){
			if(v[l]+v[r]>m) r--;
			ans=max(ans, v[l]+v[r]);
		}
		
		cout << ans << endl;
	}
}