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<vector>
#include<algorithm>
using namespace std;
int main(){
    int n,m;
    while(cin>>n>>m,n||m){
        vector<int>pnt(n+1);
        for(int i=0;i<n;i++)cin>>pnt[i];
        pnt[n]=0;
        vector<int>latte;
        for(int i=0;i<n+1;i++)
            for(int j=i;j<n+1;j++)
                latte.push_back(pnt[i]+pnt[j]);

        sort(latte.begin(),latte.end());
        int Max=0;
        for(int i=1;i<latte.size()&&latte[i]<=m;i++){
            int s=*(upper_bound(latte.begin(),latte.end(),m-latte[i])-1)+latte[i];
            Max=max(Max,s);
            //cout<<latte[i]<<" "<<s-latte[i]<<" "<<s<<endl;
        }
        cout<<Max<<endl;

    }
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> a;
vector <int> all;
int n,m;


int main() {

  while(1) {
    cin >> n >> m;
    if(n == 0 && m ==0) break;
    a.resize(n);
    for(int i=0;i<n;i++) cin >>a[i];

    a.push_back(0);
    all.clear();
    for(int i=0;i<a.size();i++) 
      for(int j=i;j<a.size();j++)
	all.push_back(a[i]+a[j]);

    sort(all.begin(),all.end());

    int ans = 0;
    int allsize = all.size();
    int b = 0;

    for(int i=allsize-1;i>= 0;i--) {
      for(int j=b;j<allsize;j++) {
	int sum = all[i] + all[j];
	if(sum > m) break;
	b++;
	ans = max(ans,sum);
      }
      if(ans == m) break;
    }


    cout << ans <<endl;
  }
  return 0;
  
}

C++: #include <cstdio>
#include <cctype>
#include <utility>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

const auto gcu = getchar_unlocked;
const auto pcu = putchar_unlocked;
#define _T template <typename T>
#define _HT template <typename H, typename... T>
#define _il inline
#define _sc _il bool scan
_T T in(int c){T n=0;int m=1;while(isspace(c)){c=gcu();}if(c=='-')m=-1,c=gcu();
	do{n=10*n+(c-'0'),c=gcu();}while(c>='0'&&c<='9');return m*n;}
_il int in() {return in<int>(gcu());}
_T T scan(T &n){int c=gcu();return c==EOF?false:(n=in<T>(c),true);}
_sc(char &c){c=gcu();gcu();return c!=EOF;}
#ifdef _GLIBCXX_STRING
_sc(string &s){int c;s="";
	for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=c;}}
#endif
_HT _sc(H &h, T&&... t){return scan(h)&&scan(t...);}
#define _ot _il void out
#define _ol _il void outl
_ot(bool b) {pcu('0'+b);}
_ot(const char *s){while(*s)pcu(*s++);}
_ot(char c){pcu(c);}
#ifdef _GLIBCXX_STRING
_ot(string s){for(char c:s)pcu(c);}
#endif
_T _ot(T n){static char b[20];char *p=b,m=n<0?pcu('-'),-1:1;
	if(!n)*p++='0';else while(n)*p++=n%10*m+'0',n/=10;while(p!=b)pcu(*--p);}
_ol(){out('\n');}
#ifdef _GLIBCXX_VECTOR
_T _ot(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);outl();}
#endif
_HT _ot(H&& h, T&&... t){out(h);out(move(t)...);}
template <typename... T> _ol(T&&... t){out(move(t)...);outl();}

int main() {
	for (int N, M; N = in(), M = in();) {
		vector<int> t(N), u;
		for (int &p: t)
			p = in();
		t.push_back(0);
		sort(t.rbegin(), t.rend());
		for (auto i = t.begin(); i != t.end(); i++)
			for (auto j = i; j != t.end(); j++)
				if (*i + *j <= M)
					u.push_back(*i + *j);
		sort(u.rbegin(), u.rend());
		u.erase(unique(u.begin(), u.end()), u.end());
		int r = 0;
		for (auto i = u.begin(), e = u.end(); i != e; i++) {
			e = lower_bound(i + 1, e, M - *i, greater<int>());
			r = max(r, *i + *e);
		}
		outl(r);
	}
}

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

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define INF 1 << 30
#define EPS 1e-10

typedef pair<int, int> pi;
typedef pair<int, pi> pii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;

int N, M, P[1001];

int main(){
  while(scanf("%d%d", &N, &M) && N+M){
    rep(i, N)  scanf("%d", P+i);
    P[N] = 0;
    vi p;
    rep(i, N+1) rep(j, N+1) if(P[i] + P[j] <= M) p.PB(P[i]+P[j]);
    sort(p.begin(), p.end());

    int res = 0;
    rep(i, p.size()){
      int d = M - p[i];
      int l = p[0], h = p[p.size()-1];
      int m;
      while(h - l > 1){
	m = (l+h)/2;
	if(p[m] < d) l = m;
	else if(p[m] > d) h = m;
	else break;
      }
      if(p[m] > d) m--;
      //      printf("%d %d\n", p[m], p[i]);
      res = max(res, p[m] + p[i]);
    }
    printf("%d\n", res);
  }
  return 0;
}

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

#define MAX_N 1001

using namespace std;

void rawcomb(vector<int> &v, int n, int rest, int nowsum, int targetSum, int *result){
	if( rest == 0 ){
		if( nowsum <= targetSum ){
			*result = max( *result, nowsum );
		}
		return ;
	}
	for(int i = 0; i < n; i++){
		nowsum += v[i];
		rawcomb(v, n, rest - 1, nowsum, targetSum, result);
		nowsum -= v[i];
	}
}

int main(void){
	while( 1 ){
		int n, m;
		vector<int> v(MAX_N,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 + 1] = 0;

		sort(v.begin(), v.begin() + n + 1);
		reverse(v.begin(), v.begin() + n + 1);

		rawcomb(v, n + 1, 4, 0, m, &Max);

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

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

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)

int main(){
    int N, M;
    while(std::cin >> N >> M, N){
        int parts[1010];
        REP(i, N){
            std::cin >> parts[i];
        }
        parts[N] = 0;

        std::vector<int> half;
        REP(i, N+1){
            REP(j, N+1){
                if(parts[i] + parts[j] <= M){
                    half.push_back(parts[i] + parts[j]);
                }
            }
        }

        int res = 0;

        std::sort(half.begin(), half.end());
        REP(i, half.size()){
            int v = half[i],
                index = std::lower_bound(half.begin(), half.end(), M-v) - half.begin();
            if(half[index] + v == M){
                res = M;
            }else if(index - 1 >= 0){
                res = std::max(res, v + half[index-1]);
            }
        }

        std::cout << res << std::endl;
    }
}