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 _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

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()
#define DEBUG 0

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
string FILE_NAME = "testcase.dart";
string NAME;
string itos (int n )
{
	stringstream ss;
	ss << n;

	return ss.str();
}

int main()
{
//	cut here before submit 
#if DEBUG
	NAME = FILE_NAME;
	int CNT = 1;
	NAME += itos (CNT );
	while (freopen (NAME.c_str() , "r", stdin ) != NULL ) {
#endif
	int n, m;
	while (scanf ("%d %d", &n, &m ), n, m ){
		vector<int> p (n, 0 );
		rep (i, n )	scanf ("%d", &p[i] );
		set<int> total; total.clear();
		rep (i, n ){
			if (p[i] <= m )
				total.insert (p[i] );
		} // end rep
		set<int>::iterator it;
		rep (i, 3 ){
			it = total.begin();
			set<int> next = total;
			for (; it != total.end(); it++ ){
				int curr = (*it);
				rep (j, n ){
					if (curr + p[j] <= m ){
						next.insert (curr + p[j] );
					} // end if
				} // end rep
			} // end for
			total = next;
		} // end rep
	
		int res = 0;
		it = total.begin();
		for (; it != total.end(); it++ ){
			int curr = (*it);
			res = max (res, curr );
		} // end for
		printf ("%d\n", res );
	} // end while
#if DEBUG
	CNT++;	// cut here before submit
	NAME = FILE_NAME;
	NAME += itos (CNT );
	} // end loop; cut here before submit
#endif			
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std ;

#define pb(n) push_back(n)
#define fi first
#define se second
#define all(r) (r).begin(),(r).end()
#define gsort(st,en) sort((st),(en),greater<int>())
#define vmax(ary) *max_element(all(ary))
#define vmin(ary) *min_element(all(ary))
#define debug(x) cout<<#x<<": "<<x<<endl
#define fcout(n) cout<<fixed<<setprecision((n))
#define scout(n) cout<<setw(n)
#define vary(type,name,size,init) vector< type> name(size,init)

#define rep(i,n) for(int i = 0; i < (int)(n);++i)
#define REP(i,a,b) for(int i = (a);i < (int)(b);++i)
#define repi(it,array) for(auto it = array.begin(),end = array.end(); it != end;++it)
#define repa(n,array) for(auto &n :(array))

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using dict = map<string,int>;
using pii = pair<int,int> ;
using pll = pair<ll,ll> ;

const int mod = 1000000007;
constexpr int imax = ((1<<30)-1)*2+1 ;
constexpr int inf = 1000000000;
constexpr double PI = acos(-1.0) ;
double eps = 1e-10 ;
const int dy[] = {-1,0,1,0};
const int dx[] = {0,-1,0,1};

inline bool value(int x,int y,int w,int h){
  return (x >= 0 && x < w && y >= 0 && y < h);
}

ll n,m;
vector<set<ll>> dp(5);

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(cin >> n >> m && n && m){
    vary(ll,s,1001,0);
    rep(i,n){
      cin >> s[i];
    }
    sort(s.begin(),s.begin()+n);
    dp = vector<set<ll>>(5);
    dp[0].insert(0LL);
    ll ans = -1;
    rep(i,4){
      for(auto &&e : dp[i]){
        if(e > m) break;
        dp[i+1].insert(e) ;
        rep(k,n){
          if(e+s[k] <= m){
            if(i == 3){
              ans = max(ans,e+s[k]);
            }
            else{
              dp[i+1].insert(e+s[k]);
            }
          }
        }
      }
      dp[i].clear();
    }
    cout << ans << endl;
  }
  return 0;
}

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

using namespace std;

#define sz			size()
#define lgt			length()
#define rep(i,n)	for (int i = 0; i < n; i++)
#define ALL(X)		(X).begin(),(X).end()
#define RALL(X)		(X).rbegin(),(X).rend()
#define pb			push_back
#define SORT(a)		sort(ALL(a));
#define RSORT(a)	sort(RALL(a));
#define mp			make_pair
#define dump(x)		cerr<<#x<<" = "<<(x)<<endl;
#define fir			first
#define sec			second

typedef pair<int,int> P;
typedef vector<int> vi;
typedef vector<string> vs;

int toInt(string s){int v;istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
vs form(string a,char s){vs v;string b;rep(i,a.lgt){if(a[i]==s){v.pb(b);b="";}else b+=a[i];}v.pb(b);return v;}
vi formint(string a,char s){vi v;string b;rep(i,a.lgt){if(a[i]==s){v.pb(toInt(b));b="";}else b+=a[i];}v.pb(toInt(b));return v;}

const double EPS=1e-10,PI=acos(-1.0);
const int INF=2100000000;

vector <int> v, v1;

int main(void)
{
	int n, m, tmp;
	while (cin >> n >> m, n && m){
		int res = 0;
		
		v.pb(0);
		for (int i = 0; i < n; i++){
			cin >> tmp;
			v.pb(tmp);
		}
		for (int i = 0; i < v.sz; i++){
			for (int j = 0; j < v.sz; j++){
				v1.pb(v[i] + v[j]);
			}
		}
		SORT(v1);
		
		
		int i, j = v1.sz - 1;
		for (i = 0; i <= v1.sz; i++){
			for (j = v1.sz - 1; m < v1[i] + v1[j] && 0 <= j; j--){}
//			cout << v1[i] << " " << v1[j] << "*" << j << endl;
			if (0 <= j) res = max(res, v1[i] + v1[j]);
		}
		
		cout << res << endl;
		v.clear();
		v1.clear();
	}
	
	return 0;
}