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 <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <map>
#include <set>
#include <stack>
#include <queue>
 
using namespace std;
 
#define pb(n)	push_back(n)
#define mp(n,m) make_pair(n,m)
#define fi 	first
#define se 	second
#define all(r) (r).begin(),(r).end()
 
#define REP(i,s,e)	for(int i=(s); i<(e); i++)
#define rep(i,n)	REP(i,0,n)
#define REPE(i,s,e)	for(int i=s; i>e; i--)
#define repe(i,n)	REPE(i,n,-1)


typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
 
typedef vector<vi> vvi;
 
const int IMAX=((1<<30)-1)*2+1;
const int INF=100000000;
const double EPS=1e-10;
//int mod=1000000007



const int MAX_N = 1000;
const int MAX_W = 200000000;

int dp[MAX_N + 1][MAX_W + 1][5];
int v[MAX_N], w[MAX_N];
int N,W;


int solve() {
	for(int i = 0; i < N; i++) {
		for(int j = 0; j <= W; j++){
			for(int k = 0; k < 5; k++){
				if(j < w[i] || k <1) {
					dp[i + 1][j][k] = dp[i][j][k];
				}
				else{
					dp[i + 1][j][k] = max(/*max(*/dp[i][j][k]/*,dp[i][j-w[i]][k-1] + v[i])*/, dp[i + 1][j - w[i]][k-1] + v[i]);
				}
			}
		}
	}
	return dp[N][W][4];
}

int main(){
	int n, m;
	while(cin>>n>>m){
		N = n;
		W = m;
		for(int i = 0; i < n; i++){
			cin >> v[i];
			w[i] = v[i];
		}
		cout<<solve()<<endl;
	}
}

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

#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)

int dp[5][1024];
int p[1024];
int main(){
	int n,m;
	while(cin>>n>>m,n|m){
		int ret = 0;
		rep(i,n)scanf("%d",&p[i]);
		rep(i,5)rep(j,n+1)dp[i][j]=0;
		
		rep(i,n){
			for(int j=0; j<=i; j++){
				rep(k,4)if( dp[k][j]+p[i]<=m ){
					dp[k+1][i] = max(dp[k+1][i], dp[k][j]+p[i]);
					ret = max(ret,dp[k+1][i]);
				}
			}
		}
		
		/*
		rep(i,n){
			rep(j,5){
				printf("%d:%d  %d\n",i,j,dp[j][i]);
			}
		}
		*/
		
		printf("%d\n",ret);
	}
	return 0;
}

C++: //http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
//http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2676345#1
#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<cstdio>
#include<fstream>
#include<cstring>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define P pair<int,int>
#define ll __int64

int n,m;
int t[10000];
const int MA=1000000;
int s1[MA],s2[MA];

int ya[4];

int main(){

while(cin>>n>>m,n||m){
rep(i,MA)s1[i]=s2[i]=0;
rep(i,10000)t[i]=0;

for(int i=1;i<=n;i++)cin>>t[i];
int g=0;

for(int i=0;i<=n;i++){
	for(int j=0;j<=n;j++){
		s1[i*(n+1)+j]=t[i]+t[j];
		//s2[i*(n+1)+j]=t[i]+t[j];	
		g++;
	}
}


sort(s1,s1+g);
rep(i,g)s2[i]=s1[i];
//sort(s2,s2+g);

//rep(i,g)cout<<s1[i]<<" ";cout<<endl;

int ans=0;

for(int i=0;i<g;i++){
	int now=s1[i];

	int l=0;
	int r=g-1;
	int mid=(l+r)/2;
	int x=s2[mid];

	for(int i=0;i<60;i++){
		if(x+now==m)break;
		if(x+now>m){
			r=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
		else{
			l=mid;
			mid=(r+l)/2;
			x=s2[mid];
		}
	}

	//cout<<" "<<x<<" "<<now<<" "<<x+now<<endl;
	if(x+now<=m)
	ans=max(ans,x+now);
}
cout<<ans<<endl;
}
	return 0;
}

C++: #include <cstdio>
#include <algorithm>
using namespace std;
long long m;
int n;
long long num[1001];
long long sum[1000005];
int main(){
	while(1){
	scanf("%d %lld",&n,&m);
	if(!n) break;
	for(int i=0;i<n;i++){
		scanf("%lld",&num[i]);
	}
	num[n]=0;
	int ro=0;
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			sum[ro]=num[i]+num[j];
			ro++;
		}
	}
	long long ans=0;
	sort(sum,sum+ro);
	for(int i=0;i<ro;i++){
		if(sum[i]>m){ break;}
		int rp=lower_bound(sum,sum+ro,m-sum[i])-sum;
			rp--;
			ans=max(ans,sum[i]+sum[rp]);
	}
	printf("%d\n",ans);
}
	return 0;
}

C++: #include <iostream>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)

typedef unsigned long long ull;

ull dp[1000][5];

int main(){
    int N;
    ull M, P[1000];

    while(std::cin >> N >> M, N){
        REP(i, N){
            std::cin >> P[i];
        }

        REP(i, 1000){
            REP(j, 5){
                dp[i][j] = 0;
            }
        }

        REP(i, 5){
            if(P[0] * i <= M){
                dp[0][i] = P[0] * i;
            }
        }

        REP(i, N-1){
            REP(j, 5){
                REP(k, j+1){
                    if(P[i+1] * k + dp[i][j-k] <= M){
                        dp[i+1][j] = std::max(P[i+1] * k + dp[i][j-k], dp[i+1][j]);
                    }
                }
            }
        }

        ull res = 0;
        REP(i, 5){
            res = std::max(dp[N-1][i], res);
        }

        std::cout << res << std::endl;
    }

    return 0;
}

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

#define ef(e, a, b) ((e) ? (a) : (b))

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];

	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		
		for (int i = 0; i < n; ++i)
		{
			cin >> p[i];
		}
		
		for (int i = 0; i < n; ++i)
		{
			if (p[i] > m) { break; }
			ans = max(ans, p[i]);
			for (int j = 0; j < n; ++j)
			{
				if (p[i] + p[j] > m) { break; }
				ans = max(ans, p[i] + p[j]);
				for (int k = 0; k < n; ++k)
				{
					if (p[i] + p[j] + p[k] > m) { break; }
					ans = max(ans, p[i] + p[j] + p[k]);
					for (int l = 0; l < n; ++l)
					{
						if (p[i] + p[j] + p[k] + p[l] > m) { break; }
						ans = max(ans, p[i] + p[j] + p[k] + p[l]);
						
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
int n,ma;
int m,p[1001];
int dfs(int k){
  if(k == 4) return 0;
  int ret = 0;
  for(int i=0;i<n;i++){
    if(dfs(k+1)+p[i]-m > 0) break;
    ret = max(ret,dfs(k+1)+p[i]);
  }
  ma = max(ma,ret);
  return ret;
}
int main(){
  while(cin >> n >> m && n!=0 && m!= 0){
    ma = 0;
    for(int i=0;i<n;i++){
      cin >> p[i];
    }
    sort(p,p+n);
    dfs(0);
    cout << ma << endl;
  }
  return (0);
}