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 <iostream>
#include <queue>

using namespace std;

int main()
{
    for(;;) {
        int n, m;
        cin >> n >> m;
        if ( n == 0 && m == 0 )
            break;

        priority_queue<int> q;

        for( int i=0; i<n; ++i ) {
            int in;
            cin >> in;
            q.push( in );
        }

        std::size_t result = 0;
        while( !q.empty() ) {
            if ( result + q.top() < m ) {
                result += q.top();
            } else {
                q.pop();
            }
        }

        cout << result << endl;
    }
}

C++: #include <vector>
#include <algorithm>
#include <iostream>
#include <climits>
using namespace std;
typedef long long int int64;

vector<int64> P,Q;
int64 N,M,T;

int main(void)
{
	while(true)
	{
		N = 0;
		M = 0;
		P.clear();
		Q.clear();
		P.shrink_to_fit();
		Q.shrink_to_fit();
		cin >> N >> M;
		if(N == 0 && M == 0)
		{
			exit(0);
		}
		for(int i = 0;i < N;i++)
		{
			cin >> T;
			P.push_back(T);
		}
		P.push_back(0);
		for(auto itr = P.begin();itr < P.end();itr++)
		{
			for(auto itr2 = P.begin();itr2 < P.end();itr2++)
			{
				Q.push_back(*itr + *itr2);
			}
		}
		Q.push_back(LLONG_MAX / 2);
		Q.push_back(LLONG_MIN / 2);
		sort(Q.begin(),Q.end());
		int64 ms = 0;
		for(auto itr = Q.begin();itr < Q.end()+1;itr++)
		{
			ms = max(ms,*itr + *(lower_bound(Q.begin(),Q.end() - 1,M-*itr+1) - 1));
		}
		cout << ms << endl;
	}
}

C++: #include<cstdio>
#include<math.h>
#include<algorithm>
#include<string.h>

using namespace std;
const int INF =1001001001;
#define rep(i,n) for(int i=0;i<n;i++)
const int MAX_T = 1002*1002;
int M;



int main(){
	int N,M;
	int P[1002];
	scanf("%d %d",&N,&M);
	do{
		rep(i,N)scanf("%d",&P[i]);
		P[N]=0;//投げない場合
		//2回の合計の場合をだす
		int P2[MAX_T];
		int T=-1;
		rep(i,N+1)rep(j,N+1)P2[++T]=P[i]+P[j];
		sort(P2,P2+T);
		//二分探索
		int ans=0;
		rep(i,T){
			int q=M-P2[i];
			int a=0,b=T;
			if(q<0)continue;
			else{
				while(b-a>1){
				int c=(b+a+1)/2;
				if(P2[c]>q){b=c;}
				else{a=c;}
				}
				ans=max(P2[i]+P2[a],ans);					
			}
		}
		printf("%d\n",ans);
		scanf("%d %d",&N,&M);
	}while(N!=0||M!=0);
	return 0;
}

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

#define INF (2 << 28)
#define fr first
#define sc second
using namespace std;

typedef long long ll;
typedef pair<int, int> iP;

int main(){
  
  int n, m, p[1111];
  int sum[1111111];

  while(cin >> n >> m, n||m){
    int idx = 0, maxi = 0;
    for(int i = 0; i < n; i++) cin >> p[i]; 
    p[n] = 0;
    
    for(int i = 0; i < n + 1; i++)
      for(int j = 0; j < n + 1; j++)
        sum[idx++] = p[i] + p[j];
    
    for(int i = 0; i < idx; i++){
      for(int j = 0; j < idx; j++){
        if(sum[i] + sum[j] <= m) maxi = max(maxi, sum[i] + sum[j]);
      }
    }
    cout << maxi << endl;
  }
}

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

using namespace std;

int main() {
	int n, m;

	while( true ){

		cin >> n >> m;

		if( !n && !m ) {
			break;
		}

		vector < int > point(n);

		for(int i = 0; i < n; i++) {
			cin >> point[i];
		}

		vector < int > total;

		for(int i = 0; i < n; i++) {
			total.push_back(point[i]);
			for(int j = 0; j < n; j++) {
				total.push_back(point[i] + point[j]);
			}
		}
		sort(total.begin(), total.end());

		int tmp, M = 0;

		/*for(int i = 0; i < total.size(); i++) {
			cout << total[i] << " ";
		}*/

		for(int i = 0; i < total.size(); i++) {
			tmp = m - total[i];
			vector<int>::iterator it = upper_bound( total.begin(), total.end(), tmp);
			if(it == total.begin()) {
				continue;
			}
			//cout << "     " << it-total.begin() << "      " << endl;
			M = max(M, total[i] + *(it - 1));
			//if(it == total.end()) {
			//	continue;
			//}
			//int sum = total[i] + (*it);
			//cout << "     " << i << "      " << endl;
			//if(sum <= m && max < m) {
			//	max = sum;
			//}
		}

		cout << M << endl;

	}
}

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, l = 0, r = 0;
        while (r < N*N) {
            int cand = arr2[l] + arr2[r];
            if (cand <= M) {
                ans = max(ans, cand);
            }
            if (l == r || (r < N*N-1 && arr2[l] + arr2[r+1] <= M)) {
                ++r;
            } else {
                ++l;
            }
        }
        cout << ans << endl;
    }
    return 0;
}