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+j] = arr[i] + arr[j]
			}
		}
		sort.Slice(sums, func(i, j int) bool { return sums[i] < sums[j] })

		var m int64 = 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>

const int MOD = 1e9 + 7;
const int iINF = 1000000000;
const long long int llINF = 1000000000000000000;
const double PI = acos(-1.0);
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;
using ll = long long int;
using P = pair<int, int>;
using edge = struct
{
    int to;
    int cost;
};

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main()
{
    int N, M;
    while (cin >> N >> M && N)
    {
        vector<int> P(N + 1);
        P[0] = 0;
        rep(i, N) cin >> P[i + 1];

        vector<ll> candi;

        rep(i, N + 1)
        {
            for (int j = i + 1; j <= N; j++)
            {
                candi.push_back(P[i] + P[j]);
            }
        }


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

        ll ans = 0;

        rep(i, candi.size())
        {
            ll diff = M - candi[i];

            if (diff < 0)
                break;

            int l = 0, r = candi.size();

            while (r - l > 1)
            {
                int mid = (r + l) / 2;

                if (diff > candi[mid])
                    l = mid;
                else
                    r = mid;
            }

            ans = max(ans, candi[i] + candi[l]);
        }

        cout << ans << endl;
    }

    return 0;
}

C++: #include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
while(1){
int i,j,n,m,s=0,o=1;
static int p[1001]={0},up[1001*1001]={0};
scanf("%d%d",&n,&m);
if(n==0&&m==0)return 0;
up[0]=0;
for(i=1;i<=n;i++){
	scanf("%d",&p[i]);
	for(j=i;j>=0;j--){
		up[o]=p[i]+p[j];
		o++;
	}
}
sort(up,up+o);
for(i=0;i<o;i++){
for(j=i;up[i]+up[j]<m&&j<o;j++);
//printf("j=%d   up[i]=%d   up[j-1]=%d   up[j]=%d   m=%d\n",j,up[i],up[j-1],up[j],m);
if(up[i]+up[j-1]<=m)s=max(s,up[i]+up[j-1]);
}
printf("%d\n",s);
}
return 0;
}

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

using namespace std;

int binarySearch(vector<int> &array, int l, int r, int v)
{
    int mid = (l + r) / 2;
    if (l == mid)
        return array[mid];
    if (array[mid] == v)
        return array[mid];
    else if (array[mid] > v)
        return binarySearch(array, l, mid, v);
    else
        return binarySearch(array, mid, r, v);
}

int main()
{
    int N, M;
    while (1)
    {
        cin >> N >> M;
        if (N == 0 && M == 0)
            break;
        vector<int> array(N + 1);
        array[0] = 0;
        for (int i = 1; i < N + 1; i++)
        {
            cin >> array.at(i);
        }

        int n = ((N + 2) * (N + 1)) / 2;
        vector<int> darts(n);
        int index = 0;
        for (int i = 0; i < N + 1; i++)
        {
            for (int j = i; j < N + 1; j++)
            {
                darts[j - i + index] = array[i] + array[j];
            }
            index += N + 1 - i;
        }

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

        int sum = 0, max_sum = -1;
        for (int i = 0; i < n; i++)
        {
            sum = darts[i];
            if (sum < M + 1)
            {
                //cout << sum << " " << binarySearch(darts, 0, N, M - sum) << " " << M - sum << endl;
                sum += binarySearch(darts, 0, n, M - sum);
                max_sum = max(sum, max_sum);
            }
        }

        cout << max_sum << endl;
    }
}

C++: #include "bits/stdc++.h"
#define in std::cin
#define out std::cout
#define rep(i,N) for(LL i=0;i<N;++i)
typedef long long int LL;

LL N, M, P[1123];
std::set<LL>list;
LL ans;

int main()
{
	while (true)
	{
		N = M = 0;
		memset(P, 0, sizeof(P));
		list.clear();
		ans = 0;

		in >> N >> M;
		if (N == 0 && M == 0) { break; }
		rep(i, N) { in >> P[i]; }

		P[N] = 0;
		N++;
		std::sort(P, P + N);
		rep(i, N)
		{
			rep(j, N) { list.insert(P[i] + P[j]); }
		}
		for (auto i : list)
		{
			if (i > M) { continue; }
			auto iter = list.upper_bound(M - i);
			--iter;
			ans = std::max(ans, i + *iter);
		}

		out << ans << std::endl;
	}
	return 0;
}

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 solve( VI Q, INT M ) {
    INT answer = 0;
    int n = Q.size();
    for ( int i = 0; i < n; ++ i ) {
        int q = Q[i];
        int L = 0;
        int R = n;
        INT m = M - q;
        if ( q + Q[R-1] < answer ) continue;
        if ( q + Q[R-1] > M ) continue;
        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 - 1;
            } else {
                L = p + 1;
            }
        }
    }
    return answer;
}

int main() {
    int n, m;
    while ( cin >> n >> m ) {
        if ( n == 0 && m == 0 ) break;
        VI P;
        for ( int i = 0; i < n; ++ i ) {
            INT p;
            cin >> p;
            P.push_back( p );
        }
        P.push_back( 0 );
        VI Q;
        for ( int i = 0; i < n + 1; ++ i ) {
            for ( int j = 0; j < n + 1; ++ j ) {
                Q.push_back( P[i] + P[j] );
            }
        }
        sort( Q.begin(), Q.end() );
        unique( Q.begin(), Q.end() );
        cout << solve( Q, 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 dp[5][1005], n, m, p[1005];

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

  while (cin >> n >> m, n) {
    memset(dp, 0, sizeof(dp));
    for (int i = 0; i < n; ++i) {
      cin >> p[i];
    }

    int ans = 0;
    for (int i = 1; i <= 4; ++i) {
      for (int j = 0; j < n; ++j) {
        for (int k = 0; k < n; ++k) {
          int temp = dp[i - 1][k] + p[j];
          if (m < temp) temp = 0;
          dp[i][j] = max(dp[i][j], temp);
          ans = max(ans, dp[i][j]);
        }
      }
    }

    cout << ans << endl;
  }

  return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
  int n,m;
  while(cin>>n>>m,n){
    int p[n];
    for(int i=0;i<n;i++) cin>>p[i];
    set<int> s;
    s.insert(0);
    s.insert(m+1);
    for(int i=0;i<n;i++)
      s.insert(p[i]);
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
	s.insert(p[i]+p[j]);
    int ans=0;
    for(int x:s){
      if(x>m) continue;
      int y=*--s.upper_bound(m-x);
      //cout<<x<<" "<<y<<endl;
      assert(x+y<=m);
      ans=max(ans,x+y);
    }
    cout<<ans<<endl;
  }
  return 0;
}