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++: // #define _GLIBCXX_DEBUG
#pragma GCC optimize("Ofast")
#pragma GCC diagnostic ignored "-Wsign-compare"
#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;
#define rep(i, n) for (i64 i = 0; i < (i64)(n); ++i)
#define reps(i, s, n) for (i64 i = s; i < (i64)(n); ++i)

void solve(vector<i64> P, i64 N, i64 M) {
    vector<i64> A;
    rep(i, N) rep(j, N) {
        if (M < P[i] + P[j]) {
            continue;
        }
        A.push_back(P[i] + P[j]);
    }
    sort(A.begin(), A.end());

    i64 ans = 0;
    // 矢が1本
    for (auto &&e : P) {
        if (e <= M) {
            ans = max(ans, e);
        }
    }
    // 矢が3本
    for (auto &&e : P) {
        if (M < e) continue;
        i64 add = M - e + 1;
        i64 idx = upper_bound(A.begin(), A.end(), add) - A.begin();
        if (idx != 0 and e + A[idx - 1] <= M) {
            ans = max(ans, e + A[idx - 1]);
        }
    }
    // 矢が2本
    for (auto &&e : A) {
        ans = max(e, ans);
    }
    // 矢が4本
    for (auto &&e : A) {
        i64 add = M - e + 1;
        i64 idx = upper_bound(A.begin(), A.end(), add) - A.begin();
        if (idx != 0 and e + A[idx - 1] <= M) {
            ans = max(ans, e + A[idx - 1]);
        }
    }
    cout << ans << "\n";
}
int main() {
    // cin.tie(0);
    // ios_base::sync_with_stdio(false);
    // cout << fixed << setprecision(15);
    i64 N, M;
    cin >> N >> M;
    while (N != 0 or M != 0) {
        vector<i64> P(N);
        for (auto &&i : P) {
            cin >> i;
        }

        solve(P, N, M);
        cin >> N >> M;
    }
}

C++: #include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;

ll n, m, p[1000], d[600000];

int main() {
  while (scanf("%lld%lld", &n, &m), n) {
    for (ll i = 0; i < n; i++) scanf("%lld", &p[i]);
    ll counter = 0;
    for (ll i = 0; i < n; i++) for (ll j = 0; j <= i; j++) d[counter++] = p[i] + p[j];
    for (ll i = 0; i < n; i++) d[counter++] = p[i];
    sort(d, d + counter);
    ll ans = 0;
    for (ll i = 0, j = counter - 1; i < counter; i++) {
      while (d[i] + d[j] > m) j--;
      if (i > j) break;
      if (ans < d[i] + d[j]) ans = d[i] + d[j];
    }
    printf("%lld\n", ans);
  }
}

C++: // Didn't see editorial
#include <iostream>
#include <queue>
#include <iomanip>
#include <map>
#include <algorithm>

using namespace std;

using ll = long long;
const ll INF = 1e9;
const ll MOD = 1e9 + 7;

int main() {
    while(true) {
        int N; ll M;
        cin >> N >> M;
        if (N == 0) return 0;
        vector<ll> P(N+1);
        for (int i = 0; i < N; i++) {
            cin >> P[i];
        }
        P.push_back(0);
        N += 1;

        vector<ll> Q(N);
        for (int a = 0; a < N; a++) {
            for (int b = 0; b < N; b++) {
                Q.push_back(P[a] + P[b]);
            }
        }
        sort(Q.begin(), Q.end());

        ll mx = 0;
        for (int a = 0; a < N; a++) {
            for (int b = 0; b < N; b++) {
                int x = upper_bound(Q.begin(), Q.end(), M - P[a] - P[b]) - 1 - Q.begin();
                if (x >= 0) {
                    mx = max(mx, P[a] + P[b] + Q[x]);
                }
            }
        }

        cout << mx << endl;
    }
}

C++: #include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <stack>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>

using namespace std;

constexpr int INF = 1000000000;/* 1e+9a */
constexpr int MODULO = 1000000007;

typedef int64_t ll;


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll N, M;
    while(cin >> N >> M)
    {
        if(N == 0) break;
        vector<ll> P;
        P.push_back(0);
        for (int i = 0; i < N; ++i) {
            ll tmp;
            std::cin >> tmp;
            P.push_back(tmp);
        }
        vector<ll> P2;
        for (int i = 0; i < P.size(); ++i) {
            for (int j = i; j < P.size(); ++j) {
                P2.push_back(P[i] + P[j]);
            }
        }
        sort(P2.begin(), P2.end());
        ll maxim = 0;
        for (int i = 0; i < P2.size(); ++i) {
            auto val12 = P2[i];
            auto gval = M - val12;
            if(gval >= 0){
                auto good = upper_bound(P2.begin(), P2.end(), gval);
                maxim = max(maxim, val12 + *(good-1));
            }
            else break;
        }
        cout << maxim << '\n';
    }
}

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

int main(){
while(1){
	int n,m,a,ans=0;
	vector<int> p,pp;
	scanf("%d%d",&n,&m);
if(n==0&&m==0)break;
	p.push_back(0);
	for(int i=0;i<n;i++){
		scanf("%d",&a);
		p.push_back(a);
	}
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			pp.push_back(p[i]+p[j]);
		}
	}
	sort(pp.begin(),pp.end());
	int s=pp.size()-1;
	for(int i=0;i<=s;i++){
		while(pp[i]+pp[s]>m)s--;
		if(ans<pp[i]+pp[s])ans=pp[i]+pp[s];
	}
	printf("%d\n",ans);
}
}

C++: ///
// File:  0529.cpp
// Author: ymiyamoto
//
// Created on Wed Feb 28 21:12:52 2018
//
#include <bits/stdc++.h>
using namespace std;

#define rep(_n, _init, _N) for (int32_t _n = _init; _n < (int32_t)(_N); _n++)
#define rrep(_n, _N, _end) for (int32_t _n = (int32_t)(_N); _n >= _end; _n--)
#define iceil(_x, _y) (((_x) + (_y)-1) / (_y))
#define ifloor(_x, _y) ((_x) / (_y))

static const double pi = 2 * asin(1);
static const double precision = 10e-9;

int32_t main()
{
  while (true) {
    int64_t N, M;
    cin >> N >> M;
    if (N == 0) break;

    vector<int64_t> arr = vector<int64_t>(N + 1);
    rep(i, 1, N + 1)
    {
      cin >> arr[i];
    }
    sort(arr.begin(), arr.end());

    vector<int64_t> sums = vector<int64_t>((N + 1) * (N + 1));
    uint32_t cnt = 0;
    rep(i, 0, N + 1)
    {
      rep(j, 0, N + 1)
      {
        sums[cnt] = arr[i] + arr[j];
        cnt++;
      }
    }

    sort(sums.begin(), sums.end());
    int64_t m = 0;
    rep(i, 0, sums.size())
    {
      int64_t rem = M - sums[i];
      if (0 <= rem) {
        auto p = lower_bound(sums.begin(), sums.end(), rem);
        if (p != sums.begin() && p != sums.end()) {
          m = max(m, *(p - 1) + sums[i]);
        }
      }
    }
    cout << m << endl;
  }

  return 0;
}