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>
#include<algorithm>
using namespace std;
int n,m,a[2000];
vector<int> t;
int main(){
  a[0]=0;
  while(cin>>n>>m&&n&&m){
    t.clear();
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=0;i<n;i++){
      for(int j=i;j<=n;j++){
	t.push_back(-(a[i]+a[j]));
      }
    }
    sort(t.begin(),t.end());
    int ans=0;
    for(int i=0;i<(int)t.size();i++){
      int x=-t[i];
      int y=m-x;
      if(y<0)continue;
      vector<int> :: iterator it;
      it = upper_bound(t.begin(),t.end(),-y);
      if(it==t.end())continue;
      int z = *it;
      ans=max(ans,x-z);
    }
    cout<<ans<<endl;
  }
  return 0;
}

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

int max_sum(int a[],int as,int b[],int bs,int m){
	int j=bs-1;
	int res=0;
	for(int i=0;i<as;i++){
		while(0<=j && m<a[i]+b[j])j--;
		if(j==-1)break;
		res=max(res,a[i]+b[j]);
	}
	return res;
}

int p[1000],p2[1000*1000];
int main(){
	int n,m;
	while(cin>>n>>m,n||m){
		int ans=0;
		for(int i=0;i<n;i++){
			cin>>p[i];
			if(p[i]<=m)ans=max(ans,p[i]);
		}
		sort(p,p+n);
		for(int i=0;i<n;i++){
			for(int j=i;j<n;j++){
				int a=p[i]+p[j];
				p2[i*n+j]=a;
				if(a<=m)ans=max(ans,a);
			}
		}
		int n2=n*(n+1)/2;
		sort(p2,p2+n2);
		ans=max(ans,max_sum(p,n,p2,n2,m));
		ans=max(ans,max_sum(p2,n2,p2,n2,m));
		cout<<ans<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#include <string>
#include <cstdio>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstring>
#include <tuple>
#include <utility>
#include <list>
#include <cmath>

using namespace std;

typedef long long LL;
typedef vector<int> Array;
typedef pair<int, int> P;

const LL LINF = 1LL << 60;
const LL MOD = 100000;
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define all(c) (c).begin(), (c).end()

struct edge{ LL to, cost; edge(int t, LL c) :to(t), cost(c){} };

int dxk[] = { 1, 1, 1, 0, -1, 0 };
int dxg[] = { 0, 1, 0, -1, -1, -1 };
int dy[] = { -1, 0, 1, 1, 0, -1 };

int main()
{
	int n;
	LL m;
	while (cin >> n >> m && n)
	{
		vector<LL> nums(n);
		rep(i, n) cin >> nums[i];
		vector<LL> arr(n*n + 2);
		rep(i, n) rep(j, n)
		{
			arr[i * n + j] = nums[i] + nums[j];
		}
		rep(i, n) arr[n*n + 1] = nums[i];
		sort(all(arr));

		LL ans = 0;
		for (auto x : arr)
		{
			LL rem = m - x;
			auto it = upper_bound(all(arr), rem);
			if (it != arr.begin())
			{
				LL num = *(--it);
				ans = max(ans, num + x);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;

ll M,N,P[1001];

int main(){
	while(scanf("%lld%lld",&N,&M),N){
		for(int i=0;i<N;i++) scanf("%lld",&P[i]);
		vector<ll> d;
		for(int i=0;i<=N;i++) for(int j=0;j<=N;j++)
			d.push_back(P[i]+P[j]);
		sort(d.begin(),d.end());
		d.erase(unique(d.begin(),d.end()),d.end());
		vector<ll>::iterator it;
		ll res=0;
		for(int i=0;i<d.size();i++){
			it=upper_bound(d.begin(),d.end(),M-d[i]);
			if(it!=d.begin()){
				it--;
				res=max(res,*it+d[i]);
			}
		}
		printf("%lld\n",res);
	}
}

C++: #include<bits/stdc++.h>
using namespace std;
int main(void){
	int n,m;
	int i,j,k;
	int high,low,base,mid;
	int a[1001];
	int MIN;
	int ans;
	int a1,a2;
	while(1){
		cin>>n>>m;
		if(n==0&&m==0)	break;
		for(i=0;i<n;i++){
			cin>>a[i];
		}
		a[n]=0;
		sort(a,a+n+1);
		int sum;
		int flg;
		MIN=INT_MAX;
		ans=0;
		//for(i=0;i<=n;i++)	cout<<a[i]<<endl;
		for(i=0;i<=n;i++){
			sum=0;
			sum+=a[i];
			a1=sum;
			for(j=0;j<=n;j++){
				sum=a1;
				sum+=a[j];
				a2=sum;
				for(k=0;k<=n;k++){
					sum=a2;
					sum+=a[k];
					if(sum<=m){
						base=m-sum;
						high=n;
						low=0;
						flg=0;
						while(low<=high){
							mid=(high+low)/2;
							if(base<a[mid]){
								high=mid-1;
							}
							else if(base>a[mid]){
								low=mid+1;
							}
							else{
								flg=1;
								break;	
							}
						}
						if(flg==1){
							sum+=base;
						}	
						else{
							sum+=a[high];
						}
					}
					
					//cout<<"M="<<MIN<<" "<<"SA="<<m-sum<<" "<<"SUM="<<sum<<endl;
					if(MIN>m-sum&&m>=sum){
						MIN=m-sum;
						ans=sum;
						//cout<<"ans="<<ans<<endl;
					}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

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

int main(){
	int n,m,i,j;
	while(cin >> n >> m, n && m){	
		int ret = 0;
		vector<int> data(n+1);
		vector<int> all;
		for(i=0;i<n;i++)cin >> data[i];
		for(i=0;i<n+1;i++)
			for(j=i;j<n+1;j++)
				all.push_back(data[i]+data[j]);
		sort(all.begin(),all.end());
		for(i=0;i<all.size();i++){
			int t = m-all[i];
			vector<int>::iterator it = upper_bound(all.begin(),all.end(),t);
			if( it == all.end() ){
				ret = max(ret,all[i] + all.back());
			}else if(it != all.begin()){
				ret = max(ret,all[i] + *(it-1) );
			}
		}
		cout << ret << endl;
	}
}

C++: #include<stdio.h>
#include<stdlib.h>
int n,m;
int a[1001];
int b[51000];
bool f[1001][1001];
int i,j;
int ans;
int c;

int max(int a,int b){
	if(a>=b)return a;
	else return b;
}

int comp(const void *a,const void *b){
	int p=*(int*)a;
	int q=*(int*)b;
	return p-q;
}

int search(int num){
	int r=0;
	int l=c;
	int mid;
	for(int k=0;k<25;k++){
		mid=(int)(r+l)/2;
		if(num-b[mid+1]>=0&&num-b[mid]>num-b[mid+1])mid=mid+1;
		if(b[mid]>num)l=mid;
		else r=mid;
	}
	return mid;
}

int main(){
	while(1){
		scanf("%d %d",&n,&m);
		if(n==0&&m==0)return 0;
		ans=0;
		c=0;
		for(i=0;i<n;i++)scanf("%d",&a[i]);
		a[n]=0;
		for(i=0;i<n+1;i++)for(j=0;j<n+1;j++)f[i][j]=false;
		for(i=0;i<n+1;i++)for(j=0;j<n+1;j++){
			if(!f[j][i]&&a[i]+a[j]<=m){
				b[c++]=a[i]+a[j];
				f[i][j]=true;
			}
		}
		qsort(b,c,sizeof(int),comp);
		for(i=0;i<c;i++){
			if(m-b[i]>=0){
				ans=max(ans,b[search(m-b[i])]+b[i]);
			}
		}
		printf("%d\n",ans);
	}
}