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 "bits/stdc++.h"
#define in std::cin
#define out std::cout
#define rep(i,N) for(LL i=0;i<N;++i)
typedef long long int LL;

LL N, M, P[1123];
std::set<LL>list;
LL ans;

int main()
{
	while (true)
	{
		N = M = 0;
		memset(P, 0, sizeof(P));
		list.clear();
		ans = 0;

		in >> N >> M;
		if (N == 0 && M == 0) { break; }
		rep(i, N) { in >> P[i]; }

		P[N] = 0;
		N++;
		std::sort(P, P + N);
		rep(i, N)
		{
			rep(j, N) { list.insert(P[i] + P[j]); }
		}
		for (auto i : list)
		{
			if (i > M) { continue; }
			auto iter = std::upper_bound(list.begin(), list.end(), M - i);
			--iter;
			ans = std::max(ans, i + *iter);
		}

		out << ans << std::endl;
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <bitset>
#include <fstream>
#include <cmath>
#include <ctime>
using namespace std;
typedef long long ll;

int main()
{
	ll n, m;

	while( cin >> n >> m && (n || m)){

		vector<ll> targets(n);
		for(int i = 0; i < n; i++)
			cin >> targets[i];

		targets.push_back(0);
		sort(targets.begin(), targets.end());
		targets.erase(unique(targets.begin(), targets.end()), targets.end());
		targets.erase(upper_bound(targets.begin(), targets.end(), m), targets.end());

		vector<ll> a1;

		for(int i = 0; i < targets.size(); i++)
			for(int j = 0; j < targets.size(); j++)
				a1.push_back(targets[i] + targets[j]);

		sort(a1.begin(), a1.end());
		a1.erase(unique(a1.begin(), a1.end()), a1.end());

		ll res = 0;

		for(int i = 0; i < a1.size(); i++)
		{
			vector<ll>::iterator it = upper_bound( a1.begin(), a1.end(), m - a1[i]);
			if(it != a1.begin()){
				it--;
				res = max(res, a1[i] + (*it));
			}
		}

		cout << res << endl;
	}
}

C++: //JOI 2008??´???3??? ?????????

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;

#define MAX -210000000
#define MIN 210000000

int a,b;
int d[1000],c[1001*1001],hk=0,mcunt,low,high;
int x,pr=0/*,flg[200000000]*/,m,ff=0;

int main(){ 
	
	scanf("%d %d",&a,&b);
	while(a!=0 && b!=0){
		d[0]=0;
		hk=0;
		ff=0;
		pr=0;
		for(int i=1;i<=a;i++) scanf("%d",&d[i]);
		
		for(int i=0;i<=a;i++){
			for(int j=0;j<=a;j++){
				c[hk]=d[i]+d[j];
				hk++;
			}
		}
		sort(c,c+hk);									 
		for(int i=0;i<hk;i++){
			x=b-c[i];
			low=0;
			high=hk-1;
			while(low<=high){
				m=(low+high)/2;
				if(x==c[m]){
					ff=1;
					break;
				}
				if(x>c[m]) low=m+1;
				else if(x<c[m]) high=m-1;
			}
			if(ff==1){
				pr=c[i]+c[m];
				break;
			}
			if(b>c[i]+c[high] && pr<c[i]+c[high]){
				pr=c[i]+c[high];
			}
		}
		printf("%d\n",pr);
		scanf("%d %d",&a,&b);
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
int dp[5][1005];

int main()
{
//	cut here before submit 
//	freopen ("testcase.darts", "r", stdin );
	int n, m;
	while (cin >> n >> m && n && m ){
		memset (dp, 0, sizeof (dp ) );
		vector<int> p (n, 0 );
		rep (i, n ){
			cin >> p[i];
		} // end rep
//		sort (ALL (p ) );

		rep (i, n ){
			dp[0][i] = (p[i] <= m ? p[i] : 0 );
		} // end rep
		rep (i, 4 ){
			rep (j, n ){
				if (dp[i][j] != 0 ){
					rep (k, n ){
						dp[i+1][k] = (p[k] + dp[i][j] <= m ? max (dp[i+1][k] , p[k] + dp[i][j] ) : dp[i+1][k] );
					} // end rep
				} // end if
			} // end rep
		} // end rep
/*
		rep (i, 4 ){
			rep (j, n ){
				cout << setw(3) << dp[i][j];
			} // end rep
			cout << endl;
		} // end rep
*/
		int res = 0;
		rep (i, 4 ){
			for (int j = n; j >= 0; j-- ){
				if (dp[i][j] != 0 ){
					res = max (res, dp[i][j] );
					break;
				} // end if
			} // end for
		} // end rep
		cout << res << endl;

	} // end loop
		
	return 0;
}

C++: #include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

#define INF (2 << 28)
#define fr first
#define sc second
using namespace std;

typedef long long ll;
typedef pair<int, int> iP;

int main(){
  
  int n, m, p[1111];
  int sum[1111111], maxi = 0;

  while(cin >> n >> m, n||m){
    maxi = 0;
    for(int i = 0; i < n; i++){
      cin >> p[i]; 
      if(p[i] <= m) maxi = max(maxi, p[i]);
    }
    
    for(int i = 0; i < n; i++){
      for(int j = 0; j < n; j++){
        sum[i * n + j] = p[i] + p[j];
        if(sum[i * n + j] <= m) maxi = max(maxi, sum[i * n + j]);
      }
    }
    
    for(int i = 0; i < n; i++){
      for(int j = 0; j < n; j++){
        if(sum[i * n + j] <= m){
          maxi = max(maxi, sum[i * n + j]);
          if(sum[i * n + j] + p[i] + p[j] <= m)
            maxi = max(maxi, sum[i * n + j] + p[i] + p[j]);
          if(sum[i * n + j] + p[i] <= m)
            maxi = max(maxi, sum[i * n + j] + p[i]);
          if(sum[i * n + j] + p[j] <= m)
            maxi = max(maxi, sum[i * n + j] + p[j]);
        }
      }
    }
    cout << maxi << endl;
  }
}