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 <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m;
int p[1001];
int pp[1500000];
bool binary_search(int x) {
    int l=0, r=(n+1)*(n+1);
    while (r-l>=1) {
        int i=(l+r)/2;
        if (pp[i]==x) return true;
        else if (pp[i]<x) l=i+1;
        else r=i;
    }
    return false;
}
bool C(int x) {
    for (int c=0; c<=n; c++) {
        for (int d=0; d<=n; d++) {
            pp[c*(n+1)+d]=p[c]+p[d];
        }
    }
    sort(pp, pp+(n+1)*(n+1));
    for (int a=0; a<=n; a++) {
        for (int b=0; b<=n; b++) {
            if (binary_search(x-p[a]-p[b])) {
                return true;
            }
        }
    }
    return false;
}
int main() {
    while (scanf("%d%d",&n,&m)) {
        if (!n&&!m) break;
        memset(p, 0, sizeof(p));
        for (int i=0; i<n; i++) scanf("%d",&p[i]);
        sort(p, p+n+1);
        for (int i=m; i>=0; i--) {
            if (C(i)) {
                printf("%d\n",i);
                break;
            }
        }
    }
}

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(one[i]+one[j]) == S.end())S.insert(one[i]+one[j]),two[p++]=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);
      solve(two[i],m,two,p);
      solve(two[i],m,one,n);
    }
    printf("%d\n",maxv);
  }
  return false;
}

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){
      if ( a[mid]+now >maxv)maxv=a[mid]+now;
      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);
    }
    printf("%u\n",maxv);
  }
  return false;
}

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

#define MAX_N 1001

using namespace std;

int BinSearch(int v[], int vsize, int search){
	int l = 0;
	int r = vsize;
	int m = 0;
	while( r - 1 > l ){
		m = (r + l) / 2;

		if( v[m] > search ){
			r = m;
		}else if(v[m] == search){
			return m;
		}else{
			l = m;
		}
	}
	return m;
}

void Merge(int a[], int p ,int q, int r){
	int i, j;
	int n1 = q - p;
	int n2 = r - q;
	int *L = new int[n1];
	int *R = new int[n2];

	for(i = 0; i < n1; i++)
		L[i] = a[p + i];

	for(j = 0; j < n2; j++)
		R[j] = a[q + j];

	i = 0;
	j = 0;

	for(int k = p; k < r; k++){
		if( i == n1 ){
			while( j < n2 ){
				a[k] = R[j];k++;j++;
			}
			break;
		}else if( j == n2 ){
			while( i < n1 ){
				a[k] = L[i];k++;i++;
			}
			break;
		}else{
			if( L[i] <= R[j] ){
				a[k] = L[i];
				i++;
			}else{
				a[k] = R[j];
				j++;
			}
		}
	}

	delete[] L;
	delete[] R;
}

void BubbleSort(int *a, int n){
	for(int i = 0; i < n; i++)
		for(int j = n - 1; j > i; j--)
			if( a[j] <= a[j - 1] )
				swap(a[j], a[j - 1]);
}

void MergeSort(int a[], int p, int r){
	if( p < r ){
		if( r - p < 9 ){
			BubbleSort(a + p, r - p);
			return ;
		}
		int q = (p + r) / 2;
		MergeSort(a, p, q);
		MergeSort(a, q, r);
		Merge(a, p, q, r);
	}
}

int main(void){
	while( true ){
		int index = 0;
		int Max = 0;
		int N, M;
		int *Q;
		int V[MAX_N];

		cin >> N >> M;
		
		if( N == 0 && M == 0 ){
			break;
		}

		for(int i = 0; i < N; i++){
			cin >> V[i];
		}
		V[N] = 0;
		N++;

		Q = new int[N*N];

		for(int i = 0; i < N; i++){
			for(int j = 0; j < N; j++){
				Q[i * N + j] = V[i] + V[j];
			}
		}
		//cout << "Sorting..." << endl;
		/*for(int i = 0; i < N * N; i++){
			cout << Q[i] << '\n';
		}*/
		
		MergeSort(Q, 0, N * N);
		//stable_sort(Q.begin(), Q.end());

		//cout << "Sorted:" << endl;
		/*for(int i = 0; i < N * N; i++){
			cout << Q[i] << '\n';
		}*/

		//cout << "Uniqing..." << endl;
		//Uniq( Q );

		for(int i = 0; i < N * N; i++){
			//cout << Q[i];
			int optim = BinSearch(Q, N*N, M - Q[i]);
			//cout << ' ' << optim << ":" << Q[optim] << '\n';
			if( optim > 0 && Q[i] + Q[optim] > M) optim--;
			Max = max( Max , Q[i] + Q[optim] > M ? 0 : Q[i] + Q[optim]);
		}

		delete[] Q;
		cout << Max << '\n';
	}
	return 0;
}

C++: #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef vector<int>V;
void I(V&v)
{
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
}
int main()
{
	int n,m,i,j,r;
	V v,w;
	v.reserve(1001);
	w.reserve(501501);
	while(scanf("%d%d",&n,&m),n)
	{
		v.clear();
		w.clear();
		for(i=0;i<n;++i)
		{
			scanf("%d",&r);
			v.push_back(r);
		}
		v.push_back(0);
		I(v);
		for(r=i=0;i<v.size();++i)for(j=i;j<v.size();++j)w.push_back(v[i]+v[j]);
		I(w);
		for(i=j=upper_bound(w.begin(),w.end(),m/2)-w.begin()-1;0<=i&&j<w.size();)
		{
			if(w[i]+w[j]>m)--i;
			else r=max(r,w[i]+w[j]),++j;
		}
		printf("%d\n",r);
	}
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
int a[1001],b[510001],*p;main(){
	int n,m,i,j,k,r;
	for(;scanf("%d%d",&n,&m)>1&&n;printf("%d\n",r)){
		for(i=1;i<=n;i++)scanf("%d",a+i);
		for(k=i=0;i<=n;i++)for(j=i;j<=n;j++)b[k++]=a[i]+a[j];
		std::sort(b,b+k);
		for(r=i=0;i<k;i++){
			p=std::upper_bound(b,b+k,m-b[i]);
			if(p>b&&r<b[i]+*(p-1))r=b[i]+*(p-1);
		}
	}
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(){
	int N,M,G,count=0,MAX=-1234567890;
	vector <int> ver;
	cin>>N>>M;
	int data[N]={0};
	for (int i=1;i<=N;i++) cin>>data[i];
	for (int i=0;i<=N;i++){
		for (int j=0;j<=N;j++){
			ver.push_back(data[i]+data[j]);
			count++;
		}
	}
	sort(ver.begin(),ver.end());
	int t=count;
	int n=count;
	for (int i=0;i<n+1;i++){
		while(ver[i]+ver[t]>M) t--;
		if (t<0) break;
		MAX=max(MAX,ver[i]+ver[t]);
	}
	cout<<MAX<<endl;
	return 0;
}