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 <cstdio>
#include <algorithm>
#pragma warning(disable : 4996)
using namespace std;
int n, m, c[1009], s[510009], t[510009], cnt[32777], sum[32777];
int main() {
	while (scanf("%d%d", &n, &m), n) {
		for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
		sort(c, c + n);
		int b = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = i; j <= n && c[i] + c[j] <= m; j++) {
				s[b++] = c[i] + c[j];
			}
		}
		for (int i = 0; i < 30; i += 15) {
			fill(cnt, cnt + 32768, 0); sum[0] = 0;
			for (int j = 0; j < b; j++) cnt[(s[j] >> i) & 32768]++;
			for (int j = 0; j < 32768; j++) sum[j + 1] = sum[j] + cnt[j];
			for (int j = 0; j < b; j++) t[sum[(s[j] >> i) & 32768]++] = s[j];
			for (int j = 0; j < b; j++) s[j] = t[j];
		}
		int r = b - 1, ret = 0;
		for (int i = 0; i < b && i <= r; i++) {
			while (r > 0 && s[i] + s[r] > m) r--;
			ret = max(ret, s[i] + s[r]);
		}
		printf("%d\n", ret);
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i, s, n) for(int i = s; i < (int)n; ++i)
#define per(i, n) for(int i = n; i >= 0; i--)
#define ROF(i, s, n) for(int i = s; i >= (int)n; i--)
#define FORIT(i, A) for (auto i : A)
#define PRINT(x) cout << (x) << "\n"
#define SCAN(x) cin >> x
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define MP make_pair
#define PB push_back
#define EACH(i, n) for (__typeof((n).begin()) i = (n).begin(); i != (n).end(); ++i)
#define SZ(a) int((a).size())
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define CLR(a) memset((a), 0 ,sizeof(a))
#define NCLR(a) memset((a), -1 ,sizeof(a))
#define sq(n) (n) * (n)
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef complex<long double> P;
typedef long long LL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef priority_queue<int> maxpq;
typedef priority_queue< int, vector<int>, greater<int> > minpq;
typedef complex<double> Point;
static const double EPS = 1e-10;
static const double PI = acos( -1.0 );
static const int mod = 1000000007;
static const int INF = 1 << 29;
static const LL LL_INF = 1ll << 60;
static const int dx[] = { -1, 0, 1, 0, 1, -1, 1, -1 };
static const int dy[] = { 0, -1, 0, 1, 1, 1, -1, -1 };

#ifdef WIN32
#define dump(x) cerr << #x << " = " << (x) << "\n"
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << "\n"
#else
#define dump(x)
#define debug(x)
#endif

template<class T> ostream &operator<<( ostream &os, vector<T> &v ) {
  for ( int i = 0; i < v.size(); i++ ) {
    if ( i ) os << " ";
    os << v[ i ];
  }
  return os;
}

int main() {
  ios::sync_with_stdio( false );
  cin.tie( 0 );
  int n, m;
  while ( cin >> n >> m && n && m ) {
    VI p( n );
    for ( int i = 0; i < n; i++ ) {
      cin >> p[ i ];
    }
    p.push_back( 0 );
    SORT( p );
    set<int> two_selected;
    for ( int i = 0; i < n + 1; i++ ) {
      for ( int j = 0; j < n + 1; j++ ) {
        two_selected.insert( p[ i ] + p[ j ] );
      }
    }
    int ans = 0;
    for ( set<int>::iterator it = two_selected.begin(); it != two_selected.end(); ++it ) {
      set<int>::iterator it2 = two_selected.upper_bound( m - *it );
      if ( it2 != two_selected.begin() ) {
        --it2;
        ans = max( ans, *it + *it2 );
      }
    }
    PRINT( ans );
  }
  return 0;
}

C++: #include <iostream>

#include <algorithm>



constexpr int MAX_N=1001;



int n,m;

int P[MAX_N];



int Data[MAX_N*MAX_N];



int main() {
    while(1){
    std::cin>>n>>m;
    if(n+m==0)
    	break;

    for(int i=1;i<=n;++i)

        std::cin>>P[i];

    for(int i=0;i<=n;++i){

		for(int j=0;j<=n;++j)

	    	Data[i*(n+1)+j]=-(P[i]+P[j]);

    }

    std::sort(Data,Data+(n+1)*(n+1));

    int ans=0;

    for(int i=0;i<=n;++i){

		for(int j=0;j<=n;++j){

	   		int x=P[i]+P[j]-m;

	    	int* v=std::lower_bound(Data,Data+(n+1)*(n+1),x);

	    	if(v!=Data+(n+1)*(n+1))

				ans=std::max(ans,P[i]+P[j]-(*v));

		}

    }

    std::cout<<ans<<std::endl;
    }

    return 0;

}

C++: #include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second

typedef pair<int, int> P;

map<int, bool> f;
priority_queue<P> q;
int a[1010];

int main()
{
  int n, m;
  while (cin >> n >> m, n){

    for (int i = 0; i < n; i++){
      cin >> a[i];
    }

    sort(a, a + n);
    
    for (int i = n - 1; i >= 0; i--){
      q.push(pair<int, int>(a[i], 1));
    }

    f.clear();
    int maxs = 0;
    while (!q.empty()){
      P s = q.top(); q.pop();

      maxs = max(s.fi, maxs);

      if (s.second == 4) continue;
      for (int i = n - 1; i >= 0; i--){
        if (s.fi + a[i] > m) continue;
        if (f[s.fi + a[i]]) continue;

        q.push(P(s.fi + a[i], s.se + 1));
        f[s.fi + a[i]] = true;
      }
    }

    cout << maxs << endl;
  }
}

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

int N,M,P[1001];
set<int> s;

int main(){
	while(scanf("%d%d",&N,&M), N != 0){
		s = set<int>();
		s.insert(0);
		for(int i = 0; i < N; i++){
			scanf("%d",&P[i]);
			s.insert(P[i]);
		}
		
		for(int i = 0; i < N; i++){
			for(int j = i; j < N; j++){
				s.insert(P[i] + P[j]);
			}
		}

		int mx = 0;
		
		for(set<int>::iterator itr = s.begin(); itr != s.end(); itr++){
			set<int>::iterator tmp = lower_bound(s.begin(),s.end(),M-*itr);
			if(*itr + *tmp > M){
				if(tmp != s.begin()){
					tmp--;
				}
				else{
					continue;
				}
			}
			if(mx < *itr + *tmp){
				mx = *itr + *tmp;
			}
		}

		printf("%d\n",mx);
	}
	return 0;
}

C++: #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int main(void){
  int n, m;
  int p[1024];
  vector<long long> v;
  for( ; ; ){
    scanf("%d %d", &n, &m);
    if(!(n + m)) break;
    for(int i = 0;i < n; i++) scanf("%d", p + i);
    v.clear();
    p[n++] = 0;
    for(int i = 0;i < n; i++)
      for(int j = i;j < n; j++)
	v.push_back(p[i] + p[j]);
    sort(v.begin(), v.end());
    long long ans = 0;
    for(int i = 0;i < v.size(); i++){
      if(v[i] > m) break;
      vector<long long>::iterator it = upper_bound(v.begin(), v.end(), m - v[i]);
      ans = max(ans, v[i] + *(it - 1));
    }
    printf("%d\n", ans);
  }
}