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>
using namespace std;

int N,M;
int data[1001];
int data2[1002001];

int main(){
	int i,j;
	int d2cor,mcor = 0;
	int max[1000] = {0};
	while(1){
		d2cor = 1;
		max[mcor] = 0;
		cin >> N >> M;
		if(N == 0 && M == 0)
			break;
		for(i = 1;i <= N;i++){
			cin >> data[i];
		}
		for(i = 0;i <= N;i++){
			for(j = i;j <= N;j++){
				data2[d2cor] = data[i]+data[j];
				d2cor++;
			}
		}
		sort(data2,data2+d2cor);
		//探索(O(NN)*O(log(NN))
		int start,last,medi;
		for(i = 0;i < d2cor;i++){
			if(data2[i] > M)
				break;
			start = 0;
			last = d2cor-1;
			while(data2[start] < data2[last]){
				medi = (start+last)/2;
				//下
				if(data2[i]+data2[medi] > M){
					last = medi-1;
				}
				//同じか上(無限ループしないように工夫.medi要素を除く工夫をする)
				else{
					//一つ上がオーバーなら、そのひとつ前に確定
					if(data2[i]+data2[medi+1] > M){
						start = medi;
						break;
					}
					//オーバーしてなければこれ以上が最大
					start = medi+1;
				}
			}
			if(max[mcor] < data2[i]+data2[start])
				max[mcor] = data2[i]+data2[start];
		}
		mcor++;
	}
	for(i = 0;i < mcor;i++){
		cout << max[i] << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int main(){
  ll N,M;
  while( cin >> N >> M){ 
    if( N == 0 && M == 0){ break;}
  vector<ll> P(N+1);
  ll ans = 0LL;
  for(ll i = 0; i < N; i++){ cin >> P[i];} P[N] = 0;
   // cin all components that is the same with P1~PN+1 in 1-indexed
  
  vector<ll> two;
  for(ll i = 0; i <= N; i++){
   for(ll j = 0; j <= N; j++){
     two.push_back(P[i]+P[j]);}}
    
  sort(two.begin(),two.end());
    
    
    
  for(ll i = 0; i < two.size(); i++){
    ll c = two[i];
  
    if( c > M){ continue;}
    
    auto itr = upper_bound(two.begin(),two.end(),M-c);
    if( itr == two.begin()){ continue;}
    itr--;
    
    if( *itr > M-c){ continue;}
    ans = max(ans, c+*itr);
  }
  
  cout << ans << endl; }return 0;}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 1000

using namespace std;

int N,M;
int pi[MAXN];

bool comp(int i,int j)
{
	return i>j;
}

void solve()
{
	int temp=4;
	int res=0;
	int grade=M;
	sort(pi,pi+N,comp);
	for(int i=0;i<N;i++)
	{
		while(grade>=pi[i]&&temp>0)
		{
			grade-=pi[i];
			temp--;
			res+=pi[i];
		}
		if(temp==0)break;
	}
	cout<<res<<endl;
}

void input()
{
	while(scanf("%d%d",&N,&M))
	{
		if(N==0&&M==0)break;
		for(int i=0;i<N;i++)
		{
			scanf("%d",&pi[i]);
		}
		solve();
	}
}

int main()
{
	input();
	return 0;
}

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 <bits/stdc++.h>

using namespace std;

int N, M;
vector<int> DartsInfo;
//set<int> Total;
vector<int> Total;

int main() {
	int p, totalMax;
	vector<int>::iterator pos;

	while (cin >> N >> M, N) {
		DartsInfo.clear();
		Total.clear();
		DartsInfo.push_back(0);
		for (int i = 0; i < N; ++i) {
			cin >> p;
			DartsInfo.push_back(p);
		}
		for (int i = 0; i <= N; ++i) {
			for (int j = 0; j <= N; ++j) {
				totalMax = DartsInfo[i] + DartsInfo[j];
				if (totalMax > M) {
					continue;
				}
				//Total.insert(totalMax);
				Total.push_back(totalMax);
			}
		}
		sort(Total.begin(), Total.end());
		totalMax = -1;
		for (pos = Total.begin(); pos != Total.end(); ++pos) {
			totalMax = max(totalMax, *pos + *(--upper_bound(Total.begin(), Total.end(), (M - *pos))));
		}
		cout << totalMax << endl;
	}

	return 0;
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;
int n, m;
int dp[10000][4], p[10000];
int main() {
    while (scanf("%d%d",&n,&m)) {
        if (!n&&!m) break;
        for (int i=0; i<n; i++) scanf("%d",&p[i]);
        int res=0;
        for (int i=0; i<4; i++) {
            if ((i+1)*p[0]>m&&i) dp[0][i]=dp[0][i-1];
            else if ((i+1)*p[0]>m) dp[0][i]=0;
            else res=max(res,dp[0][i]=(i+1)*p[0]);
        }
        for (int i=1; i<n; i++) {
            for (int j=0; j<4; j++) {
                for (int k=0; k<=j; k++) {
                    if (dp[i-1][j-k]+k*p[i]<=m)
                        dp[i][j]=max(dp[i][j],dp[i-1][j-k]+k*p[i]);
                }
            }
        }
        printf("%d\n",dp[n-1][3]);
    }
}

C++: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int main() {
	int n, m;
	vector<int> a;
	cin >> n >> m;
	while((n*n)+(m*m)!=0){
	 int bi = ((n + 1)*(n + 2)) / 2;
	vector<int> p(n);
	for (int i = 0; i < n; i++) {
		cin >> p[i];
	}
	vector<int> g(bi);
	int ch = n + 1;
	for (int i = 0; i < n; i++) {
		g[i] = p[i];
	}
	g[n] = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j <= i; j++) {
			g[ch] = p[i] + p[j];
			ch++;
		}
	}
	sort(g.begin(), g.end());
	int ans = 0;
	int qans;
	for (int i = 0; i < bi; i++) {
		int lo = 0;
		int up = bi - 1;
		int tan = m - g[i];
		if (g[up] <= tan) {
			qans = g[up];
		}
		else if (tan < g[lo]) {
			qans = -2 * 1000 * 1000 * 1000 - 1;
		}
		else {
			while (up - lo > 1) {
				int mi = (up + lo) / 2;
				if (tan < g[mi]) {
					up = mi;
				}
				else {
					lo = mi;
				}
			}
			qans = g[lo];
		}
		ans = max(ans, g[i] + qans);
	}
	cout << ans << endl;   
	cin >> n>>m;
	}
}