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 <array>
#include <numeric>
using namespace std;

const auto gcu = getchar_unlocked;
const auto pcu = putchar_unlocked;
#define _NE noexcept
#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)_NE{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()_NE{return in<int>(gcu());}
_T T scan(T &n)_NE{int c=gcu();return c==EOF?false:(n=in<T>(c),true);}
_sc(char &c)_NE{c=gcu();gcu();return c!=EOF;}
#ifdef _GLIBCXX_STRING
_sc(string &s)_NE{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)_NE{pcu('0'+b);}
_ot(const char *s)_NE{while(*s)pcu(*s++);}
_ot(char c)_NE{pcu(c);}
#ifdef _GLIBCXX_STRING
_ot(string s)_NE{for(char c:s)pcu(c);}
#endif
_T _ot(T n)_NE{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)_NE{for(T &x:v)out(&x == &v[0]?"":" "),out(x);outl();}
#endif
_HT _ot(H&& h, T&&... t)_NE{out(h);out(move(t)...);}
template <typename... T> _ol(T&&... t)_NE{out(move(t)...);outl();}

#define all(o) o.begin(), o.end()

void radix_sort(vector<int> &v) {
	vector<int> t(v.size());
	array<int, 256> c, s;
	for (int i = 0; i < 32; i += 8) {
		fill(all(c), 0);
		for_each(all(v), [&](int j) {c[(j >> i) & 255]++;});
		s.front() = 0;
		partial_sum(all(c) - 1, s.begin() + 1);
		for_each(all(v), [&](int j) {t[s[(j >> i) & 255]++] = j;});
		swap(v, t);
	}
}

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);
		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);
		radix_sort(u);
		int r = 0;
		for (auto i = u.begin(), e = u.end() - 1; i <= e; i++) {
			for (; *i + *e >= M; e--)
				;
			r = max(r, *i + *e);
		}
		outl(r);
	}
}

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

using namespace std;

void solve()
{
	int N, M;
	while(cin >> N >> M, N || M)
	{
		vector<int> Vec(N);
		for(int i = 0; i < N; ++i)
		{
			cin >> Vec[i];
		}
		vector<int> Vec1;
		for(int i = 0; i < N; ++i)
		{
			Vec1.push_back(M - Vec[i]);
			for(int j = 0; j < N; ++j)
			{
				int label = i * N + j;
				int temp = Vec[i] + Vec[j];
				Vec.push_back(temp);
				Vec1.push_back(M - temp);
			}
		}
		sort(Vec.begin(), Vec.end());
		sort(Vec1.begin(), Vec1.end());
		int size = N * N;
		for(int i = 0; i < M; ++i)
		{
			for(int j = 0; j < size; ++j)
			{
				if(binary_search(Vec.begin(), Vec.end(), Vec1[j] - i))
				{
					cout << M - i << endl;
					goto NEXT;
				}
			}
		}
NEXT:
		;
	}
}

int main()
{
	solve();
	return(0);
}

C++: #include<iostream>
using namespace std;
int p[1001],s[1002001];
int main(){
	int n,m;
	while(true){
	cin>>n>>m;
	if(n==0&&m==0)break;
	int cnt=1;
	p[0]=0,s[0]=0;
	for(int i=1;i<=n;i++){
		cin>>p[i];
		for(int j=0;j<=i;j++)
			s[cnt]=p[i]+p[j],cnt++;
	}
	int ans=0;
	for(int i=0;i<cnt;i++){
		int left=0,right=cnt,mid;
		while(true){
			if(left>=right-1)break;
			mid=(left+right)/2;
			if(s[i]+s[mid]<=m){
				ans=max(ans,s[i]+s[mid]);
				left=mid;
			}
			else right=mid;
		}
	}
	cout<<ans<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <string.h>
#include <algorithm>
#include <set>
#include <cstdio>
#include <vector>
using namespace std;

int main() {
	int N, M;
	while(cin >> N >> M && (N || M)){
		int  P[1001] = {0}, ans = 0;
		for(int i = 0; i < N; ++i){
			scanf("%d", &P[i]);
		}
		set<int> darts;
		for(int i = 0; i <= N; ++i){
			for(int j = 0; j <= N; ++j){
				if(P[i] + P[j] <= M)
					darts.insert(darts.end(), P[i] + P[j]);
			}
		}
		vector<int> v(darts.begin(), darts.end());
		for(unsigned int i = 0; i < v.size(); ++i){
			if(v[i] > M)
				continue;
			vector<int>::iterator it = lower_bound(v.begin(), v.end(), M - v[i]);
			if(it == v.end())
				--it;
			if(*it > M - v[i])
				--it;
					
			ans = max(ans, v[i] + *it);
		}
		/*for(int i = 0; i <= N; ++i){
			for(int j = 0; j <= N; ++j){
				if(P[i] + P[j] > M)
					continue;
				set<int>::iterator it = darts.lower_bound(M - (P[i] + P[j]));
				if(it == darts.end())
					--it;
				if(*it > M - (P[i] + P[j]))
					--it;
					
				ans = max(ans, P[i] + P[j] + *it);
			}
		}*/
		cout << ans << endl;
	}
	return 0;
}

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

int n, m;
int p[1001], dp[5][1001];
int main()
{
  while(true){
    //chap1
    cin >> n >> m;
    if(!n && !m) break;
    
    memset(dp, 0, sizeof dp);
    for(int i = 1; i <= n; i++)
      cin >> p[i];

    //chap2
    for(int i = 1; i <= n; i++)
      for(int j = 0; j <= 4; j++)
	for(int k = 0; j + k <= 4; k++)
	  if(dp[i - 1][j] + p[i] * k <= m)
	    dp[i][j + k] = max(dp[i][j + k], dp[i - 1][j] + p[i] * k);

    cout << dp[n][4] << endl;
  }
  return 0;
}

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

int m, n, dp[1001][5];
vector<int> p;

int maxx(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0){
    int t = ( a > b ? a : b ), u = ( c > d ? c : d );
    int v = ( t > u ? t : u );
    return ( v > e ? v : e );
}

int f(int n){
    return (n <= m ? n : 0);
}

int main(){
    while( true ){
        cin >> n >> m;
        if( m == 0 && n == 0 ) break;
        for(int i = 0; i < n; i++){
            int k;
            cin >> k;
            p.push_back(k);
        }
        sort( p.begin(), p.end() , greater<int>() );
        for(int i = 0; i < n; i++){
            for(int j = 0; j < 4; j++){
                dp[i+1][j+1] = maxx( f( dp[i+1][j] + p[i] ),
                                     f( dp[i][j] + p[i] ),
                                     f( dp[i][j+1] ) );
            }
        }
        cout << maxx( dp[n][0], dp[n][1], dp[n][2], dp[n][3], dp[n][4] )
             << endl;
        while( !p.empty() ) p.pop_back();
    }
    return 0;
}

C++: #include <iostream>
#include <map>
#include <algorithm>
#define INF (2LL << 58)
using namespace std;

typedef long long ll;

map<pair<int, int>, ll> dp;
int n, m, p[1111];

ll rec(int sum, int cnt){
    
    if(sum < 0) return -INF;
    if(cnt == 4) return 0;
    //if(dp[make_pair(sum, cnt]) return dp[make_pair(sum, cnt)];
    
    ll ret = -INF;
    for(int i = 0; i < n; i++){
        ret = max(ret, max(rec(sum - p[i], cnt + 1) + p[i], rec(sum, cnt + 1)));
    }
    return ret;
}

int main(){
    
    while(cin >> n >> m, n||m){
        dp.clear();
        for(int i = 0; i < n; i++) cin >> p[i];
        cout << rec(m, 0) << endl;
    }
}