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 <sstream>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef long long INT;
typedef vector <INT> VI;
typedef set <INT> SI;

INT P[1001];
INT Q[1002001];

INT solve( int N, INT M ) {
    INT answer = 0;
    int n = N;
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        while ( L < R ) {
            int p = ( R - L ) / 2 + L;
            INT t = q + Q[p];
            if ( t > M ) t = 0;
            answer = max( answer, t );
            if ( Q[p] > m ) {
                R = p;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P[i] = p;
        }
        P[n] = 0;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q[i * ( n + 1 ) + j] = P[i] + P[j];
            }
        }
        int length = ( n + 1 ) * ( n + 1 );
        sort( Q, Q + length );
        cout << solve( ( n + 1 ) * ( n + 1 ), m ) << endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define PB push_back
#define PPB pop_back
typedef pair<int, int> pii;
static const int INF = 1LL<<61;

int gedo[1000 * 1005], p[1005], n, m;

inline void cut(int *k) {
  if (m < *k) *k = 0;
}

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

  while (cin >> n >> m, n) {
    fill((int*)gedo, (int*)gedo + 1000 * 1005, INF);
    for (int i = 0; i < n; ++i) {
      cin >> p[i];
    }

    for (int i = 0; i < n; ++i) {
      for (int j = i; j < n; ++j) {
        int temp = p[i] + p[j];
        cut(&temp);
        gedo[i * j] = temp;
      }

      int t = p[i];
      cut(&t);
      gedo[i * n] = t;
    }
    sort(gedo, gedo + n * n);

    int ans = 0;
    for (int i = 0; i < n; ++i) {
      for (int j = i; j < n; ++j) {
        int l = 0, r = n * n, cur = gedo[i * j];

        while (1 <= r - l) {
          int k = (r + l) / 2, temp1 = cur + gedo[k + 1], temp2 = cur + gedo[k];
          cut(&temp1);
          cut(&temp2);
          ans = max(ans, temp2);

          if (temp2 != 0 && temp1 == 0) {
            break;
          }

          if (temp2 == 0) {
            r = k;
          } else {
            l = k + 1;
          }
        }
      }
    }

    cout << ans << endl;
  }

  return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit
#include <cstdio>	// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()
#define DEBUG 0

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
string FILE_NAME = "testcase.dart";
string NAME;
string itos (int n )
{
	stringstream ss;
	ss << n;

	return ss.str();
}

/*
	解法３ O(n^2log(n))
	
	3本の矢を投げて、残りの矢を２分探索する
*/
int n, m, k;
int p[1005];
int s[1005*1005];

bool query (int c, int sum )
{
	return (sum + s[c] <= m );
}

int solve (int sum )
{
	int L = 0;
	int R = k;
	while( R-L > 1 ){
		int C = (L+R)/2;
		(query(C, sum ) ? L : R ) = C;
	} // end while

	return sum + s[L]; 
}
int main()
{
//	cut here before submit 
#if DEBUG
	NAME = FILE_NAME;
	int CNT = 1;
	NAME += itos (CNT );
	while (freopen (NAME.c_str() , "r", stdin ) != NULL ) {
#endif
	while (scanf ("%d %d", &n, &m ), n, m ){
		memset (p, 0, sizeof (p ) );
		memset (s, 0, sizeof (s ) );
		for (int i = 1; i <= n; i++ )	scanf ("%d", &p[i] );
		sort (p, p+n+1 );
		k = 0;
		for (int a = 0; a <= n; a++ ){
			for (int b = 0; b <= n; b++ ){
				if (p[a] + p[b] > m ) continue;
				s[k++] = p[a] + p[b];
			} // end for
		} // end for

		sort (s, s+k );

		int res = 0;
		rep (i, k ){
			int curr = solve (s[i] );	
			res = max (res, curr );
		} // end rep

		printf ("%d\n", res );
	} // end while
#if DEBUG
	CNT++;	// cut here before submit
	NAME = FILE_NAME;
	NAME += itos (CNT );
	} // end loop; cut here before submit
#endif			
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> a;
vector <int> all;
int n,m;

int bainary_search(int i) {
  int L=0;int R = all.size()-1,M;
  
  while(L<R) {
    M = (L+R)/2;
    if(all[i]+all[M] <= m) L = M+1;
    else R = M;
  }

  if(L != 0) L--;
  return L;
}

int main() {

  while(1) {
    cin >> n >> m;
    if(n == 0 && m == 0) break;
    a.resize(n);
    for(int i=0;i<n;i++) cin >>a[i];
    a.push_back(0);
    all.clear();
    for(int i=0;i<=n;i++)
      for(int j=i;j<=n;j++)
	all.push_back(a[i]+a[j]);

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

    int allsize = all.size();
    int ans = 0;
    for(int i=0;i<allsize;i++) {
      int res = all[i] + all[bainary_search(i)];
      if(ans < res && res <= m) ans = res;
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
	int a,b,mato[1000];
	vector<int> nums;
	while(scanf("%d%d",&a,&b),a,b){
		int res=0;
		nums.clear();
		for(int i=0;i<a;i++)scanf("%d",mato+i);
		for(int i=0;i<=a;i++)
			for(int j=0;j<=a;j++)
				nums.push_back(mato[i]*!!(i-a)+mato[j]*!!(j-a));
				
		sort(nums.begin(),nums.end());
		vector<int>::iterator it=nums.begin();
		while(it!=nums.end() && b>=*it){
			vector<int>::iterator itt=upper_bound(nums.begin(),nums.end(),b-*it);
			res=max(res,*it+++*--itt);
		}
		printf("%d\n",res);
	}
	return 0;
}