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 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 <vector>

using namespace std;

typedef unsigned long long int ULLI;

int main() {
    int n;
    ULLI m;
    ULLI p[1001];
    while (true) {
        ULLI max_point;
        vector<ULLI> half_points, points;
        cin >> n >> m;
        if (n == 0) {
            return 0;
        }
        for (int i=0; i<n; i++) {
            cin >> p[i];
        }
        p[n] = 0;
        for (int i=0; i<=n; i++) {
            for (int j=i; j<=n; j++) {
                ULLI point = p[i]+p[j];
                if (point <= m) {
                    half_points.push_back(point);
                }
            }
        }
        for (int i=0; i<(int)half_points.size(); i++) {
            for (int j=i; j<(int)half_points.size(); j++) {
                ULLI point = half_points[i]+half_points[j];
                if (point <= m) {
                    points.push_back(point);
                }
            }
        }
        max_point = points[0];
        for (int i=1; i<(int)points.size(); i++) {
            max_point = max(max_point, points[i]);
        }
        cout << max_point << endl;
    }
}

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;
	getchar();
	getchar();
	return 0;
}

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

const int MAX_N = 1009;
int ps[MAX_N];
int N, M;

int solve(){
	ps[N++] = 0;
	vector<int> as;
	for(int i=0; i<N; i++)for(int j=i; j<N; j++)if(ps[i]+ps[j] <= M){
		as.push_back(ps[i] + ps[j]);
	}
	sort(as.begin(), as.end());
	as.erase(unique(as.begin(), as.end()), as.end());

	int ret = 0;
	for(int i=0; i<as.size(); i++){
		ret = max(ret, as[i] + *lower_bound(as.rbegin(), as.rend(), M-as[i], greater<int>()));
	}
	return ret;
}

int main(){
	while(scanf("%d%d",&N,&M),N){
		for(int i=0; i<N; i++){
			scanf("%d",ps+i);
		}
		printf("%d\n",solve());
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
int sum[1000100];

int main(){
  int n,d;
  int m[1111];
  while(cin >> n >> d , n){
    memset(sum,0,sizeof(sum));
    for(int i=0;i<n;i++){
      cin >> m[i];
    }
    m[n] = 0;
    n++;
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
	sum[i*n+j] = m[i] + m[j];
      }
    }
    sort(sum,sum+n*n);
    
    int res = 0;
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
	int ab = m[i] + m[j];
	int h = d - (m[i] + m[j]);
	int tmp = sum[upper_bound(sum,sum+n*n,h)-sum-1] + ab;
	if(tmp <= d){
	  res = max(res,tmp);
	}
      }
    }
    cout << res << endl;
  }
}

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

int main()
{
	int n, m;
	int point[1000 + 10] = {0};
	vector<int> sec;

	int sum;

	int i, j;

	while (cin >> n >> m, n != 0 && m != 0)
	{
		sec.clear();
		sum = 0;
		for (i = 1; i <= n; i++)
		{
			cin >> point[i];
		}

		for (i = 0; i <= n; i++)
		{
			for (j = i; j <= n; j++)
			{
				sec.push_back(point[i]+point[j]);
			}
		} 

		sort(sec.begin(), sec.end());

		j = sec.size()-1;
		for (i = 0; i <= sec.size() - 1; i++)
		{
			//cout <<"A"<< j << " " <<i << endl;
			while (sec[i] + sec[j] > m && j > 0) j--;
			if (j == 0 && sec[i] + sec[j] > m) j--;

			//cout << "c " << j << endl;
			if (j < 0) break;

			//cout << "B" << sec[i] << " " << sec[j] << endl;

			sum = max(sum, sec[i] + sec[j]);
		}

		cout << sum << endl;
	}

	return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(int i=a; i<int(b); i++)
#define rep(i,b) loop(i,0,b)
#define each(e,c) for(auto& e:c)
#define iter(it,c) for(auto it=c.begin(); it!=c.end(); ++it)

ll const inf = 1<<28;
double const pi = acos(-1);

int a[1024];
int d[1024*1024];

// 整数二分探索,
// int res=l;
// for(int d=(inf); d; d>>=1) if(res+d <= r && ok(res+d)) res += d;
// すると間違えない. (n回目)
int solve(int n, int k){
    int c=0;
    rep(i,n)loop(j,i,n){
        int s=a[i]+a[j];
        if(s<=k){
            d[c++]=s;
        }
    }

    sort(d,d+c);
    int ans=0;
    rep(i,c){
        int s1=d[i];
        int l=0, r=c;
        int res=l;
        for(int w=r-l;w;w>>=1){
            bool ok;
            if(res+w>=r) ok=false;
            else{
                int s2=d[res+w];
                ok=(s1+s2<=k);
            }
            if(res+w<r && ok) res+=w;
        }
        ans=max(ans, s1+d[res]);

        // int s1=d[i];
        // int l=0, r=c;
        // while(l+1<r){
        //     int mid=(l+r)>>1;
        //     int s2=d[mid];
        //     if(s1+s2>k){
        //         r=mid;
        //     }else{
        //         l=mid;
        //     }
        // }
        // int s2=d[l];
        // ans=max(ans, s1+s2);
    }
    return ans;
}

int main(){
    int n,k;
    while(cin>>n>>k && n|k){
        a[0]=0;
        rep(i,n)cin>>a[i+1];
        n++;
        cout << solve(n,k) << endl;
    }
}

C++: #include <cstdio>
#include <algorithm>
#include <vector>
#define repi(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,a) repi(i,0,a)
#define all(a) (a).begin(), (a).end()

constexpr int MAX_N = 1010;

using ll = long long;

ll N, M;
ll P[MAX_N];

int main()
{
  while( scanf( "%lld%lld", &N, &M ), N|M )
  {
    rep( i, N )
      scanf( "%lld", P+i+1 );

    ++N;

    std::vector<ll> S;

    rep( i, N ) rep( j, N )
      S.emplace_back( P[i]+P[j] );

    std::sort( all(S) );
    S.erase( std::unique( all(S) ), S.end() );

    ll ans = 0;

    int q;
    rep( i, S.size() )
    {
      if( S[i] > M )
        break;

      q = i;
    }

    //rep( p, S.size() )
      //printf( "%lld%c", S[p], p==S.size()-1?'\n':' ' );

    rep( p, S.size() ) if( p <= q )
    {
      ll res = S[p]+S[q];

      while( res > M && p <= q )
        --q, res = S[p]+S[q];  
        
      if( p > q )
        break;

      if( res <= M )
        ans = std::max( ans, res );

      //printf( "(%lld,%lld)\n", S[p], S[q] );
    }

    printf( "%lld\n", ans );
  }
  
  return 0;
}