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*len(arr)+j] = arr[i] + arr[j]
			}
		}

		sort.Slice(sums, func(i, j int) bool { return sums[i] < sums[j] })
		var m int64 = 0
		for _, val := range sums {
			rem := M - val
			if rem >= 0 {
				index := sort.Search(len(sums), func(i int) bool { return sums[i] > rem }) - 1
				if index >= 0 {
					m = max(m, val+sums[index])
				}
			}
		}
		fmt.Println(m)
	}
}

C++: #include <algorithm>
#include <climits>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

int main(){
    int N, M;
    while (cin >> N >> M, N) {
        vector<long long> P(N);
        for (int i=0; i<N; ++i) {
            cin >> P[i];
        }

        vector<long long> score_half(1, 0);
        for (int i=0; i<N; ++i) {
            score_half.push_back(P[i]);
            for (int j=0; j<N; ++j) {
                score_half.push_back(P[i] + P[j]);
            }
        }
        sort(score_half.begin(), score_half.end());

        long long res = 0;
        for (int i=0; i<(int)score_half.size(); ++i) {
            auto it = upper_bound(score_half.begin(), score_half.end(), M - score_half[i]);
            if (it != score_half.begin()) {
                res = max(res, score_half[i] + *(it-1));
            }
        }
        cout << res << endl;
    }

    return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
bool ok(int *q,int m,int h,int count){
  for(int i=0;i<count;i++){
    if(q[i]>m) continue;
    for(int j=0;j<count;j++){
      if(q[i]+q[j]<=m&&q[i]+q[j]>h) return true;
    }
  }
  return false;
}
int main(){
  int n,m;
  while(cin>>n>>m){
    if(n==0&&m==0) return 0;
    int data[n+1];
    int q[(n+1)*(n+1)];
    for(int i=0;i<n;i++) cin >> data[i];
    data[n] = 0;
    int count = 0;
    for(int i=0;i<=n;i++){
      for(int j=0;j<=n;j++){
	q[count] = data[i] + data[j];
	count++;
      }
    }
    sort(q,q+count,greater<int>());
    int min=0,max=m;
    while(min!=max){
      int h = (min+max)/2;
      if(ok(q,m,h,count)) min = h+1;
      else max = h;
    }
    cout << max << endl;
  }
}

C++: #include<iostream>
#include<set>
#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)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){
    set<uint> S;    
    uint one[n];
    uint two[n*n];
    int p=0;
    maxv=0;
    for(int i=0;i<n;i++)scanf("%d",&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++){
	two[p++]=one[i]+one[j];
	if (two[p-1]>maxv&&two[p-1]<=m)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<bits/stdc++.h>
using namespace std;
vector<long int> po;
vector <pair <int ,long int> > sss;
long int n,a,low,m,lastans,memo[1005];
void solve(int dp,long int sum);

int main(){
    while(1){
        lastans=0;
        po.clear();
        //for(int i=0;i<1005;i++)memo[i]=0;

        cin >> n >> m;
        if(n==0&&m==0)break;
        for(int i=0;i<n;i++){
            cin >> a;
            po.push_back(a);
           // low=min(low,a);
        }
        sort(po.begin(),po.end());
        //cout << po[0] << endl;
        //solve(0,0);
        //lastans=po[n-1];

        for(int i=4;i>0;i--){
            for(int j=n-1;j>=0;j--){
                if(m>=i*po[j]){
                    lastans=max(i*po[j],lastans);

                    for(int k=4-i;i>0;i--){
                        for(int s=0;s<n;s++){
                            if(m>=i*po[j]+po[s]){
                                lastans=max(i*po[j]+po[s],lastans);

                                for(int t=4-k;t>0;t--){
                                    for(int u=0;u<n;u++){
                                        if(m>=i*po[j]+po[s]+po[u]){
                                         lastans=max(i*po[j]+po[s]+po[u],lastans);

                                         for(int v=4-t;v>0;v--){
                                            for(int w=u-1;w>=0;w--){
                                                if(m>=i*po[j]+po[s]+po[u]+po[w]){
                                                    lastans=max(lastans,i*po[j]+po[s]+po[u]+po[w]);

                                                }else break;
                                            }
                                         }

                                        }else break;
                                    }
                                }

                            }else break;

                        }
                    }

                    lastans=max(lastans,po[j]*i);
                    break;
                }else break;
            }
        }



        cout << lastans << endl;
        //cout <<"ss=" << ss << endl;
    }

    return 0;
}

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

using namespace std;

int main ( void )
{
	int n, m;
	int p[1000];
	set<int> S;
	
	while ( cin >> n >> m, (n | m) )
	{
		int ans = 0;
		S.clear();
		for ( int i = 0; i < n; ++i )
        {
            cin >> p[i];
            if ( p[i] < m )
            {
                S.insert(p[i]);
                ans = max( ans, p[i] );
            }
        }
        for ( int i = 0; i < n; ++i )
        {
            for ( int j = i; j < n; ++j )
            {
                int x = p[i] + p[j];
                if ( x <= m )
                {
                    S.insert(x);
                    ans = max( ans, x );
                    int y = m - x;
                    set<int>::iterator it = lower_bound( S.begin(), S.end(), y );
                    if ( *it > y )	--it;
                    ans = max( ans, (x + *it) );
                }
            }
        }
		cout << ans << endl;
	}
	
	return 0;
}

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

int P[1000], mem[1000 * 1000], N, M;
int main()
{
loop:
  cin >> N >> M;
  if(!N)
    return 0;
  N++;
  P[0] = 0;
  for(int i = 1; i < N; i++)
    cin >> P[i];
  for(int i = 0; i < N; i++)
    for(int j = 0; j < N; j++)
      mem[N * i + j] = P[i] + P[j];
  sort(mem, mem + N * N);

  int ans = 0;
  for(int i = 0; i < N * N; i++)
  {
    if(mem[i] > M)
      continue;
    ans = max(ans, mem[i] + *(upper_bound(mem, mem + N * N, M - mem[i]) - 1));
  }
  cout << ans << endl;
  goto loop;
}