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 <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;
}

C++: #include <cstdio>
#include <cctype>
#include <utility>
#include <vector>
#include <algorithm>
#include <array>
#include <numeric>
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();}

void radix_sort(vector<int>::iterator b,vector<int>::iterator e) {
    vector<int> t(e - b);
    array<int, 256> c, s;
    for (int i = 0; i < 32; i += 8) {
        fill(c.begin(), c.end(), 0);
        for_each(b, e, [&](int j) {c[(j >> i) & 255]++;});
        s[0] = 0;
        partial_sum(c.begin(), c.end() - 1, s.begin() + 1);
        for_each(b, e, [&](int j) {t[s[(j >> i) & 255]++] = j;});
        copy(t.begin(), t.end(), b);
    }
}

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.begin(), t.end());
		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);
		radix_sort(u.begin(), u.end());
		int r = 0;
		for (auto i = u.begin(), e = u.end() - 1; i <= e; i++) {
			for (; *i + *e >= M; e--)
				;
			r = max(r, *i + *e);
		}
		outl(r);
	}
}

C++: #include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long lint;

int main()
{
	lint n, m;
	lint score[1024];
	static lint pSum[512 * 1023];
	
	while (scanf("%lld %lld", &n, &m) && n){
		
		for (int i = 0; i < n; i++){
			scanf("%lld", score + i);
		}
		score[n++] = 0;
		
		int k = 0;
		for (int i = 0; i < n; i++){
			for (int j = i; j < n; j++){
				pSum[k++] = score[i] + score[j];
			}
		}
		
		sort(pSum, pSum + k);
		
		lint res = 0;
		for (int i = 0; i < k; i++){
			if (pSum[i] > m) break;
			res = max(res, pSum[i] + *(upper_bound(pSum, pSum + k, m - pSum[i]) - 1));
		}
		
		printf("%lld\n", res);
	}
	return (0);
}