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 <cstdio>
#include <cctype>
#include <utility>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

const auto gcu = getchar_unlocked;
const auto pcu = putchar_unlocked;
#define _T template <typename T>
#define _HT template <typename H, typename... T>
#define _il inline
#define _sc _il bool scan
_T T in(int c){T n=0;int m=1;while(isspace(c)){c=gcu();}if(c=='-')m=-1,c=gcu();
	do{n=10*n+(c-'0'),c=gcu();}while(c>='0'&&c<='9');return m*n;}
_il int in() {return in<int>(gcu());}
_T T scan(T &n){int c=gcu();return c==EOF?false:(n=in<T>(c),true);}
_sc(char &c){c=gcu();gcu();return c!=EOF;}
#ifdef _GLIBCXX_STRING
_sc(string &s){int c;s="";
	for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=c;}}
#endif
_HT _sc(H &h, T&&... t){return scan(h)&&scan(t...);}
#define _ot _il void out
#define _ol _il void outl
_ot(bool b) {pcu('0'+b);}
_ot(const char *s){while(*s)pcu(*s++);}
_ot(char c){pcu(c);}
#ifdef _GLIBCXX_STRING
_ot(string s){for(char c:s)pcu(c);}
#endif
_T _ot(T n){static char b[20];char *p=b,m=n<0?pcu('-'),-1:1;
	if(!n)*p++='0';else while(n)*p++=n%10*m+'0',n/=10;while(p!=b)pcu(*--p);}
_ol(){out('\n');}
#ifdef _GLIBCXX_VECTOR
_T _ot(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);outl();}
#endif
_HT _ot(H&& h, T&&... t){out(h);out(move(t)...);}
template <typename... T> _ol(T&&... t){out(move(t)...);outl();}

int main() {
	for (int N, M; N = in(), M = in();) {
		vector<int> t(N), u;
		for (int &p: t)
			p = in();
		t.push_back(0);
		sort(t.rbegin(), t.rend());
		for (auto i = t.begin(); i != t.end(); i++)
			for (auto j = i; j != t.end(); j++)
				if (*i + *j <= M)
					u.push_back(*i + *j);
		sort(u.rbegin(), u.rend());
		u.erase(unique(u.begin(), u.end()), u.end());
		int r = 0;
		for (auto i = u.begin(), e = u.end(); i != e; i++) {
			e = lower_bound(i + 1, e, M - *i, greater<int>());
			r = max(r, *i + *e);
		}
		outl(r);
	}
}

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

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define INF 1 << 30
#define EPS 1e-10

typedef pair<int, int> pi;
typedef pair<int, pi> pii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;

int N, M, P[1001];

int main(){
  while(scanf("%d%d", &N, &M) && N+M){
    rep(i, N)  scanf("%d", P+i);
    P[N] = 0;
    vi p;
    rep(i, N+1) rep(j, N+1) if(P[i] + P[j] <= M) p.PB(P[i]+P[j]);
    sort(p.begin(), p.end());

    int res = 0;
    rep(i, p.size()){
      int d = M - p[i];
      int l = p[0], h = p[p.size()-1];
      int m;
      while(h - l > 1){
	m = (l+h)/2;
	if(p[m] < d) l = m;
	else if(p[m] > d) h = m;
	else break;
      }
      if(p[m] > d) m--;
      //      printf("%d %d\n", p[m], p[i]);
      res = max(res, p[m] + p[i]);
    }
    printf("%d\n", res);
  }
  return 0;
}

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

#define MAX_N 1001

using namespace std;

void rawcomb(vector<int> &v, int n, int rest, int nowsum, int targetSum, int *result){
	if( rest == 0 ){
		if( nowsum <= targetSum ){
			*result = max( *result, nowsum );
		}
		return ;
	}
	for(int i = 0; i < n; i++){
		nowsum += v[i];
		rawcomb(v, n, rest - 1, nowsum, targetSum, result);
		nowsum -= v[i];
	}
}

int main(void){
	while( 1 ){
		int n, m;
		vector<int> v(MAX_N,0);
		int Max = 0;
		cin >> n >> m;

		if( n == 0 && m == 0 ){
			break;
		}

		for(int i = 0; i < n; i++){
			cin >> v[i];
		}
		v[n + 1] = 0;

		sort(v.begin(), v.begin() + n + 1);
		reverse(v.begin(), v.begin() + n + 1);

		rawcomb(v, n + 1, 4, 0, m, &Max);

		cout << Max << '\n';
	}
	return 0;
}

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

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)

int main(){
    int N, M;
    while(std::cin >> N >> M, N){
        int parts[1010];
        REP(i, N){
            std::cin >> parts[i];
        }
        parts[N] = 0;

        std::vector<int> half;
        REP(i, N+1){
            REP(j, N+1){
                if(parts[i] + parts[j] <= M){
                    half.push_back(parts[i] + parts[j]);
                }
            }
        }

        int res = 0;

        std::sort(half.begin(), half.end());
        REP(i, half.size()){
            int v = half[i],
                index = std::lower_bound(half.begin(), half.end(), M-v) - half.begin();
            if(half[index] + v == M){
                res = M;
            }else if(index - 1 >= 0){
                res = std::max(res, v + half[index-1]);
            }
        }

        std::cout << res << std::endl;
    }
}

C++: //Solution for AOJ 0529: Darts
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_N = 1000, MAX_M = 200000000;
int n, m;
int p[MAX_N + 1], p2[MAX_N*MAX_N], ans, roop, s, mid;
void search(int end, int start){
	if ((end + start) % 2)
		mid = (end + start) / 2 + 1;
	else
		mid = (end + start) / 2;
	if (p2[mid] == s)
		return;
	if (p2[mid] < s){
		if (end - mid == 1){
			if (p2[end]<s)
				mid++;
			return;
		}
		search(end, mid);
	}
	else{
		if (mid - start == 1){
			mid--;
			return;
		}
		search(mid, start);
	}
}
int main(){
	while (cin >> n >> m){
		ans = 0;
		if (!n&&!m)
			return 0;
		for (int i = 1; i <= n; i++){
			cin >> p[i];
		}
		roop = 0;
		for (int i = 0; i <= n; i++){
			for (int j = i; j <= n; j++){
				if (p[i] + p[j] <= m){
					p2[roop] = p[i] + p[j];
					roop++;
				}
			}
		}
		sort(p2, p2 + roop);
		for (int i = 0; i < roop; i++){
			s = m - p2[i];
			search(roop - 1, 0);
			ans = max(ans, p2[i] + p2[mid]);
			if (ans == m)
				break;
		}
		cout << ans << endl;
	}
}

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

#define MAX_N 1000
int P[MAX_N + 1];
int N, M;
int table[5][MAX_N + 1];

int dfs(int a, int b, int c){
	if(c > M) return P[b] * -1;
	if(a == 0) return P[b];
	if(table[a][b] >= 0) return table[a][b];
	
	int cho = b;
	while(cho <= N){
		int d = dfs(a - 1, cho, c + P[b]) + P[b];
		table[a][b] = max(table[a][b], (d > M)? 0 : d);
		cho++;
	}
	
	return table[a][b];
}

int main(){
	ifstream ifs("input.txt");
	
	for(int i = 0; i < 5; i++){
		for(int j = 0; j <= MAX_N; j++){
			table[i][j] = -1;
		}
	}
	
	ifs >> N >> M;
	
	P[0] = 0;
	for(int i = 1; i <= N; i++) ifs >> P[i];
	
	printf("%d\n", dfs(4, 0, 0));
	
	return 0;
}