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<bits/stdc++.h>
using namespace std;
int main(){
  int n,m,p[1001],ans;
  while(cin >> n >> m){
    if(n == 0 && m == 0) break;
    vector<int> vec1,vec2;
    for(int i=0;i<n;i++) cin >> p[i];
    p[n] = 0;
    for(int i=0;i<=n;i++){
      for(int j=0;j<=n;j++){
	vec1.push_back(p[i]+p[j]);
	vec2.push_back(p[i]+p[j]);
      }
    }
    ans = 0;
    for(int i=0;i<vec1.size();i++){
      for(int j=0;j<vec2.size();j++){
	if(m >= vec1[i] + vec2[j]) ans = max(ans,vec1[i]+vec2[j]);
      }
    }
    cout << ans << endl;
  }
  return (0);
}

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

int main() {
    while(true) {
        int n,m; scanf("%d%d", &n, &m);
        if(n==0) break;
        static int ps[1001];
        static int pps[1002001];
        for(int i = 0; i < n; i++) scanf("%d", ps+i);
        ps[n++] = 0;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                pps[i*n+j] = ps[i]+ps[j];
        sort(pps, pps+n*n);
        int max_val = 0;
        int x = 0;
        int y = n*n-1;
        while(x<n*n && y>=0) {
            if(pps[x]+pps[y]<=m) {
                max_val = max(max_val, pps[x]+pps[y]);
                x++;
            } else {
                y--;
            }
        }
        printf("%d\n", max_val);
    }
    return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<cstdio>
#include<map>
#include<algorithm>
#include<stack>
#define P pair<int,int>
using namespace std;

int g[1000005];
int main() {
	int a, b, c[1001];
	while (scanf("%d%d", &a, &b), a | b) {
		for (int d = 0; d < a; d++)scanf("%d", &c[d+1]);
		c[0] = 0;
		int sum = 0;
		for (int e = 0; e <= a; e++) {
			for (int f = e; f <= a; f++) {
				g[sum] = c[e] + c[f];
				sum++;
			}
		}
		sort(g, g + sum);
		int MAX = 0;
		for (int l = 0; l < sum; l++) {
			auto x = upper_bound(g, g + sum, b - g[l]);
			x--;
			if(g[l]<=b)MAX = max(MAX, g[l] + *x);
		}
		cout << MAX << endl;
	}
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<climits>

using namespace std;

int main() {
	long long   m[10], t[10][1000]{ 0 }, a[1000];
	int n[10], i = 0;
	while (1) {
		cin >> n[i] >> m[i];
		if (n[i] == 0)break;
		for (int j = 0; j < n[i]; j++)cin >> t[i][j];
		i++;
	}
	for (int k = 0; k < i; k++) {
		long long ans = 0;
		for (int j = 0; j < n[k]; j++)a[j] = t[k][j];
		sort(a, a + n[k]);
		for (int p = n[k] - 1; p >= 0; p--) {
			if (a[p] > m[k])continue;
			else if (a[p] == m[k]) {
				ans = m[k];
				goto ANS;
			}
			else if (ans > a[p] * 4)goto ANS;
			else {
				ans = max(ans, a[p]);
				if (m[k] < a[p] + a[0])break;
				for (int q = p; q >= 0; q--) {
					if (a[p] + a[q] > m[k])continue;
					else if (a[p] + a[q] == m[k]) {
						ans = m[k];
						goto ANS;
					}
					else if (ans > a[p] + a[q] * 3)break;
					else {
						ans = max(ans, a[p] + a[q]);
						if (m[k] < a[p] + a[q] + a[0])break;
						for (int r = q; r >= 0; r--) {
							if (a[p] + a[q] + a[r] > m[k])continue;
							else if (a[p] + a[q] + a[r] == m[k]) {
								ans = m[k];
								goto ANS;
							}
							else if (ans > a[p] + a[q] + a[r] * 2)break;
							else {
								ans = max(ans, a[p] + a[q] + a[r]);
								if (m[k] < a[p] + a[q] + a[r] + a[0])break;
								for (int s = r; s >= 0; s--) {
									if (a[p] + a[q] + a[r] + a[s] > m[k])continue;
									else if (a[p] + a[q] + a[r] + a[s] == m[k]) {
										ans = m[k];
										goto ANS;
									}
									else if (ans > a[p] + a[q] + a[r] + a[s])break;
									else ans= a[p] + a[q] + a[r] + a[s];
								}
							}
						}
					}
				}
			}
		}
	ANS:
		cout << ans << endl;
	}
	return 0;
}

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

using namespace std;

int main(){

	int n,m;
	while(cin>>n>>m&&!(n==0&&m==0)){
		int scores[1001];
		vector<int> comb;
		for(int i = 0; i < n; i++){
			cin>>scores[i];
		}
		scores[n]=0;
		for(int i = 0; i < n+1; i++){
			for(int j = 0; j < n+1; j++){
				int sum=scores[i]+scores[j];
				if(sum<=m)
					comb.push_back(sum);
			}
		}
		sort(comb.begin(),comb.end());
		comb.erase(unique(comb.begin(),comb.end()),comb.end());

		int maxNum=0;
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				int left = (scores[i]+scores[j]);
				if(left<=m&&comb[0]+left<=m){
					vector<int>::iterator it = lower_bound(comb.begin(),comb.end(),m-left);
					if(it==comb.end()){
						maxNum=max(maxNum,comb[comb.size()-1]+left);
					}
					else{
						if(*it==(m-left)){
							maxNum=m;
						}
						else{
							it--;
							maxNum=max(maxNum,*it+left);
						}
					}
				}
			}
		}
		cout<<maxNum<<endl;
	}

	return 0;
}

C++: #include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<queue>
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) for(int i=0;i<(n);i++)
using namespace std;
typedef long long ll;


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	
	int N;
	ll M;
	cin >> N >> M;
	if (N == 0 && M == 0) return 0;
	vector<ll> P(N + 1);
	REP(i, N) cin >> P[i];
	P[N] = 0;
	vector<ll> sum((N + 1) * (N + 1));
	REP(i, N + 1)REP(j, N + 1) sum[(N + 1) * i + j] = P[i] + P[j];
	sort(sum.begin(),sum.end());
	ll res = 0;
	REP(i, N + 1)REP(j, N + 1) {
		if (sum[(N + 1) * i + j] <= M) {
			int n = upper_bound(sum.begin(), sum.end(), M - sum[(N + 1) * i + j]) - sum.begin() - 1;
			res = max(res, sum[(N + 1) * i + j] + sum[n]);
		}
	}
	cout << res << "\n";

	return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using int64 = int64_t;

constexpr int64 MOD = 1000000007;

int N, M, arr[1000];

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    while (true) {
        cin >> N >> M;
        if (N == 0 && M == 0) break;
        arr[0] = 0; ++N;
        for (int j = 1; j < N; ++j) {
            cin >> arr[j];
        }
        int arr2[1002*1002];
        for (int j = 0; j < N; ++j) for (int k = 0; k < N; ++k) {
            arr2[N*j+k] = arr[j] + arr[k];
        }
        sort(arr2, arr2+N*N);

        int ans = 0;
        for (int j = 0; j < N*N; ++j) {
            if (arr2[j] > M) break;
            ans = max(ans, arr2[j] + *(upper_bound(arr2, arr2+N*N, M-arr2[j])-1));
        }
        cout << ans << endl;
    }
    return 0;
}