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<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[1002001];
int main(void){
	while(1){
		ll n,m,i,j,p[1001],hi,lo,mi,pp,x,mx;
		cin>>n>>m;
		if(n==0)break;
		p[0]=0;
		for(i=1;i<=n;i++) cin>>p[i];
		for(i=0;i<=n;i++) for(j=0;j<=n;j++) a[i*n+j]=p[i]+p[j];
		pp=pow(n+1,2);
		sort(a,a+(pp+2));
		for(i=0;i<=pp+1;i++) cout<<a[i]<<endl;
		mx=0;
		for(i=0;i<=pp+1;i++){
			hi=pp+1; lo=0;
			while(hi>lo){
				mi=(hi+lo)/2;
				x=a[i]+a[mi];
				if(x>m) hi=mi-1;
				else if(x<m) lo=mi+1;
			}
			x=a[i]+a[lo];
			if(mx<x&&m>=x) mx=x;
		}
		cout<<mx<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <cmath>
#include <limits>
#include <functional>

#define REP(i,n) for(int i=0;i<n;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--)
#define pb(x) push_back(x) 
#define SORT(x) sort((x).begin(),(x).end())
#define INF 999999999

using namespace std;

#define int long long

signed main(){
	while(1){
		int n, m;
		cin >> n >> m;
		if(n==0) return 0;
		
		vector<int> p(n);
		REP(i, n){
			cin >> p[i];
		}
		p.push_back(0);
		sort(p.begin(), p.end());
		n++;
		
		vector<int> v;
		REP(i, n){
			REP(j, n){
				v.push_back(p[i]+p[j]);
			}
		}
		SORT(v);
		
		int l=0, r=v.size()-1, ans=0;
		for(; l<r; l++){
			if(v[l]+v[r]>m) r--;
			ans=max(ans, v[l]+v[r]);
		}
		
		cout << ans << endl;
	}
}

C++: #include <iostream>
#include <algorithm>
#include <set>
#define N_MAX 1001
using namespace std;

int N, M;
int P[N_MAX];
set<int> sp;

int solve() {
  set<int> s;
  for(int i = 0; i <= N; i++) {
    for(int j = i; j <= N; j++) {
      for(int k = j; k <= N; k++) {
        int tmp = P[i] + P[j] + P[k];
        if(tmp > M) break;
	if(M-tmp < P[k]) break;
        s.insert(tmp);
      }
    }
  }

  for(int i = 0; ; i++) {
    for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
      int tmp = M - *it - i;
      if(sp.find(tmp) != sp.end()) return tmp + *it;
    }
  }
}

int main() {
  while((cin >> N >> M) && N && M) {
    P[0] = 0;
    sp.clear();
    sp.insert(0);
    for(int i = 1; i <= N; i++) {
      cin >> P[i];
      sp.insert(P[i]);
    }
    cout << solve() << endl;
  }
  return 0;
}

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

template<class T> inline void chmax(T& a, T b) { if(b > a) a = b; }

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	for(int n, m; cin >> n >> m, n;) {
		vector<int> p;
		p.reserve(n);
		for(int i = 0; i < n; ++i) {
			int in;
			cin >> in;
			if(in <= m)
				p.push_back(in);
		}

		n = p.size();

		vector<int> score;
		score.reserve(n * n + n);
		for(int i = 0; i < n; ++i) {
			score.push_back(p[i]);
			for(int j = 0; j < n; ++j) {
				if(p[i] + p[j] <= m)
					score.push_back(p[i] + p[j]);
			}
		}

		sort(score.begin(), score.end());

		int ans = 0;
		for(int i = 0, j = score.size() - 1; i <= j; ++i) {
			while(i <= j && score[i] + score[j] > m)
				--j;

			if(i <= j)
				chmax(ans, score[i] + score[j]);
		}

		cout << ans << endl;
	}

	return EXIT_SUCCESS;
}

C++: #include<iostream>
#include<algorithm>
#include<iterator>
using namespace std;
const int N=1000;
int*pe,p[1+N],*qe,q[1+N*N],n,m,v;
int main(){
	for(;cin>>n>>m,n;){
		v=*p=0;
		pe=copy_n(istream_iterator<int>(cin),n,p+1);
		sort(p,pe);
		pe=unique(p,pe);
		qe=q;
		for(int*i=p;i!=pe;++i)
			qe=transform(p,i+1,qe,bind2nd(plus<int>(),*i));
		sort(q,qe);
		qe=unique(q,qe);
		*qe++=m+1;//ツ氾板閉コ
		for(int*i=q;*i<=m;++i)
			v=max(v,*i+upper_bound(q+1,qe,m-*i)[-1]);
		cout<<v<<endl;
	}
	cout<<endl;
}

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

using namespace std;

int main(){
  while(true){
    int N,M,mex;
    mex = -1;
    cin >> N >> M ;
    if(N+M == 0)break;
    vector<int> val,dp;
    for(int i=0;i<N;i++){
      int a; cin >> a; 
      val.push_back(a);     
      dp.push_back(a);
    }
    dp.push_back(0);
    map<int,bool> exist;
    for(int i=0;i<val.size();i++){
      for(int j=0;j<val.size();j++){
	//if(M > val[i]+val[j])continue;
	dp.push_back(val[i]+val[j]);
      }
    }
    sort(dp.begin(),dp.end());
    int mmex = -1; 
    for(int i=0;i<dp.size();i++){
      if(M >= dp[i])mmex = max(mmex,dp[i]+upper_bound(dp.begin(),dp.end(),M-dp[i])[-1]);
      
    }

    cout << mmex << endl;
    mex = -1;
  }
  return 0;
}

C++: #include<cstdio>
#include<iostream>
#include<queue>
#include<vector>

using namespace std;

int main(void)
{
   vector<int>a;
   priority_queue<int>ans;

   int n,m;
   int input;

   while(scanf("%d%d",&n,&m),n+m)
   {
      a.clear();
      while(ans.size()) ans.pop();

      a.push_back(0);
      for(int i = 0;i < n;i++)
      {
         scanf("%d",&input);
         a.push_back(input);
      }

      int s = a.size();
      int one,two;
      for(int i = 0;i < s;i++)
         for(int j = 0;j < s;j++)
         {
            one = a[i],two = a[j];
            if(one + two <= m) a.push_back(one + two);
         }

      s = a.size();
      for(int i = 0;i < s;i++)
         for(int j = 0;j < s;j++)
         {
            one = a[i],two = a[j];
            if(one+two <= m) ans.push(one+two);
         }
      cout<<ans.top()<<endl;
   }
   return 0;
}

C++: #include "bits/stdc++.h"
using namespace std;
#define ll long long int
#define rep(i,n) for( int i = 0; i < n; i++ )
#define REP(i,s,t) for( int i = s; i <= t; i++ )
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define INF 2000000000
#define mod 1000000007
#define INF2 1000000000000000000

int kk[1100001];
int n, m;

int binary_search(int x) {
    if (x <= 0) return 0;
    int l = 0, r = n * n;
    //dump(r - l);
    int i = 0;
    while(r - l >= 1) {
        i = (l + r) / 2;
        if (kk[i] == x) return i;
        else if (kk[i] < x) l = i + 1;
        else r = i;
    }
    while(kk[i] > x) i--;
    return i;
}

int main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(true){
        cin >> n >> m;
        if(n == 0 && m == 0) return 0;
        int k[n+1];
        k[0] = 0;
        rep(i, n) cin >> k[i+1];
        rep(k, 1100001) kk[k] = 0;
        rep(c, n+1) {
            rep(d, n+1) {
                kk[c * n + d] = k[c] + k[d];
            }
        }

        sort(kk, kk + (n+1) * (n+1));
        int ans = 0;
        rep(a, n+1) {
            rep(b, n+1) {
                int index = binary_search(m - k[a] - k[b]);
                int tmp = kk[index] + k[a] + k[b];
                if(tmp <= m) ans = max(ans, tmp);
                tmp = kk[index+1] + k[a] + k[b];
                if(tmp <= m) ans = max(ans, tmp);

            }
        }
        cout << ans << endl;
    }

    return 0;
}