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+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 <algorithm>
#include <vector>
#include <cstring>
using namespace std;

int n, m, point1[1001], sum, ans;
vector<int> point2;

int solve(int start, int end, int border){
    int mid;
    while(1){
        if((end + start) % 2){
            mid = (end + start) / 2 + 1;
        } else{
            mid = (end + start) / 2;
        }

        if(point2[mid] > border){
            end = mid;
        } else{
            start = mid;
        }

        if(end - start == 1){
            if(point2[end] < border){
                return point2[end];
            } else{
                return point2[start];
            }
        }
    }
}

int main(){
    while(cin >> n >> m && n && m){
        for(int i = 0; i < n; i++){
            cin >> point1[i];
        }
        for(int i = 0; i < n + 1; i++){
            for(int j = 0; j < n + 1; j++){
                point2.push_back(point1[i] + point1[j]);
            }
        }

        sort(point1, point1 + n + 1);
        sort(point2.begin(), point2.end());

        for(int i = 0; i < n + 1; i++){
            if(point2[i] > m){
                continue;
            }
            ans = max(ans, points2[i] + solve(0, point2.size() - 1, m - point2[i]));
        }

        cout << ans << endl;

        memset(point1, 0, sizeof(point1));
        point2.clear();
        ans = 0;
    }

    return 0;
}

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

int main()
{
	ios::sync_with_stdio(false), cin.tie(0);
	int N, M;
	while (cin >> N >> M, N | M) {
		vector<int> P(N);
		for (int i = 0; i < N; i++) {
			cin >> P[i];
		}
		P.push_back(0);
		sort(P.begin(), P.end());
		P.erase(unique(P.begin(), P.end()), P.end());
		int N = P.size();
		vector<int> all;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				all.push_back(P[i] + P[j]);
			}
		}
		sort(all.begin(), all.end());
		all.erase(unique(all.begin(), all.end()), all.end());
		int res = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				int id = upper_bound(all.begin(), all.end(), M - (P[i] + P[j])) - all.begin() - 1;
				if (id >= 0) {
					res = max(res, P[i] + P[j] + all[id]);
				}
			}
		}
		cout << res << endl;
	}
	return 0;
}

C++: #include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m;
vector<int> p;
int main(void){
  while(1){
    cin >> n >> m; if(!n) break;
    p.clear();
    for(int i = 0; i < n; i++){
      int a;
      cin >> a;
      p.push_back(a);
    }
    for(int i = 0; i < n; i++){
      for(int j = i; j < n; j++){
	p.push_back(p[i] + p[j]);
      }
    }
    p.push_back(0);
    sort(p.begin(),p.end());
    int ret = 0;
    for(int i = 0; i < (int)p.size() && p[i] < m; i++){
      ret = max(ret,*(upper_bound(p.begin(),p.end(),m - p[i]) - 1) + p[i]);
    }
    cout << ret << endl;
  }
}

C++: #include<stdio.h>
#include<algorithm>

#define rep(i,j) for(int i=0;i<(j);i++)
#define reps(i,j,k) for(int i=j;i<=k;i++)

using namespace std;
int main(){
	int n,m,ans,p[1001];
	int dp[1001][4];
	for(;;){
		scanf("%d%d",&n,&m);
		if(n==0&&m==0)break;
		rep(i,1001)rep(j,4)dp[i][j]=0;
		rep(i,n)scanf("%d",p+i);
		sort(p,p+n);
		ans = 0;
		rep(i,n)if(p[i]<=m)dp[i][0] = p[i];
		rep(i,4){
			rep(j,n){
				rep(k,i)rep(l,n){
					int t = dp[l][k] + p[j];
					if(t <= m){
						dp[j][i] = max(dp[j][i],t);
					}
				}
				ans = max(ans,dp[j][i]);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using vb=vector<bool>;
using vvb=vector<vb>;
using vd=vector<double>;
using vvd=vector<vd>;
using vl=vector<ll>;
using vvl=vector<vl>;
using pll=pair<ll,ll>;
using tll=tuple<ll,ll>;
using vs=vector<string>;
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define rep(i,n) range(i,0,n)
#define range(i,a,n) for(int i=(a);i<(n);i++)

#define LINF    	((ll)1ll<<60)
#define INF     	((int)1<<30)
#define EPS     	(1e-9)
#define MOD     	(1000000007ll)
#define fcout(a)	cout<<setprecision(a)<<fixed
#define fs 			first
#define sc			second
#define PI			3.1415926535897932384

int dx[]={1,0,-1,0,1,-1,-1,1},dy[]={0,1,0,-1,1,1,-1,-1};
template<class S,class T>ostream&operator<<(ostream&os,pair<S,T>p){os<<"["<<p.first<<", "<<p.second<<"]";return os;};
template<class S>auto&operator<<(ostream&os,vector<S>t){bool a=1; for(auto s:t){os<<(a?"":" ")<<s; a=0;} return os;}
void OUT(bool b){cout<<(b?"YES":"NO")<<endl;}
void Out(bool b){cout<<(b?"Yes":"No")<<endl;}
void out(bool b){cout<<(b?"yes":"no")<<endl;}
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int clz(int x) { return 31 - __builtin_clz(x); }
int clz(ll x) { return 63 - __builtin_clzll(x); }
int ctz(int x) { return __builtin_ctz(x); }
int ctz(ll x) { return __builtin_ctzll(x); }

class compare {
public:
	bool operator()(tuple<ll, ll> a, tuple<ll, ll> b) {
		return (get<1>(a) > get<1>(b));
	}
};

void solve(ll n,ll m){
	ll ans=0;
	vl v(n);
	rep(i,n){
		cin>>v[i];
	}
	v.push_back(0);
	set<ll> cop;
	rep(i,n+1){
		range(j,i,n+1){
			cop.insert(v[i]+v[j]);
		}
	}
	for(auto x:cop){
		for(auto y:cop){
			if(x+y<=m)ans=max(ans,x+y);
		}
	}
	cout<<ans<<endl;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll n,m;
	while(cin>>n>>m,n){
		solve(n,m);
	}
}

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 SQ(x) ((x)*(x))
#define Mod(x, mod) (((x)+(mod)%(mod))
#define MP make_pair
#define PB push_back
#define Fi first
#define Se second
#define INF (1<<29)
#define EPS 1e-10
#define MOD 1000000007

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

int N;
ll M;
ll P[1024];

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