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<algorithm>

#define NMAX 1000
using namespace std;

int N;
int big;
long long M;
long long  sc[NMAX];

int solve(long long s,int d){
	int m=-1;
	if(s>M) return 0;
	if(d==4) return s;
	for(int i=0;i<N;i++){
		if(s+sc[i]+big*(3-d)<m) break;
		m=max(m,solve(s+sc[i],d+1));
	}
	if(s+big*(3-d)>m) m=max(m,solve(s,d+1));
	return m;
}

int main(void){
	std::ios_base::sync_with_stdio(false);

	while(1){

		cin>>N>>M;
		if(N==0&&M==0) break;
		big=-1;

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

		cout<<solve(0,0)<<endl;
	}

	return 0;
}

C++: //JOI 2008??´???3??? ?????????

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;

#define MAX -210000000
#define MIN 210000000

int a,b;
int d[1000],c[1000*1000+2],hk=0,mcunt,low,high;
int x,pr=0/*,flg[200000000]*/,m,ff=0;

int main(){ 
	
	scanf("%d %d",&a,&b);
	
	d[0]=0;
	hk=0;
	for(int i=1;i<=a;i++) scanf("%d",&d[i]);
	
	for(int i=0;i<=a;i++){
		for(int j=0;j<=a;j++){
			//if(flg[d[i]+d[j]]!=1){
				c[hk]=d[i]+d[j];
				//printf("%lld\n",c[cunt]);
				hk++;
			/*	flg[d[i]+d[j]]=1;
			
			}*/
		}
	}
	//printf("Sort???\n");
	sort(c,c+hk);
	/*printf("\n");
	for(int i=0;i<hk;i++) printf("%d\n",c[i]);
	printf("\n");
	
	printf("hk=%d\n",hk);
	printf("c[low]=%d c[high]=%d\n",c[hk],c[hk-1]);*/
	                                 
	for(int i=0;i<hk;i++){
		x=b-c[i];
		//printf("x=%d\n",x);
		low=0;
		high=hk;
		
		while(low<=high){
			m=(low+high)/2;
			if(x==c[m]){
				ff=1;
				break;
			}
			if(x>c[m]) low=m+1;
			else if(x<c[m]) high=m-1;
		}
		//printf("\n%d\n",low);
		if(ff==1){
			pr=c[i]+c[m];
			break;
		}
		if(b>c[i]+c[high] && pr<c[i]+c[high]){
			pr=c[i]+c[high];
		//	printf("%d %d\n",c[i],c[high]);
		}
	}
	printf("%d\n",pr);
	return 0;
}

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

using namespace std;

int main() {
	int n[1000], m[1000], p[10][1000],ans=0, i = 0;
	vector<int> v;
	while (cin >> n[i] >> m[i]) {
		if (n[i] == 0)break;
		for (int j = 0; j < n[i]; j++)cin >> p[i][j];
		i++;
	}
	for (int k = 0; k < i; k++) {
		ans = 0;
		v = vector<int>(1,0);
		for (int a = 0; a < n[k]; a++) {
			v.push_back(p[k][a]);
			for (int b = 0; b < n[k]; b++)
				v.push_back(p[k][a] + p[k][b]);
		}
		sort(v.begin(), v.end());
		for (int j = 0; j < v.size(); j++) {
			if (v[j] > m[k])break;
			decltype(v)::iterator itr= upper_bound(v.begin(), v.end(), m[k]-v[j]);
			itr--;
			ans = max(ans, v[j] + *itr);
		}
		cout << ans << endl;
	}
	return 0;
}

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

#define ALL(n) (n).begin(),(n).end()

int main(){
	int n,m;
	while(1){
		cin>>n>>m;	if(n==0&&m==0)break;

		vector<int> p(n+1);
		p[0]=0;
		for(int i=1;i<=n;i++)cin>>p[i];
		sort( ALL(p) );

		vector<int> pc_pd((n+1)*(n+1));
		for(int c=0;c<=n;c++){
			for(int d=0;d<=n;d++){
				pc_pd[c*(n+1) + d]=p[c]+p[d];
			}
		}
		sort( ALL(pc_pd) );

		int ans=0;
		for(int a=0;a<=n;a++){
			for(int b=0;b<=n;b++){
				int tmp=p[a]+p[b];

				if(tmp>m)continue;
				else{
					//{{{ binary_search
					int OK=0, NG=(n+1)*(n+1);
					int MAX=m-tmp;

					while(NG-OK>1){
						int mid=(NG+OK)/2;

						if(pc_pd[mid]<=MAX) OK=mid;
						else NG=mid;
					}
					tmp+=pc_pd[OK];
					//}}}
				}


				ans=max(ans,tmp);
			}
		}

		cout<<ans<<endl;

	}
	return 0;
}

C++: 
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main()
{
	int ans[4];
	int temp;
	double energy,energy_min,energy_now;
	int M, N;
	int* p;
	int i, j;
	double T=100;
	int ret;
	while (1) {
		scanf("%d%d", &N, &M);
		p = (int*)malloc((N+1) * sizeof(int));
		for (i = 0; i < N; i++) {
			scanf("%d", &p[i]);
		}
		p[N] = 0;
		if (N == M && N == 0) {
			break;
		}
		energy_min = pow(10, 300);
		for (j = 0; j < 4; j++) {
			ans[j] = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
		}
		
		for (T = 1000000; T > 103; T--) {
			for (j = 0; j < 4; j++) {
				temp = p[(int)((double)(rand() + 1) / (RAND_MAX + 2)*(N+1))];
				for (j = 0; j < 4; j++) {
					ret = ans[0] + ans[1] + ans[2] + ans[3];
					ret += temp - ans[j];
					energy = M - ret;
					if (M < ret)energy += 100000000;

					if (energy < energy_min) {
						energy_min = energy;
						ans[j] = temp;
					}
					else if ((double)(rand() + 1) / (RAND_MAX + 2) < exp((energy_min - energy) / T*10)) {
						energy_min = energy;
						ans[j] = temp;
					}
				}

			}
		}
		ret=ans[0]+ +ans[1] + ans[2] + ans[3];
		printf("%d\n", ret);
	}
    return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define FORR(i, m, n) for (int i = (m); i >= (n); --i)
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll mod2 = 998244353;
const int INF = 1000000005;

int main() {
  int n, m, point, rest;
  while (cin >> n >> m) {
    if (n == 0 && m == 0) break;
    int ans = 0;
    vector<int> p(n + 1), pp;
    rep(i, n) {
      cin >> p[i];
    }
    rep(i, n + 1) {
      rep(j, n + 1) {
        pp.push_back(p[i] + p[j]);
      }
    }
    sort(pp.begin(), pp.end());

    rep(i, n + 1) {
      rep(j, n + 1) {
        point = p[i] + p[j];
        if (point > m) continue;
        rest = m - point;
        point += *(upper_bound(pp.begin(), pp.end(), rest) - 1);
        if (point <= m) {
          ans = max(ans, point);
        }
      }
    }

    cout << ans << endl;

  }

  
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    while(true){
        int n,m;
        cin >> n >> m;
        if(n==0)break;
        vector<int> list(n);
        for(int i=0;i<n;i++){
            cin >> list[i];
        }
        sort(list.begin(),list.end());
        vector<vector<int> > map(n,vector<int>(5,0));
        for(int i=1;i<=4;i++){
           if(list[0]*i<=m)map[0][i]=list[0]*i;
           else map[0][i]=map[0][i-1];
        }
        for(int i=1;i<n;i++){
            if(list[i]<=m)map[i][1]=max(list[i],list[i-1]);
            else list[i-1];
        }
        for(int i=1;i<n;i++){
            for(int j=2;j<=4;j++){
                map[i][j]=map[i][j-1];
                for(int k=0;k<=i;k++){
                for(int l=0;l<=i;l++){
                    if(map[k][j-1]+list[l]<=m){
                        map[i][j]=max(map[k][j-1]+list[l],map[i][j]);
                    }
                    else break;
                }
                }
            }
        }
        cout << map[n-1][4] << endl;
    }
    return 0;
}