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++: #include <bits/stdc++.h>
#define MAX 100000000

int main()
{

    int N, maxv, tmp;
    int ans;
    while(1) {
        std::scanf("%d %d", &N, &maxv);
        if (N == 0 && maxv == 0) break;
        std::vector<int> nums;
        nums.reserve(MAX);
        ans = 0;

        int arr[N+1];
        arr[0] = 0;

        for (int i = 1; i <= N; i++) {
            std::scanf("%d", &arr[i]);
            for (int j = 0; j <= i; j++) {
                tmp = arr[i] + arr[j];
                if (tmp < maxv) nums.push_back(tmp);
            }
        }
        std::sort(nums.begin(), nums.end());

        for (unsigned long i = 0; i < nums.size(); i++) {
            tmp = nums[i] + nums[std::upper_bound(nums.begin(), nums.end(), maxv-nums[i]) - nums.begin() - 1];
            if (tmp > ans) ans = tmp;
            if (ans == maxv) break;
        }
        std::cout << ans << std::endl;
    }

    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define INF 100000005
#define MAX 1004

int p[MAX], q[MAX*MAX];
int main(){
	int n, m, ans, qq;
	while(cin >> n >> m, n){
		for(int i = 1;i <= n;i++)cin >> p[i];
		ans = 0;p[0] = 0;qq = 0;
		
		for(int i = 0;i <= n;i++){
			for(int j = 0;j <= n;j++){
				q[qq++] = p[i] + p[j];
			}
		}
		sort(q, q+qq);
		int t;
		//for(int i = 0;i < qq;i++)cout << q[i] << endl;
		for(int i = 0;i < qq;i++){
			t = upper_bound(q, q+qq, (m-q[i]))-q;
			if(t-1 >= 0)ans = max(ans, q[i]+q[t-1]);
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #define _USE_MATH_DEFINES
#include<stdio.h>
#include<string>
#include<iostream>
#include<cctype>
#include<cstdio>
#include<vector>
#include <algorithm>
#include<math.h>
#include<set>
#include<map>
#include<iomanip>
using namespace std;


int main(){
	
	int n,m;
	while(1){
		cin>>n>>m;
		if(!n&&!m)break;
		int g[1009]={};
		int w=2000000000;
		for(int i=0;i<n;i++)
		{cin>>g[i];w=min(w,g[i]);}
		sort(g,g+n);
		reverse(g,g+n);
		long long int ans=0;
		int y=0;
		int r=n-1;
		int i=0;
		while(i<n){
			if(ans+g[y]+(r-i)*w<=m){ans+=g[y];i++;}
			else y++;
		}
		cout<<ans<<endl;
	}
	


	return 0;
}

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

int p[1010];
int sum[1002010];

int main(void){
	int n,m;

	while(scanf("%d%d",&n,&m) && (n||m)){
		for(int i=0;i<n;i++){
			scanf("%d",&p[i]);
		}
		p[n++] = 0; //0点のスコアを作る

		int size=0;
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				sum[size++] = p[i] + p[j];
			}
		}
		sort(sum,sum+size);

		int ans = 0;

		for(int i=0;i<size;i++){
			int rem = m - sum[i];
			if(rem < 0) continue;
			int left = 0, right = size;

			while(left < right){
				int center = (left + right) / 2;
				if(rem > sum[center]){
					left = center + 1;
				}
				else if(rem < sum[center]){
					right = center;
				}
				else {
					break;
				}
			}

			ans = max(ans, sum[i] + sum[right-1]);
		}

		printf("%d\n",ans);
	}

	return 0;
}

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

int main() {
    int N, M;
    while (cin >> N >> M, N) {
        vector<int> p(N + 1);
        for (int i = 0; i < N; i++) cin >> p[i];
        p[N] = 0;
        // 半分全列挙
        vector<int> pp;
        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < N + 1; j++) {
                pp.push_back(p[i] + p[j]);
            }
        }
        sort(pp.begin(), pp.end());
        // 二分探索
        int ma = 0;
        for (int i = 0; i < pp.size(); i++) {
            if (M - pp[i] >= 0) {
                int rest = *(upper_bound(pp.begin(), pp.end(), M - pp[i]) - 1);
                ma = max(ma, pp[i] + rest);
            }
        }
        cout << ma << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
using namespace std;

int N, M;
int P[1000];
int D[1002000];
int S;

int main() {
  while (cin >> N >> M) {
    if (N == 0 && M == 0) break;
    for (int i=0; i<N; i++) cin >> P[i];
    D[0] = 0;
    for (int i=0; i<N; i++) {
      D[i+1] = P[i];
      for (int j=0; j<N; j++) {
        D[(i+1)*N + j + 1] = P[i] + P[j];
      }
    }
    S = N*(N+1) + 1;
    sort(D, D + S);
    int ans = 0;
    for (int i=0; i<N*N; i++) {
      ans = max(ans, D[i] + *(upper_bound(D, D + S, M - D[i]) - 1));
    }
    cout << ans << "\n";
  }
  return 0;
}

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

#define MOD 1000000007

using namespace std;
typedef long long ll;
//typedef pair<int, int> P;

vector<ll> P1,P2;
ll ans;

int main()
{
	ll N, S;
	while (1) {
		cin >> N >> S;
		if (N == 0 && S == 0)break;
		ans = 0;
		P1.clear(),P2.clear();

		P1.push_back(0);
		for (int i = 0; i < N; i++) {
			int a;
			cin >> a;
			P1.push_back(a);
		}
		sort(P1.begin(),P1.end());

		for (int i = 0; i <= N; i++) {
			for (int j = i; j <= N; j++) {
				if (P1[i] + P1[j] <= S)P2.push_back(P1[i] + P1[j]);
			}
		}
		sort(P2.begin(),P2.end());
		int cnt = P2.size() - 1;
		for (int i = 0; i < P2.size(); i++) {
			while (P2[i] + P2[cnt] > S)cnt--;
			if (P2[cnt] + P2[i] <= S)
				ans = max(ans, P2[cnt] + P2[i]);
		}
		cout << ans << endl;
	}
	return 0;
}

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

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for(int i = 0;i < (n);i++)
#define FOR(i, a, b) for(int i = (a);i < (b);i++)
#define all(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;
typedef pair<int, PII> PPII;
typedef pair<int, PPII> PPPII;

class Union_find{
private:
	vector<int> par;
	vector<int> rank;
	int n;

public:
	Union_find(int a){
		n = a;
		for(int i = 0;i < n;i++){
			par.push_back(i);
			rank.push_back(0);
		}
	}

	int find(int x){
		if(par[x] == x){
			return x;
		}else{
			return par[x] = find(par[x]);
		}
	}

	void unite(int x, int y){
		x = find(x);
		y = find(y);
		if(x == y) return;

		if(rank[x] < rank[y]){
			par[x] = y;
		}else{
			par[y] = x;
			if(rank[x] == rank[y]) rank[x]++;
		}
	}

	bool same(int x, int y){
		return find(x) == find(y);
	}
};

int main(void){
	ll N, M;
	while(cin >> N >> M && N && M){
	ll P[1010];
	ll res = 0;
	vector<int> two;
	REP(i, N){
		cin >> P[i];
	}
	P[N] = 0;
	REP(i, N+1){
		REP(j, N+1){
			if(P[i]+P[j] <= M)
				two.push_back(P[i]+P[j]);
		}
	}
	sort(all(two));
	REP(i, N+1){
		REP(j, N+1){
			ll a = P[i]+P[j];
			if(a > M) continue;
			res = max(res, a+(*(upper_bound(all(two), M-a)-1)));
		}
	}
	cout << res << endl;
	}
}