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

Python: from bisect import bisect_right

while True:
    n, m = map(int, input().split())
    if not n:
        break

    ps = [0] + sorted(int(input()) for _ in range(n))

    p2 = set()
    for i, pi in enumerate(ps):
        for pj in ps[i:]:
            if pi + pj > m:
                break
            p2.add(pi + pj)

    p2 = sorted(p2)

    max_s = 0
    for pi in p2:
        j = bisect_right(p2, m - pi)
        s = pi + p2[j - 1]
        if max_s < s:
            max_s = s
    print(max_s)

Python: from bisect import bisect_left as bl
while 1:
    n,m=map(int,input().split())
    if n==0 and m==0:
        break
    s=[int(input())for i in range(n)]
    a=set()
    a.add(0)
    for i in range(n):
        a.add(s[i])
        for j in range(i,n):
            a.add(s[i]+s[j])
    a=sorted(list(a))
    s=0
    for i in a:
        if i<m:
            s=max(s,i+a[bl(a,m-i)-1])
    print(s)

Python: while True:
    n,m = map(int, input().split())
    if(n|m)==0: break

    onelist = [0]
    for i in range(n):
        onelist.append(int(input()))

    twolist = set()
    for no in range(n+1):
        for no2 in range(no,n+1):
            twolist.add(onelist[no]+onelist[no2])
    twolist = sorted(twolist)

    ans = 0
    l = len(twolist)
    for no in twolist:
        for no2 in twolist:
            if no+no2 <= m:
                ans = max(ans,no+no2)

    print(ans)

Python: from bisect import bisect_right

while True:
    N, M = [int(x) for x in input().split()]
    if N == 0 and M == 0:
        break

    _P = [0] * N

    for i in range(N):
        _P[i] = int(input())
    _P.append(0)

    P = list(set(x + y for x in _P for y in _P))
    P.sort()

    ans = 0

    for p in P:
        if p > M // 2:
            break
        i = bisect_right(P, M - p)
        ans = max(ans, p + P[i - 1])

    print(ans)

Python: def solve():
  while True:
    n,m = map(int,input().split())
    if not n and not m: break
    lst = []
    lst2 = []
    for i in range(n):
      lst.append(int(input()))
    for i in lst:
      for j in lst:
        lst2.append(i + j)
    lst2 = list(set(lst2 + lst))
    lst2.sort()
    ans = 0
    def binary(x, left, right):
      center = (left + right) // 2
      length = right - left + 1
      if length <= 0:
        return -100
      elif length == 1:
        if lst2[center] > x:
          return center - 1
        else:
          return center
      elif length == 2:
        if lst2[center] > x:
          return center - 1
        else:
          return center
      elif lst2[center] == x: return x
      elif lst2[center] < x: return binary(x, center, right)
      elif lst2[center] > x: return binary(x, left, center)
      
    for i in lst2:
      if i <= m:
        ans = max(ans, i + lst2[binary(m - i, 0, len(lst2) - 1)])
      else:
        break
    print(ans)
solve()

Python: import bisect
def main():
	while True:
		n,m=map(int,input().split())
		if n==0 and m==0:
			break
		p=[0]+sorted([int(input()) for i in range(n)])
		s=list()
		for i in range(n+1):
			for j in p[i:]:
				if p[i]+j>m:
					break
				s+=[p[i]+j]
		s.sort()
		print(max(i+s[bisect.bisect_right(s,m-i)-1] for i in s))

if __name__=="__main__":
	main()

Python: import bisect

while 1:
    n,m=map(int,raw_input().split())
    if n==m==0:break
    p=[0]+[int(raw_input()) for _ in xrange(n)]
    com=[0]*((n+1)**2)
    for i in xrange(n+1):
        for j in xrange(n+1):
            com[(n+1)*i+j]=p[i]+p[j]
    com.sort()
    ans=0
    for i in xrange(n+1):
        for j in xrange(n+1):
            if m-com[(n+1)*i+j]<0:continue
            index=bisect.bisect_left(com,m-com[(n+1)*i+j])
            if index==len(com):continue
            if com[index]>m-com[(n+1)*i+j]:
                if index==0:continue
                else:
                    index-=1
            ans=max(ans,com[(n+1)*i+j]+com[index])
    print(ans)

Python: import bisect
def main():
    while True:
        n, m = map(int, input().split())
        if n == 0:
            break
        p = list(int(input()) for i in range(n))
        point = [] + p
        for i in p:
            for j in p:
                a = i + j
                if a <= m and a not in point:
                    point.append(a)
        point.sort()
        maxp = 0
        for i in point:
            if m - i in point:
                print(m)
                break
            pp = i + point[bisect.bisect_left(point, m - i) - 1]
            if pp > maxp:
                maxp = pp
        else:
            print(maxp)
            
if __name__=="__main__":
	main()

Python: from itertools import product
from bisect import bisect_left

def main():
    while True:
        N, M = map(int, input().split())
        if N == M == 0:
            break
        p = [int(input()) for _ in range(N)]
        p.append(0)
        points = []
        for i in range(N + 1):
            for j in range(i, N + 1):
                points.append(p[i] + p[j])
        points.sort()
        ans = 0
        for i in range(len(points)):
            index = bisect_left(points, M - points[i])
            if index != 0:
                ans = max(ans, points[i] + points[index - 1])
        print(ans)


if __name__ == '__main__':
    main()

Python: import bisect
# python template for atcoder1
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline


def solve():
    N, M = map(int, input().split())
    if N*M == 0:
        return False
    P = [0]+[int(input()) for _ in range(N)]
    # solve
    k = [P[i]+P[j] for i in range(N) for j in range(i, N)]
    k = sorted(k)

    ret = 0
    for tmp in k:
        if tmp > M:
            break
        else:
            r = M-tmp
            l = bisect.bisect_right(k, r)
            tmp += k[l-1]
            ret = max(ret, tmp)
    return ret


ans = []
while True:
    ret = solve()
    if ret:
        ans.append(ret)
    else:
        break
print("\n".join(map(str, ans)))

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

inline long long f(long long M, long long s)
{
  return s > M ? 0LL : s;
}


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

    vector<vector<long long> > dp(N, vector<long long>(5, 0));
    for (int j = 0; j < 5; j++) {
      dp[0][j] = f(M, ps[0]*j);
    }

    for (int i = 1; i < N; i++) {
      for (int j = 0; j < 5; j++) {
        for (int k = 0; k <= j; k++) {
          if (k == 0 || dp[i-1][k] != 0) {
            dp[i][j] = max(dp[i][j], f(M, dp[i-1][k] + ps[i]*(j-k)));
          }
        }
      }
    }
    long long ans = 0;
    for (int j = 0; j < 5; j++) {
      ans = max(ans, dp[N-1][j]);
    }
    cout << ans << endl;
  }
  return 0;
}