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<iostream>
#include<vector>
#include<map>
#include<cassert>
#define MAX 200000010
using namespace std;























































































//???????????????????????????????????????????????
















//?????????????????


int main(){
  int N,M;
  vector<int> vec[5];
  map<int,bool> used;
  while(true){
  cin >> N >> M;
  if(N+M == 0)break;
  int val[N];
  for(int i=0;i<5;i++)vec[i].clear();
  used.clear();
  int mex = -1;
  int master = -1;
  
  for(int i=0;i<N;i++){
    cin >> val[i];
    used[val[i]] = true;
    mex = max(mex,val[i]);
    vec[1].push_back(val[i]);
  }
  master = mex;
  if(mex == M){
    cout << M << endl;
    continue;
  }
  bool fin = false;
  for(int i=2;i<=4;i++){       
     
      for(int j=0;j<vec[i-1].size();j++){
	if(vec[i-1][j]+master <= mex)continue;
	for(int k=0;k<N;k++){
	  if(val[k] >= M)continue;

	  if(used[vec[i-1][j]+val[k]])continue;
	  if(i == 4 && vec[i-1][j]+val[k] <= mex)continue;

	  used[vec[i-1][j]+val[k]] = true;
	  vec[i].push_back(vec[i-1][j]+val[k]);
	

	if(M >= vec[i-1][j]+val[k])mex = max(mex,vec[i-1][j]+val[k]);

	if(mex == M){
	  fin = true;
	  break;
	}
      }
      if(fin)break;
    }
    if(fin)break;
 
  }
  assert(mex != -1);
  cout << mex << endl;	
  }
  return 0;
}

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

using namespace std;

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

C++: #include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> mato;
vector<int> a;

int main(){
	int n,m;
	int self;
	while(scanf("%d %d",&n,&m) && n && m){
		mato.clear();
		a.clear();
		
		for(int i=0;i<n;i++){
			scanf("%d",&self);
			mato.push_back(self);
		}
		mato.push_back(0);
		sort(mato.begin(),mato.end());
		mato.erase(unique(mato.begin(),mato.end()),mato.end());
		int size = mato.size();
		for(int i=0;i<size;i++){
			for(int j=0;j<size;j++){
				a.push_back(mato[i] + mato[j]);
			}
		}
		sort(a.begin(),a.end());
		a.erase(unique(a.begin(),a.end()),a.end());
		int max = 0;
		size = a.size();
		int s,ss;
		for(int i=0;i<size;i++){
			s = m - a[i];
			if(s > 0){
				ss = *(lower_bound(a.begin(),a.end(),s) - 1);
				//printf("find:%d -> %d\n",s,ss);
				if(a[i] + ss > max){ max = a[i] + ss; }
			}
		}
		printf("%d\n",max);
	}
}

C++: #include<bits/stdc++.h>
using namespace std;
vector<long int> po;
long int n,a,b,m,lastans;
void solve(int dp,long int sum);

int main(){
    while(1){
        lastans=0;
        po.clear();

        cin >> n >> m;
        if(n==0&&m==0)break;
        for(int i=0;i<n;i++){
            cin >> a;
            po.push_back(a);
        }
        solve(0,0);
        cout << lastans << endl;
    }

    return 0;
}

void solve(int dp,long int sum){
    int ans=0;
    if(dp==n)return ;
    else{
     for(int i=0;i<n;i++){
        if(sum+po[i]<m){
            lastans=max(lastans,sum+po[i]);
            solve(dp+1,sum+po[i]);
            }
        }
    }
    return;
}

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

int n, m;
int p[1000];
int s;
vector<int> a;
vector<int> b;

void f(int x){
	if(x <= m) s = max(s, x);
}

int main(){
	while(1){
		scanf("%d %d", &n, &m);
		if(n == 0 && m == 0) break;
		memset(p, 0, sizeof(p));
		for(int i=0; i<n; i++) scanf("%d", &p[i]);
		a = b;
		s = 0;

		for(int i=0; i<n; i++){
			f(p[i]);
		}
		for(int i=0; i<n; i++){
			for(int j=i; j<=i; j++){
				a.push_back(p[i] + p[j]);
				f(p[i] + p[j]);
			}
		}
		for(int i=0; i<n; i++){
			for(int j=0; j<a.size(); j++){
				f(p[i] + a[j]);
			}
		}
		for(int i=0; i<a.size(); i++){
			for(int j=0; j<a.size(); j++){
				f(a[i] + a[j]);
			}
		}
		printf("%d\n", s);

	}
	return 0;
}

C++: #include<iostream>
#include<vector>
using namespace std;
typedef unsigned int uint;
uint maxv;
void solve(uint now,uint m,uint *a,int n){
  int r=n-1,l=0,mid;
  while(l <=r){
    mid = (l+r)/2;
    if ( a[mid]+now>m)r=mid-1;
    else if ( a[mid]+now <=m){
      if ( a[mid]+now >maxv)maxv=a[mid]+now;
      l=mid+1;
    }
    //else break;
  }
  if ( now+a[mid]>maxv&& now+a[mid]<=m)maxv=now+a[mid];
}


main(){
  int n;
  uint m;
  while(scanf("%d%u",&n,&m) && n){
    uint one[n];
    uint two[n*n];
    int p=0;
    maxv=0;
    for(int i=0;i<n;i++)scanf("%u",&one[i]);
    for(int i=0;i<n;i++){
      if ( one[i]>maxv &&one[i] <=m)maxv=one[i];
      for(int j=i;j<n;j++){
	if ( one[i]+one[j]>m)continue;
	two[p++]=one[i]+one[j];
	if (two[p-1]>maxv)maxv=two[p-1];
      }
    }
    sort(one,one+n);
    sort(two,two+p);
    for(int i=0;i<p;i++){
      if ( two[i]+one[0]>m)break;
      if ( two[i]+two[0]<=m)solve(two[i],m,two,p);
      if ( two[i]+one[0]<=m)solve(two[i],m,one,n);
    }
    printf("%u\n",maxv);
  }
  return false;
}

C++: #include<iostream>
#include<iomanip>
#include<algorithm>
#include<array>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<numeric>
#include<set>
#include<stack>
#include<string>
#include<sstream>
#include<unordered_map>
#include<queue>
#include<vector>
using namespace std;

//#define int long long
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(a) (a).begin(),(a).end()
#define dump(o) if(DEBUG){cerr<<#o<<" "<<o<<endl;}
#define dumpc(o) if(DEBUG){cerr<<#o; for(auto &e:(o))cerr<<" "<<e;cerr<<endl;}
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
const int MOD = 1e9 + 7;
const bool DEBUG = false;

signed main() {
	int P[1010] = {};
	static int a[1000010] = {}; //1000010
	for (int N, M; cin >> N >> M&&N;) {
		memset(a, 0x3f, sizeof(a));
		rep(i, 0, N)cin >> P[i];
		P[N] = 0;
		N++;
		rep(i, 0, N)rep(j, 0, N) {
			a[i*N + j] = P[i] + P[j];
		}
		dumpc(a);
		sort(a, a + N*N);
		dumpc(a);
		int ans = 0;
		rep(i, 0, N*N) {
			if (a[i] > M)break;
			int add = a[upper_bound(a, a + N*N, M - a[i]) - a - 1];
			ans = max(ans, a[i] + add);
		}
		cout << ans << endl;
	}
	return 0;
}