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+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++: /**
 * File    : JOI_2007_darts.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-3-8 20:45:20
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, M;
int P[1010];
set<int> S;

int main()
{
  while (cin >> N >> M && N && M)
  {
    S.clear();
    for (auto i = 0; i < N; i++)
    {
      cin >> P[i];
    }
    P[N] = 0;
    N++;
    for (auto i = 0; i < N; i++)
    {
      for (auto j = i; j < N; j++)
      {
        S.insert(P[i] + P[j]);
      }
    }
    S.insert(M + 1);
    int ans = 0;
    for (auto i = 0; i < N; i++)
    {
      for (auto j = i; j < N; j++)
      {
        int sum = P[i] + P[j];
        if (sum <= M)
        {
          auto t = S.upper_bound(M - sum);
          t--;
          ans = max(ans, sum + *t);
        }
      }
    }
    cout << ans << endl;
  }
}

C++: #include <bits/stdc++.h>
using namespace std;

int main(void)
{
    long long n, m;

    while (scanf("%lld %lld", &n, &m), n){
        long long p[1024];

        for (int i = 0; i < n; i++) scanf("%lld", p + i);
        p[n++] = 0;

        vector<long long> score;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                if (!binary_search(score.begin(), score.end(), p[i] + p[j])) score.push_back(p[i] + p[j]);
            }
        }
        sort(score.begin(), score.end());
        score.erase(unique(score.begin(), score.end()), score.end());

        long long maxi = 0;
        for (auto i : score){
            if (i > m) continue;
            maxi = max(maxi, min(*(upper_bound(score.begin(), score.end(), m - i) - 1) + i, m));
        }

        printf("%lld\n", maxi);
    }

    return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
vector<long int> po;
vector <pair <int ,long int> > sss;
long int n,a,low,m,lastans,memo[1005];
void solve(int dp,long int sum);

int main(){
    while(1){
        lastans=0;
        po.clear();
        //for(int i=0;i<1005;i++)memo[i]=0;

        cin >> n >> m;
        if(n==0&&m==0)break;
        for(int i=0;i<n;i++){
            cin >> a;
            po.push_back(a);
           // low=min(low,a);
        }
        sort(po.begin(),po.end());
        //cout << po[0] << endl;
        //solve(0,0);
        //lastans=po[n-1];

        for(int i=4;i>0;i--){
            for(int j=n-1;j>=0;j--){
                if(m>=i*po[j]){
                    lastans=max(i*po[j],lastans);

                    for(int k=4-i;i>0;i--){
                        for(int s=0;s<n;s++){
                            if(m>=i*po[j]+po[s]){
                                lastans=max(i*po[j]+po[s],lastans);

                                for(int t=4-k;t>0;t--){
                                    for(int u=0;u<n;u++){
                                        if(m>=i*po[j]+po[s]+po[u]){
                                         lastans=max(i*po[j]+po[s]+po[u],lastans);

                                         for(int v=4-t;v>0;v--){
                                            for(int w=u-1;w>=0;w--){
                                                if(m>=i*po[j]+po[s]+po[u]+po[w]){
                                                    lastans=max(lastans,i*po[j]+po[s]+po[u]+po[w]);

                                                }else break;
                                            }
                                         }

                                        }else break;
                                    }
                                }

                            }else break;

                        }
                    }

                    lastans=max(lastans,po[j]*i);
                }else break;
            }
        }



        cout << lastans << endl;
        //cout <<"ss=" << ss << endl;
    }

    return 0;
}

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,m,p[1001],q[1002001],t,k,ans;
int main(){
	while(cin>>n>>m,n){
		rep(i,n)cin>>t,p[i+1]=-t; ans=0,k=(n+1)*(n+1);
		rep(i,n+1)rep(j,n+1)q[i*n+j]=p[i]+p[j]; sort(q,q+k);
		rep(i,k)if(q[i]>=-m){
			int *j=lower_bound(q,q+k,-m-q[i]);
			if(ans>q[i]+*j)ans=q[i]+*j;
		}
		cout<<-ans<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <map>
#include <set>
#include <stack>
#include <queue>
 
using namespace std;
 
#define pb(n)	push_back(n)
#define mp(n,m) make_pair(n,m)
#define fi 	first
#define se 	second
#define all(r) (r).begin(),(r).end()
 
#define REP(i,s,e)	for(int i=(s); i<(e); i++)
#define rep(i,n)	REP(i,0,n)
#define REPE(i,s,e)	for(int i=s; i>e; i--)
#define repe(i,n)	REPE(i,n,-1)


typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
 
typedef vector<vi> vvi;
 
const int IMAX=((1<<30)-1)*2+1;
const int INF=100000000;
const double EPS=1e-10;
//int mod=1000000007



const int MAX_N = 1000;
const int MAX_W = 200000000;

int dp[MAX_N + 1][MAX_W + 1][5];
int v[MAX_N], w[MAX_N];
int N,W;


int solve() {
	for(int i = 0; i < N; i++) {
		for(int j = 0; j <= W; j++){
			for(int k = 0; k < 5; k++){
				if(j < w[i] || k <1) {
					dp[i + 1][j][k] = dp[i][j][k];
				}
				else{
					dp[i + 1][j][k] = max(max(dp[i][j][k],dp[i][j-w[i]][k-1] + v[i]), dp[i + 1][j - w[i]][k-1] + v[i]);
				}
			}
		}
	}
	return dp[N][W][4];
}

int main(){
	int n, m;
	while(cin>>n>>m){
		N = n;
		W = m;
		for(int i = 0; i < n; i++){
			cin >> v[i];
			w[i] = v[i];
		}
		cout<<solve()<<endl;
	}
}