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 _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

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

#define MAX_N 1001

using namespace std;

int main(void){
	while( 1 ){
		int n, m;
		int V[MAX_N] = {0,};
		int D[MAX_N][4] = {{0,},};
		int Max = 0;

		cin >> n >> m;

		if( n == 0 && m == 0 ){
			break;
		}

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

		sort(V, V + n);
		reverse(V, V + n);

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				if( j == 0 ){
					D[i][j] = V[i] > m ? -1 : V[i];
				}else{
					int thisMax = 0;

					if( D[i][j - 1] < 0 ){
						D[i][j] = -1;
						continue;
					}
					
					for(int k = 0; k <= i; k++){
						int tmp = V[i] + D[k][j - 1];
						if( D[k][j - 1] < 0 ){
							continue;
						}
						if( tmp > m ){
							continue;
						}
						thisMax = max(thisMax, tmp);
					}
					
					if( thisMax > V[i] ){
						D[i][j] = thisMax > m ? -1 : thisMax;
					}
				}
			}
		}

		for(int i = 0; i < n; i++){
			for(int j = 0; j < 4; j++){
				//cout << D[i][j] << ' ';
				if( D[i][j] <= m ){
					if( Max < D[i][j] ){
						Max = D[i][j];
					}
				}
			}
			//cout << '\n';
		}

		cout << Max << '\n';
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#include <set>
#define N_MAX 1001
using namespace std;

int N, M;
int P[N_MAX];

int solve() {
  int ans = -1;
  for(int i = 0; i <= N; i++) {
    if(P[i] > M) break;
    for(int j = i; j <= N; j++) {
      if(P[i] + P[j] > M) break;
      for(int k = j; k <= N; k++) {
	if(P[i] + P[j] + P[k] > M) break;
	for(int l = k; l <= N; l++) {
	  int tmp = P[i] + P[j] + P[k] + P[l];
	  if(tmp > M) break;
	  ans = max(ans, tmp);
	}
      }
    }
  }
  return ans;
}

int main() {
  while((cin >> N >> M) && N && M) {
    P[0] = 0;
    for(int i = 1; i <= N; i++) {
      cin >> P[i];
    }
    sort(P, P+N+1);
    cout << solve() << endl;
  }
  return 0;
}

C++: #include<iostream>
#include<set>
#include<vector>
using namespace std;
typedef unsigned int uint;
uint maxv;
void solve(uint now,uint m,uint *a,int n){
  int r=n-1,l=0,mid;
  while(l <=r){
    mid = (l+r)/2;
    if ( a[mid]+now>m)r=mid-1;
    else if ( a[mid]+now <m)l=mid+1;
    else break;

  }
  if ( now+a[mid]>maxv&& now+a[mid]<m)maxv=now+a[mid];
}


main(){
  int n;
  uint m;
  while(scanf("%d%d",&n,&m) && n){
    set<uint> S;    
    uint one[n];
    uint two[n*n];
    int p=0;
    for(int i=0;i<n;i++)scanf("%d",&one[i]);
    for(int i=0;i<n;i++){
      for(int j=i;j<n;j++){
	if ( S.find(i+j) == S.end())S.insert(one[i]+one[j]),two[p++]=one[i]+one[j];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    maxv=0;
    for(int i=0;i<p;i++){
      if ( two[i]+one[0]>m)break;
      if ( two[i]+two[0]<=m)solve(two[i],m,two,p);
      if ( two[i]+one[0]<=m)solve(two[i],m,one,n);
    }
    printf("%d\n",maxv);
  }
  return false;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <functional>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <deque>
using namespace std;
#define INF 10000000
#define LLINF 100000000000000
typedef pair<int, int> P;
typedef long long ll;
#define pb push_back
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define VSORT(v) sort(v.begin(), v.end());
#define fi first
#define se second
#define out(x) cout << x << endl;
int dx[] = { 1, 0, -1, 0 }, dy[] = { 0,1,0,-1 };
ll MOD = 1000000007;
ll ha[1000005] = { 0 };

int main() {
	while (true) {
		ll n, m;
		ll p[1005] = { 0 };
		ll res = 0;
		int cnt = 0;
		cin >> n >> m;
		if (n == 0 && m == 0) return 0;
		for (ll i = 1; i <= n; i++) cin >> p[i];
		for (ll i = 0; i <= n; i++) {
			for (ll j = i; j <= n; j++) {
				ha[cnt++] = p[i] + p[j];
			}
		}
		sort(ha, ha + cnt);
		for (int i = 0; i < cnt; i++) {
			ll sum = ha[i];
			int a = upper_bound(ha, ha + cnt, m - sum) - ha;
			//out(m-sum);
			if (a >= 1) if (sum + ha[a - 1] <= m) res = max(res, sum + ha[a - 1]);
		}
		out(res);
	}
	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());
		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;
}