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 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>
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;
}

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

int A[2000];
int KK[2000000];
int N,M;
int k;
void getK()
{
	k = 0;
	for(int i =0; i<=N; i++)
		for(int j = i; j<=N; j++)
			KK[k++] = A[i]+A[j];	
	
	sort(KK,KK+k);		

}


int binarySearch(int a)
{
	int left = 0;
	int right = k;
	int mid;
	while(left+1<right)
	{
		mid = (left+right)/2;
		if(KK[mid] <= a) left = mid;
		else right = mid;
	}

	return KK[left];
}
void solve()
{
	
	int maxS = 0;
	for(int i =0; i<=N;i++)
		for(int j = 0; j <=N; j++)
		{
			int temp = binarySearch(M-A[i]-A[j])+A[i]+A[j];	
			if(temp > maxS && temp <= M)
				maxS = temp;
		}
	cout << maxS << endl;
}

int main()
{
	A[0] = 0;
	while(cin >>N>>M && N||M)
	{
		
		for(int i = 1; i<=N;i++)
			cin >> A[i];
		sort(A,A+N+1);
		getK();
		solve();
	}
}

C++: #include<bits/stdc++.h>
using ll = long long;
using namespace std;
const ll INF = 1000000000000000000;
const ll mod = 1000000007;
ll ok[12345678];
signed main() {
	for (int z = 0; z < 11; z++) {
		ll n, m, a, ans = 0; cin >> n >> m;
		if (n == 0 && m == 0) { return 0; }
		for (int h = 0; h < n; h++) {
			cin >> ok[h];
		}
		vector<ll> v;
		//最後の二本
		for (int h = 0; h <= n; h++) {
			for (int i = 0; i <= n; i++) {
				v.push_back(ok[h] + ok[i]);
			}
		}
		sort(v.begin(), v.end());
		//最初の二本+最後の二本の二分探索
		for (int h = 0; h <= n; h++) {
			for (int i = 0; i <= n; i++) {
				ll sum = ok[h] + ok[i];
				if (sum > m) { continue; }
				ll ng = lower_bound(v.begin(), v.end(), m - sum) - v.begin();
				if (ng == 0) { continue; }
				ans = max(ans, sum + v[ng - 1]);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

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

int main(){
  long n,m,p[1001];
  while(cin>>n>>m,n||m){
    for(int i=1;i<=n;++i) cin>>p[i];
    p[0]=0;
    vector<long> s(0);
    for(int i=0;i<=n;++i){
      for(int j=0;j<=n;++j) s.push_back(p[i]+p[j]);
    }
    sort(s.begin(),s.end());
    long a=0;
    for(vector<long>::iterator it=s.begin();*it>m/2;++it){
      a=max(a,*it+*(upper_bound(s.begin(),s.end(),m-*it)-1));
    }
    cout<<a<<endl;
  }
  return 0;
}

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

int solve(vector<int>, int);
int main(){
  int n, points;
  vector<int> ans;
  while(cin>>n>>points, n!=0 && points!=0){
    vector<int> darts;
    darts.push_back(0);//投げない場合を含めておく
    for(int i=0; i<n; i++){
      int temp; cin >> temp;
      darts.push_back(temp);
    }
    ans.push_back(solve(darts, points));
  }

  for(int i=0; i<ans.size(); i++){
    cout << ans[i] << endl;
  }

  return 0;
}

int solve(vector<int> darts, int point){
  vector<int> temp;
  //2本投げ終わった後の合計点数を探索
  for(int i=0; i<darts.size(); i++){
    for(int j=0; j<darts.size(); j++){
      temp.push_back(darts[i]+darts[j]);
      sort(temp.begin(), temp.end());
    }
  }

  int ans=0;
  for(int i=0; i<darts.size()*darts.size(); i++){
    int aim = point-temp[i];
    int last = *(upper_bound(temp.begin(), temp.end(), aim)-1);
    if(temp[i]+last<=point) ans=max(ans, temp[i]+last);
  }

  return ans;
}