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 <cctype>
#include <utility>
#include <vector>
#include <algorithm>
#include <array>
#include <numeric>
using namespace std;

const auto gcu = getchar_unlocked;
const auto pcu = putchar_unlocked;
#define _NE noexcept
#define _T template <typename T>
#define _HT template <typename H, typename... T>
#define _il inline
#define _sc _il bool scan
_T T in(int c)_NE{T n=0;int m=1;while(isspace(c)){c=gcu();}if(c=='-')m=-1,c=gcu();
	do{n=10*n+(c-'0'),c=gcu();}while(c>='0'&&c<='9');return m*n;}
_il int in()_NE{return in<int>(gcu());}
_T T scan(T &n)_NE{int c=gcu();return c==EOF?false:(n=in<T>(c),true);}
_sc(char &c)_NE{c=gcu();gcu();return c!=EOF;}
#ifdef _GLIBCXX_STRING
_sc(string &s)_NE{int c;s="";
	for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=c;}}
#endif
_HT _sc(H &h, T&&... t){return scan(h)&&scan(t...);}
#define _ot _il void out
#define _ol _il void outl
_ot(bool b)_NE{pcu('0'+b);}
_ot(const char *s)_NE{while(*s)pcu(*s++);}
_ot(char c)_NE{pcu(c);}
#ifdef _GLIBCXX_STRING
_ot(string s)_NE{for(char c:s)pcu(c);}
#endif
_T _ot(T n)_NE{static char b[20];char *p=b,m=n<0?pcu('-'),-1:1;
	if(!n)*p++='0';else while(n)*p++=n%10*m+'0',n/=10;while(p!=b)pcu(*--p);}
_ol(){out('\n');}
#ifdef _GLIBCXX_VECTOR
_T _ot(vector<T> &v)_NE{for(T &x:v)out(&x == &v[0]?"":" "),out(x);outl();}
#endif
_HT _ot(H&& h, T&&... t)_NE{out(h);out(move(t)...);}
template <typename... T> _ol(T&&... t)_NE{out(move(t)...);outl();}

#define all(o) o.begin(), o.end()

void radix_sort(vector<int> &v) {
	vector<int> t(v.size());
	array<int, 256> c, s;
	for (int i = 0; i < 32; i += 8) {
		fill(all(c), 0);
		for_each(all(v), [&](int j) {c[(j >> i) & 255]++;});
		s.front() = 0;
		partial_sum(all(c) - 1, s.begin() + 1);
		for_each(all(v), [&](int j) {t[s[(j >> i) & 255]++] = j;});
		swap(v, t);
	}
}

int main() {
	for (int N, M; N = in(), M = in();) {
		vector<int> t(N), u;
		for (int &p: t)
			p = in();
		t.push_back(0);
		for (auto i = t.begin(); i != t.end(); i++)
			for (auto j = i; j != t.end(); j++)
				if (*i + *j <= M)
					u.push_back(*i + *j);
		radix_sort(u);
		int r = 0;
		for (auto i = u.begin(), e = u.end() - 1; i <= e; i++) {
			for (; *i + *e >= M; e--)
				;
			r = max(r, *i + *e);
		}
		outl(r);
	}
}

C++: #include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctype.h>
#include <ctime>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <numeric>
#include <complex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

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

//4方向ベクトル→↑←↓
int dx[] ={1,0,-1,0};
int dy[] ={0,-1,0,1};
int N,M;
int ans;
int sum[10000000];
int main()
{
  vector<int> D;
  while(cin>>N>>M,N||M){
    for(int i = 0;i < N;i++){
      cin >>ans;
      D.push_back(ans);
    }
    D.push_back(0);
    int size = 0;
    for(int i = 0;i <= N;i++){
      for(int j = 0;j <=N;j++){
	sum[size++] =D[i]+D[j];
      }
    }
    sort(sum,sum+size);
    for(int i = 0;i <size;i++){
      int rem =M -sum[i];
      if(rem <0)continue;
      int left = 0;
      int right = size;
      while(left <right){
	int center =(left+right)/2;
	if(rem >sum[center]){
	  left =center +1;
	}else if(rem <sum[center]){
	  right = center;
	}
	else{
	  break;
	}
      }
      D.clear();
      ans = max(ans,sum[i]+sum[right-1]);
  }
    cout <<ans<<endl;
  }
  return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define lp(i,n) for(int i=0;i<(n);i++)
#define int long long

signed main()
{
   while(true){
      int N,M; cin>>N>>M;
      if(N==0 and M==0) break;
      vector<int> a(N+1);
      for(int i=0;i<N;i++){
         cin>>a[i];
      }
      a[N]=0; N++;
      vector<int> b;
      for(int i=0;i<N;i++){
         for(int j=i;j<N;j++){
            b.push_back(a[i]+a[j]);
         }
      }
      sort(b.begin(),b.end());

      int ans=0;
      for(int i=0;i<b.size();i++){
         int j=upper_bound(b.begin(),b.end(),M-b[i])-b.begin();
         if(j>0){
            ans=max(ans,b[i]+b[j-1]);
         }
      }
      cout<<ans<<endl;
   }
}

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

int max(int x, int y);
int add(int x, int y, int m);

int main(){
  int n, m;
  while(cin >> n >> m, n&&m){
    int dp[4][n];
    for(int i = 0; i < 4; i++){
      for(int j = 0; j < n; j++){
	dp[i][j]  = 0;
      }
    }
    for(int i = 0; i < n; i++){
      cin >> dp[0][i];
    }

    for(int i = 1; i < 4; i++){
      for(int j = 0; j < n; j++){
	for(int k = 0; k < n; k++){
	  dp[i][j] = max(add(dp[i-1][j], dp[0][k], m), dp[i][j]);
	}
      }
    }
    int max = 0;
    for(int i = 0; i < n; i++){
      if(dp[3][i] > max) max = dp[3][i];
    }
    cout << max << endl;
  }
}


int max(int x, int y){
  return x < y ? y : x;
}

int add(int x, int y, int m){
  return x+y < m ? x+y : 0;
}

C++: //INCLUDE
//------------------------------------------
#include <iostream>
#include <algorithm>
#include <vector>
//DEFINE
//------------------------------------------
#define ll long long
#define ALLv(a)  (a).begin(),(a).end()
#define vi vector<long long>
//REPEAT
//------------------------------------------
#define REP(i,n) for(ll(i)=0;(i)<(n);(i)++)
#define REPS(i,x) for(ll(i)=1;(i)<=(x);(i)++)
#define WREP(i,in,j,jn) REP(i,in)REP(j,jn)
using namespace std;
//-------------------------------------------
void solve(ll N,ll M){
  vi p(N+1);p[0]=0;REPS(i,N)cin>>p[i];
  vi pp;WREP(i,N+1,j,N+1)pp.push_back(p[i]+p[j]);
  sort(ALLv(pp));
  ll ans=0;
  REP(i,pp.size()){
    ll idx=upper_bound(ALLv(pp),M-pp[i])-pp.begin()-1;
    if(idx<0)continue;
    ans=max(ans,pp[i]+pp[idx]);
  }
  cout<<ans<<"\n";
}
int main(void){
  ll N,M;
  while(cin>>N&&cin>>M){
  	if(N==0&&M==0)break;
    solve(N,M);
  }
}

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

int main(){
while(1){
	int n,m,a,ans=0;
	vector<int> p,pp;
	scanf("%d%d",&n,&m);
	if(n==0&&m==0)break;
	p.push_back(0);
	for(int i=0;i<n;i++){
		scanf("%d",&a);
		p.push_back(a);
	}
	for(int i=0;i<=n;i++){
		for(int j=i;j<=n;j++){
			if(p[i]+p[j]>m)break;
			pp.push_back(p[i]+p[j]);
		}
	}
	sort(pp.begin(),pp.end());
	int s=pp.size()-1;
	for(int i=0;i<=s;i++){
		while(pp[i]+pp[s]>m)s--;
		if(ans<pp[i]+pp[s])ans=pp[i]+pp[s];
	}
	printf("%d\n",ans);
}
}