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 <algorithm>
#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MOD 1000000007
#define REP(i, N) for (int i = 0; i < N; ++i)
#define REP1(i, N) for (int i = 1; i <= N; ++i)
#define RREP(i, N) for (int i = N - 1; i >= 0; --i)
#define ALL(a) a.begin(), a.end()

int main() {
  int n;
  ll m;
  while (cin >> n >> m && n && m) {
    vector<ll> a, b, c, d;
    a.push_back(0);
    b.push_back(0);
    c.push_back(0);
    d.push_back(0);
    REP(i, n) {
      ll p;
      cin >> p;
      a.push_back(p);
      b.push_back(p);
      c.push_back(p);
      d.push_back(p);
    }
    a.push_back(1e9);
    b.push_back(1e9);
    c.push_back(1e9);
    d.push_back(1e9);
    vector<ll> ab;
    REP(i, a.size()) REP(j, b.size()) ab.push_back(a[i] + b[j]);
    sort(ALL(ab));
    ll ans = -1e18;
    REP(i, c.size()) REP(j, d.size()) {
      ll k = m - (c[i] + d[j]);
      if (k < 0) continue;
      int ok = 0, ng = ab.size() - 1;
      while (1 < abs(ok - ng)) {
        int mid = (ok + ng) / 2;
        if (ab[mid] <= k)
          ok = mid;
        else
          ng = mid;
      }
      ans = max(ans, c[i] + d[j] + ab[ok]);
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include <cstdio>
#include <algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n, m, c[1009], s[510009], t[510009], cnt[1027], sum[1027];
int main() {
	while (scanf("%d%d", &n, &m), n) {
		for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
		sort(c, c + n);
		int b = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = i; j <= n && c[i] + c[j] <= m; j++) {
				s[b++] = c[i] + c[j];
			}
		}
		for (int i = 0; i < 30; i += 10) {
			fill(cnt, cnt + 1024, 0); sum[0] = 0;
			for (int j = 0; j < b; j++) cnt[(s[j] >> i) & 1023]++;
			for (int j = 0; j < 1024; j++) sum[j + 1] = sum[j] + cnt[j];
			for (int j = 0; j < b; j++) t[sum[(s[j] >> i) & 1023]++] = s[j];
			for (int j = 0; j < b; j++) s[j] = t[j];
		}
		int r = b - 1, ret = 0;
		for (int i = 0; i < b && i <= r; i++) {
			while (r > 0 && s[i] + s[r] > m) r--;
			ret = max(ret, s[i] + s[r]);
		}
		printf("%d\n", ret);
	}
	return 0;
}

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

#define MAX_N (1000)
#define MAX_M (2 * 1e8)

using namespace std;

int field[MAX_N + 1];
int fld[(MAX_N + 1) * (MAX_N + 1)];

int N,M;

int ans;

int bin_search(int tar,int *s,int *e){
	int result;
	int width = e - s;
	while(true){
		width = e - s;
		if(width <= 1){
			result = *s;
			break;
		}

		if(*(s + (width / 2)) <= tar){
			s = s + (width / 2);
		}
		else{
			e = s + (width / 2);
		}
	}
	
	return result;
}

void solve(){
	for(int i = 0;i <= N;i++){
		for(int j = 0;j <= N;j++){
			fld[(N + 1) * i + j] = field[i] + field[j];
		}
	}

	sort(fld,fld + (N + 1) * (N + 1));

	int rest;
	int sample;
	for(int i = 0;i <= N;i++){
		for(int j = 0;j <= N;j++){
			rest = M - (field[i] + field[j]);
			if(rest < 0) break;
			sample = bin_search(rest,fld,fld + (N + 1) * (N + 1));
			ans = max(ans,field[i] + field[j] + sample);
		}
	}

	return ;
}

int main(){

	while(true){
		scanf("%d%d",&N,&M);
		if(N == 0 && M == 0) break;
		for(int i = 1;i <= N;i++){	//fiest element is 0;
			scanf("%d",field + i);
		}

		solve();

		printf("%d\n",ans);

	}

	return 0;
}

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

using namespace std;

int main() {
	int n;
	long long int m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) {
			break;
		}
		long long int b;
		vector<long long int> ss;
		ss.push_back(0);
		for (int i = 0; i < n; i++) {
			cin >> b;
			if (b <= m) {
				ss.push_back(b);
			}
		}
		vector<long long int> ss2;
		for (long long int i = 0; i < ss.size(); i++) {
			ss2.push_back(ss[i]);
			for (long long int j = i; j < ss.size(); j++) {
				if (ss[i]+ss[j] <= m) {
					ss2.push_back(ss[i]+ss[j]);
				}
			}
		}
		sort(ss2.begin(), ss2.end());
		/*for (long long int i = 0; i < ss2.size(); i++) {
			cout << ss2[i] << endl;
		}*/
		long long int MAX = 0;
		long long int sz = ss2.size();
		for (long long int j = 0; j < sz; j++) {
			long long int a = m;
			for (long long int i = 0; i < 2; i++) {
				vector<long long int>::iterator ite = upper_bound(ss2.begin(), ss2.end(), a);
				if (ite != ss.begin()) {
					ite--;
					a -= *(ite);
				}
			}
			vector<long long int>::iterator ite2 = ss2.end();
			ss2.erase(ite2-1);
			MAX = max(MAX, m-a);
		}
		cout << MAX << endl;
	}
	return 0;
}

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

using namespace std;

int n , m;
vector<int> point, points;

int main()
{
	int c;
	while(cin >> n >> m){
		if(n == 0, m == 0) break;
		point.push_back(0);

		for(int i = 0; i < n; i++)
		{
			cin >> c;
			point.push_back(c);
		}

		n++;

		for(int i = 0; i < n; i++)
		{
			for(int j = i; j < n; j++)
			{
				points.push_back(point[i]+point[j]);
			}
		}
		int ans = 0, left, right, mid;

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

		for(int i = 0; i < points.size(); i++)
		{
			left = 0;
			right = points.size();

			int temp = m - points[i];

			if(temp < 0) continue;

			while(right - left > 1)
			{
				mid = (right + left) / 2;
				if(temp < points[mid]) right = mid;
				else if(temp > points[mid]) left = mid;
				else if(temp == points[mid]) break;
			}
			ans = max(ans, points[i] + points[left]);
		}
		cout << ans << endl;
		point.clear();
		points.clear();
	}
}

C++: #include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

set<long long> sep;
long long ary[1010];
int main(){
	int N;
	long long M,res;
	set<long long>::iterator it,it2;
	while(1){
		sep.clear();
		cin>>N>>M;
		if(N==0&&M==0) break;
		for(int i=0;i<N;i++){
			cin>>ary[i];
		}
		ary[N]=0;
		for(int i=0;i<=N;i++){
			for(int j=i;j<=N;j++){
				if(ary[i]+ary[j]<=M){
					sep.insert(ary[i]+ary[j]);
				}
			}
		}
		res=0;
		it2=sep.end();
		it2--;
		for(it=sep.begin();it!=sep.end();it++){
			while((*it)+(*it2)>M)it2--;
			if((*it)>(*it2)) break;
			res=max(res,(*it)+(*it2));
		}
		cout<<res<<endl;

	}
	return 0;
}

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

int main(){
	cin.tie(0),ios::sync_with_stdio(false);
	while(true){
		int n,m; cin>>n>>m;
		if(n==0&&m==0)break;
		vector<int>p(n); for(auto&&i:p)cin>>i; p.emplace_back(0);
		vector<int>b;
		for(int i=0;i<=n;++i){
			for(int j=i;j<=n;++j){
				b.emplace_back(1L*p.at(i)+p.at(j));
			}
		}
		sort(b.begin(),b.end());
		int ans=0;
		for(int i=0;i<n;++i){
			for(int j=i;j<n;++j){
				int L=0,R=b.size(),score=p.at(i)+p.at(j),mx=m-score;
				if(mx<0)continue;
				while(R-L>1){
					int mid=(L+R)/2;
					if(b.at(mid)>mx)R=mid;
					else L=mid;
				}
				score+=b.at(L);
				if(score<=m)ans=max(ans,score);
			}
		}
		cout<<ans<<"\n"s;
	}
}