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 <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <stack>
#include <list>
using namespace std;
#define INF 100000000
typedef long long int lli;
typedef pair<int,int> P;

int p[1001];
int h[1000*1000+1001];

int main(){
	int n,m,ans;
	while(cin>>n>>m){
		if(n==0&&m==0) break;
		p[0]=0;
		ans=0;
		for(int i=1; i<=n; ++i){
			cin >> p[i];
		}
		for(int i=0; i<=n; ++i){	
			for(int j=0; j<=n; ++j){
				h[i*n+j]=p[i]+p[j];
			}
		}
		sort(h,h+n*n+1);
		/*
		for(int i=0; i<=n*n; ++i){
			cout << h[i] << "\n";
		}
		*/
		for(int i=0; i<=n; ++i){	
			for(int j=0; j<=n; ++j){	
				int tmp=p[i]+p[j];
				int l=0,r=n*n;
				int cnt=0;
				while(1){
					int mid=(r+l)/2;
					if(cnt>=30){
						if(h[mid]+tmp<=m) ans=max(ans,h[mid]+tmp);
						break;
					}
					if(h[mid]+tmp>m){
						r=mid;
					} else if(h[mid]+tmp<m){
						l=mid;
					} else if(h[mid]+tmp==m){
						ans=m;
						break;
					}
					++cnt;
				}
			}
		}
		cout << ans << "\n";
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
#define INF 200000000
using namespace std;


int point2[1000000];

int search(int a[], int n, int key) {
	int left = 0;
	int right = n;
	int mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (a[mid] == key) return a[mid];
		else if (a[mid] < key) left = mid + 1;
		else right = mid;
	}
	return a[left-1];
}

int main() {
	while (true) {
		int n, m;
		cin >> n >> m;
		if (n == 0 && m == 0) return 0;
		int point[n+1];
		for (int i = 0; i < n; i++) cin >> point[i];
		point[n] = 0;
		int k = 0;
		for (int i = 0; i < n + 1; i++) {
			for (int j = i; j < n + 1; j++) {
				point2[k] = point[i] + point[j];
				k++;	
			}
		}
		int np = k;
		sort(point2, point2 + np);

		int ans = 0;
		for (int i = 0; i < np; i++) {
			if (point2[i] > m) break;
			int s = search(point2, np, m - point2[i]);
			int t = s + point2[i];
			if (t > ans) ans = t;
		}
		cout << ans << endl;
	}
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(ll i=0;i<n;i++)
using namespace std;
typedef long long ll;

ll k[1000010];
ll p[1010];
int main() {
	ll n, m;
	while (scanf("%lld%lld", &n, &m), n) {
		memset(p, 0, sizeof(p));
		rep(i, n)scanf("%lld", &p[i]);
		ll c = 0;
		rep(i, n + 1)for (ll j = i; j < n + 1; j++) {
			k[c++] = p[i] + p[j];
		}
		sort(k, k + c);
		ll Max = 0;
		rep(i, n + 1)for (ll j = i; j < n + 1; j++) {
			ll*a = upper_bound(k, k + c, m - p[i] - p[j]);
			if (a == k)continue;
			Max = max(Max, *(a - 1) + p[i] + p[j]);
		}
		printf("%lld\n", Max);
	}
}

C++: #include<iostream>
#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%u",&n,&m) && n){
    uint one[n];
    uint two[n*n];
    int p=0;
    maxv=0;
    for(int i=0;i<n;i++)scanf("%u",&one[i]);
    for(int i=0;i<n;i++){
      if ( one[i]>maxv &&one[i] <=m)maxv=one[i];
      for(int j=i;j<n;j++){
	if ( one[i]+one[j]>m)continue;
	two[p++]=one[i]+one[j];
	if (two[p-1]>maxv)maxv=two[p-1];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    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);
    }
    if ( maxv>m)return true;
    printf("%u\n",maxv);
  }
  return false;
}

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

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() {return val;}
    bool operator!=(Iterator& itr) {return val < itr.val;}
    void operator++() {++val;}
  };
  Iterator i, n;
public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator& begin() {return i;}
  Iterator& end() {return n;}
};

template<class T> inline T at(const vector<T> &v, int i) {return v[(i % (int)v.size() + v.size()) % v.size()];}

template<class T> inline bool is_max(T &a, const T &b) {return a < b ? a = b, true : false;}
template<class T> inline bool is_min(T &a, const T &b) {return a > b ? a = b, true : false;}

int main() {
  while (true) {
    int n, m;
    cin >> n >> m;
    if (n == 0 && m == 0) break;
    vector<int> p;
    for (int _ : range(n)) {
      int x;
      cin >> x;
      p.emplace_back(x);
    }
    p.emplace_back(0);
    set<int> s;
    for (int i : p) for (int j : p) s.insert(i + j);
    int res = 0;
    for (int i : s) {
      auto k = s.upper_bound(m - i);
      if (k == s.begin()) continue;
      --k;
      is_max(res, i + *k);
    }
    cout << res << endl;
  }
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;

#define MAX_N 1000

int main(){
	int N, M, P[MAX_N + 1];
	int table[(MAX_N + 1) * (MAX_N + 1)];
	int size;
	int ub, lb, mid;
	int res;
	
	while(true){
		scanf("%d%d", &N, &M);
		if(N == 0 && M == 0) break;
		for(int i = 1; i <= N; i++){
			scanf("%d", &P[i]);
		}
		P[0] = 0;
		
		for(int i = 0; i <= N; i++){
			for(int j = 0; j <= N; j++){
				table[(i * (N + 1)) + j] = P[i] + P[j];
			}
		}
		size = (N + 1) * (N + 1);
		sort(table, table + size);
		
		res = 0;
		for(int i = 0; i < size; i++){
			if(table[i] > M) continue;
			ub = size; lb = 0;
			while(ub - lb > 1){
				mid = (ub + lb) / 2;
				if(table[i] + table[mid] <= M){
					lb = mid;
				}
				else{
					ub = mid;
				}
			}
			if(res < table[i] + table[lb]){
				res = table[i] + table[lb];
			}
		}
		
		printf("%d\n", res);
	}
	
	return 0;
}