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<algorithm>
using namespace std;
int f[210000000];
int main(void)
{
	int a,s,d[1000],high,low,ba,naka,nokori,kore,g,h,i,j,z,x,c,v;
	while(1){
		scanf("%d %d",&a,&s);
		if(a==0&&s==0)
			break;
		d[0]=0;
		for(i=1;i<=a;i++){
			scanf("%d",&d[i]);
		}
		g=0;
		for(i=0;i<=a;i++){
			for(j=i;j<=a;j++){
				f[g]=d[i]+d[j];
				g++;
			}
		}
		sort(f,f+g);
		/*for(i=0;i<g;i++)
			printf("%d\n",f[i]);*/
		kore=0;
		for(i=0;i<g;i++){
			v=0;
			low=0;
			high=g-1;
			nokori=s-f[i];
		//	printf("%d %d\n",i,nokori);
			if(nokori>=0){
				while(1){
					if(low>high)
						break;
					naka=(low+high)/2;
				//	printf("%d = %d %d %d %d %d\n",i,f[high],f[naka],f[low],f[i],nokori);
					if(nokori>f[naka]){
						low=naka+1;
					//	printf("%d %d %d low\n",i,nokori,f[naka]);
					}
					if(nokori<f[naka]){
						high=naka-1;
					//	printf("%d %d %d high\n",i,nokori,f[naka]);
					}
					if(nokori==f[naka]){
						ba=f[naka];
						v=1;
						break;
					}
				}
				if(v==0)
					ba=f[low-1];
				//printf("%d\n",f[i]+ba);
				if(kore<f[i]+ba){
					kore=f[i]+ba;
				//	printf("   %d\n",kore);
				}
			}
		}
		printf("%d\n",kore);
	}
	return 0;
}

C++: #include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#define MAXSIZE 1000005
#define LL long long
#define INF 0x3f3f3f3f

using namespace std;

LL val[MAXSIZE];

void DFS(LL n,LL m,LL sum,LL step,LL k,bool &ok,bool &big)
{
    if(step > 4)
        return;
    if(sum > k)
        big = true;
    if(sum == k)
        ok = true;
    if(ok)
        return ;
    for(int i=1;i<=n;i++)
    {
        if(sum+val[i] > m)
            break;
        else
        {
            DFS(n,m,sum+val[i],step+1,k,ok,big);
        }
    }
}

int Check(LL k,LL n,LL m)
{
    bool ok = false;
    bool big = false;
    DFS(n,m,0,0,k,ok,big);
    if(ok)
        return 2;
    else if(big)
        return 1;
    return 0;
}

LL Solve(LL n,LL m)
{
    m = min(m , val[n]*4);
    LL R = m;
    LL L = 0;
    LL ans = 0;
    while(L <= R)
    {
        LL mid = (L + R) / 2;
        int op = Check(mid,n,m);
        if(op > 0)
        {
            if(op==2)
                ans = max(ans,mid);
            L = mid + 1;
        }
        else
        {
            R = mid - 1;
        }
    }
    return ans;
}

int main()
{
    LL n,m;
    while(scanf("%lld%lld",&n,&m),n+m)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&val[i]);
        }
        sort(val+1,val+1+n);
        LL ans = Solve(n,m);
        printf("%lld\n",ans);
    }
    return 0;
}

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

int P[1001],Q[1000000];
int main(){
    int n,m;

while(true){
    cin >> n >> m;
    if(n==0 && m==0) break;

    P[0]=0;
    for(int i=1;i<=n;i++) scanf("%d",&P[i]);

    int num=0;
    for(int i=0;i<=n;i++){
	for(int j=i;j<=n;j++){
	    Q[num++]=P[i]+P[j];
	}
    }

    sort(Q,Q+num);

    int key,ans=0,idx;
    int *pos;
    for(int i=0;i<num;i++){
	key=m-Q[i];
	if(key<0) break;
 	pos=upper_bound(Q,Q+num,key);
	idx=distance(Q,pos);
	
	if(Q[i]+Q[idx-1]>ans) ans=Q[i]+Q[idx-1];
    }
    
    cout << ans << endl;
}

    return 0;
}

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

int m, n, p[1000], pp[1000*1000];

int main(){
    while( true ){
        cin >> n >> m;
        if( m == 0 && n == 0 ) break;
        for(int i = 0; i < n; i++){
            cin >> p[i];
        }
        sort(p, p+n);
        for(int i = 0; i < n*n; i++){
            pp[i] = p[i/n] + p[i%n];
        }
        sort(pp, pp + n*n);
        int c = n/p[n-1];
        if( c >= 4 ){
            cout << p[n-1]*4;
            continue;
        }
        int cand = 0;
        if( c <= 3 ){
            int j = n*n-1;
            for(int i = 0; i <= n*n/2 && j > 0; i++){
                while( j >= 0 && pp[i] + pp[j] > m ) j--;
                if(j >= 0) cand = max(cand, pp[i] + pp[j]);
            }
        }
        if( c <= 2 ){
            int j = n*n-1;
            for(int i = 0; i <= n/2; i++){
                while( j >= 0 && p[i] + pp[j] > m ) j--;
                if(j >= 0) cand = max(cand, p[i] + pp[j]);
            }
        }
        if( c <= 1 ){
            int j = n-1;
            for(int i = 0; i <= n/2; i++){
                while( j >= 0 && p[i] + p[j] > m ) j--;
                if(j >= 0) cand = max(cand, p[i] + p[j]);
            }
        }
        int k;
        for(k = n-1; k >= 0 && p[k] > m; k--);
        if( k >= 0 ) cand = max(cand, p[k]);
        cout << cand << endl;
    }
    return 0;
}

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

using namespace std;

int N;
int M;
vector<int>P;
int ans=0;

/*
int binarySearch(int t){
    int lo=0,hi=N-1;
    int te;
    while(true){
        int m=(lo+hi)/2;
        if(P[m]<t){
            hi=(m-1)<=1?0:m-1;
        }else if(P[m]>t){
            lo=m+1;
        }
        if(lo>=hi){
            te=hi;
        }
    }
    return te;
}*/



void func(int dart,int sum){
    ans=max(ans,sum);
    if(dart==4)return ;
    int s=M-sum;
    auto it = upper_bound(P.begin(),P.end(),s);
    it = prev(it);
    for(auto i=it;i!=P.begin();i--){
        func(dart+1,sum+*it);
    }
    
    
    /*
    if(sum+P[n]<=M){
        func(n-1,dart+1,sum+P[n]);
        func(n,1+dart,sum+P[n]);
        func(n-1,dart,sum);
    }
    else {
        func(n-1,dart,sum);
    }
     */
    
    return ;
}
int main(){
    while(cin>>N>>M,N,M){
        P = vector<int>(N+1,0);
        for(int i=0;i<N;i++){
            cin>>P[i];
        }
        sort(P.begin(),P.end());
        P.erase(unique(P.begin(), P.end()), P.end());
        func(0,0);
        cout<<ans<<endl;
        ans=0;
    }
    
    
}

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

int binary(vector<int> &a, int tar){
  int begin = 0, end = a.size() - 1, mid = (begin + end)/2;
  while(begin < mid){
    if(a[mid] < tar){
      begin = mid;
    }else{
      end = mid;
    }
    mid = (begin + end)/2;
  }
  return a[mid];
}


int main(int argc, char *argv[]){
  int n, m;
  while(scanf("%d %d\n", &n, &m)){
    if(n == 0 && m == 0)break;
    int point[n + 1];
    point[0] = 0;
    vector<int> a;
    for (int i = 1; i <= n; i++) {
      scanf("%d\n", &point[i]);
    }
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= n; j++) {
        a.push_back(point[i] + point[j]);
      }
    }
    sort(a.begin(), a.end());
    int ans = 0;
    for (int i: a){
      int tmp = binary(a, m - i);
      if(i + tmp <= m)
        ans = max(ans, i + tmp);
    }
    std::cout << ans << std::endl;
  }
  return 0;
}