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;
using ll=long long;
using vec=vector<ll>;
using mat=vector<vec>;
#define For(i,a,b) for(i=a;i<b;i++)
#define rep(i,N) For(i,0,N)
#define rep1(i,N) For(i,1,N)
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define mod 1000000007
using datas=pair<ll,ll>;
using tdata=pair<datas,ll>;

long mmid(long a,long b,long c){return a<b?(b<c?b:max(a,c)):(b>c?b:min(a,c));}

ll modinv(ll a) {
  ll b=mod,u=1,v=0,t;
  while(b){
    t=a/b;
    a-=t*b; swap(a,b);
    u-=t*v; swap(u,v);
  }
  return (u+mod)%mod;
}

ll moddevide(ll a,ll b){return (a*modinv(b))%mod;}

ll modncr(ll n,ll r){
  ll i,plus=1;
  rep(i,r){
    plus=(plus*(n-i))%mod;
    plus=moddevide(plus,i+1);
  }
  return plus;
}

ll modncrlistp[200000],modncrlistm[200000];

ll modncrs(ll n,ll r){
  ll i,j;
  if(modncrlistp[n]==0){
    for(i=n;i>=0;i--){
      if(modncrlistp[i])break;
    }
    if(i<0){
      modncrlistp[0]=1;
      rep1(i,n+1){
        modncrlistp[i]=(modncrlistp[i-1]*i)%mod;
      }
    }else{
      For(j,i+1,n+1){
        modncrlistp[j]=(modncrlistp[j-1]*j)%mod;
      }
    }
  }
  if(modncrlistm[n]==0){
    for(i=n;i>=0;i--){
      if(modncrlistm[i])break;
    }
    if(i<0){
      modncrlistm[0]=1;
      rep1(i,n+1){
        modncrlistm[i]=(modncrlistm[i-1]*modinv(i))%mod;
      }
    }else{
      For(j,i+1,n+1)modncrlistm[j]=(modncrlistm[j-1]*modinv(j))%mod;
    }
  }
  return (((modncrlistp[n]*modncrlistm[r])%mod)*modncrlistm[n-r])%mod;
}

ll euclidean_gcd(ll a, ll b) {
  if(a<b) return euclidean_gcd(b, a);
  ll r;
  while ((r=a%b)){a=b;b=r;}
  return b;
}

ll countdigits(ll n){
  ll ans=0;
  while(n){n/=10;ans++;}
  return ans;
}

ll sumdigits(ll n){
  ll ans=0;
  while(n){ans+=n%10;n/=10;}
  return ans;
}

void printmap(vector<ll>& a,ll H,ll W){
  ll i,j;
  For(i,0,H+2){
    For(j,0,W+2){cout<<a[i*(W+2)+j];}
    cout<<endl;
  }
}
void inputmap(vector<ll>& a,ll H,ll W){
  ll i,j;
  string ss;
  For(i,1,H+1){
    cin>>ss;
    For(j,1,W+1){
      if(ss[j-1]=='#'){
        a[i*(W+2)+j]=1;
      }else{
        a[i*(W+2)+j]=0;
      }
    }
  }
}
ll lpow(ll a,ll b){
  ll i,res=1;
  rep(i,b){
    res*=a;
  }
  return res;
}

struct unionfind{
  vector<ll> par,treesize;
  unionfind(ll N){
    par.resize(N);
    for(ll i=0;i<N;i++)par[i]=i;
    treesize.resize(N);
    for(ll i=0;i<N;i++)treesize[i]=1;
  }
  ll root(ll x){
    ll r;
    if(par[x]==x)return x;
    r=root(par[x]);
    if(par[x]!=r){
      treesize[r]+=treesize[x];
      treesize[x]=0;
      par[x]=r;
    }
    return r;
  }
  void unite(ll x,ll y){
    ll px=root(x);
    ll py=root(y);
    if(px!=py){
      par[px]=py;
      treesize[py]+=treesize[px];
      treesize[px]=0;
    }
  }
  bool parcheck(ll x,ll y){
    ll px=root(x);
    ll py=root(y);
    return px==py;
  }
  ll size(ll x){
    ll px=root(x);
    return treesize[px];
  }
};
int main(){
  while(1){
  ll i,j,N,M,ans=0,cnt=0;
  cin>>N>>M;
  if(N+M==0){
    return 0;
  }
  vec v(N+1),a((N+1)*(N+1));
  rep(i,N){
    cin>>v[i];
  }
  v[N]=0;
  rep(i,N+1){
    rep(j,N+1){
      if(v[i]+v[j]<=M){
        a[cnt++]=v[i]+v[j];
      }
    }
  }
  a.resize(cnt);
  i=0;j=cnt-1;
  vsort(a);
  while(i<=j){
    while(a[i]+a[j]<=M)i++;
    i--;
    ans=max(ans,a[i]+a[j]);
    i++;
    while(a[i]+a[j]>M)j--;
  }
  cout<<ans<<endl;
}}

C++: #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

typedef long long ll;

using namespace std;

int mato[1001],n,m,ans;

void dfs(int h,int sum,int j){
    
    ans=max(ans,sum);
    
    if(h==4) return;
    
    for(int i=j;i<n;i++)
        if(sum+mato[i]<=m)
            dfs(h+1,sum+mato[i],i);

    return;
}

void solve(){
    ans=0;
    
    for(int i=0;i<n;i++)
        scanf("%d",&mato[i]);
    
    sort(mato,mato+n);
    
    dfs(0,0,0);
    
    printf("%d\n",ans);
    
    return;
}

int main(){
    
    while(1){
        scanf("%d%d",&n,&m);
        if(n+m==0)
            break;
        solve();
    }
    
    return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
	while(true){
		int n,m;
		scanf("%d%d",&n,&m);
		if(n==0&&m==0)return 0;
		int p[1001];
		for(int i=0;i<n;i++)scanf("%d",&p[i]);
		p[n]=0;
		n++;
		sort(p,p+n);

		int ans=0;
		for(int i=0;i<n;i++){
			for(int j=0;j<=i;j++){
				for(int k=0;k<=j;k++){
					for(int l=0;l<=k;l++){
						if(p[i]+p[j]+p[k]+p[l]<=m)ans=max(ans,p[i]+p[j]+p[k]+p[l]);
						else break;
					}

				}
			}
		}

		printf("%d\n",ans);
	}
}

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();
      ans.clear();

      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 <iostream>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)

int main(void){
	while(1){
		int n, m; cin >> n >> m;
		if(n == 0 && m == 0) return 0;
		vector<int> p(n);
		rep(i, n) cin >> p[i];
		p.push_back(0);//??¢????????????????????\??????
		vector<int> pp((n + 1) * (n + 1));
		int cnt = 0;
		rep(i, n + 1)rep(j, n + 1){
			pp[cnt] = p[i] + p[j];
			cnt++;
		}
	
		sort(pp.begin(), pp.end());
		int ans = 0;
		//?¨???????(n^2*log(n*n))
		rep(i, (n + 1) * (n + 1)){
			int tmp = pp[i];
			int aim = m - tmp;
			if(aim < 0) continue;
			tmp += *(upper_bound(pp.begin(), pp.end(), aim) - 1);
			if(tmp <= m) ans = max(ans, tmp);
		}
		printf("%d\n", ans);
	}
	return 0;
}