Problem:
Handing out Balloons
Each time an ICPC participant team has successfully solved a
problem at the competition site, a balloon of a color specific to that
problem is delivered to that team.  You had thus prepared enough
number of balloons of various colors for the case when all the teams solved
all the
problems, but many problems have been solved by few teams.
You thus decided to give away the remaining balloons
to the kids in the neighborhood.
You are preparing poles, each tied down with one or more
balloons of the same color.  You are lining up these poles from left
to right.  Whenever a kid comes up, you give three balloons of
different colors to the kid picking up one from each of the three
leftmost poles.  Poles that run out of the balloons are removed, and
when the poles remaining are two or less, you finish giving balloons away.
The number of kids you can give the balloons depends on the order of the
poles.  Find the maximum possible number of kids you can give the balloons
by arranging the order of poles appropriately.
The figure on the right depicts the consequences of different
arrangements of five poles with 1, 2, 3, 4 and 5 balloons.
When poles are lined up in the order of 1, 2, 3, 4 and 5 balloons,
you can give to only three kids; when they are in the
order of 5, 4, 3, 2 and 1 balloons, you can give to five kids.
Input
The input consists of multiple datasets, each in the following format.
n
b
1
b
2
…
b
n
n
is the number of poles.
n
is an integer between 3 and 50, inclusive.
b
1
through
b
n
are the numbers of the balloons on the poles.
Each
b
i
is a positive integer not exceeding 50.
The end of the input is indicated by a line containing a zero.
The number of datasets does not exceed 50.
Output
For each dataset, output a single line containing the maximum number of
kids you can give the balloons to.
Sample Input
5
1 2 3 4 5
9
1 3 3 3 3 3 3 4 4
4
5 2 8 3
0
Output for the Sample Input
5
9
5

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using B = bitset<2501>;

void solve(int n) {
    vector<int> a(n);
    int sm = 0;
    for (auto &i: a) {
        cin >> i;
        sm += i;
    }
    vector<B> dp(2501);
    dp[0][0] = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 2500; j >= 0; j--) {
            if (j + a[i] <= 2500)
                dp[j + a[i]] |= dp[j];
            dp[j] |= dp[j] << a[i];
        }
    }
    int ans = 0;
    for (int i = 0; i <= sm; i++) {
        for (int j = 0; j <= sm; j++) {
            if (dp[i][j]) {
                ans = max(ans, min(i, min(j, sm - i - j)));
            }
        }
    }
    cout << ans << "\n";
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 260
memory_kb: 4160
final_rank: 2

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

using ll = long long;

template <typename T>
bool chmin(T &x, T y) {
    return x > y ? x = y, true : false;
}

template <typename T>
bool chmax(T &x, T y) {
    return x < y ? x = y, true : false;
}



bool solve() {
    int N;
    cin >> N;
    if (N == 0) return false;
    const int M = 2500;
    vector<vector<bool>> dp(M + 1, vector<bool>(M + 1, false));
    dp[0][0] = true;
    int sum = 0;
    while (N--) {
        int a;
        cin >> a;
        sum += a;
        for (int i = M; i >= 0; i--) {
            for (int j = M; j >= 0; j--) {
                if (dp[i][j]) {
                    if (i + a <= M) dp[i + a][j] = true;
                    if (j + a <= M) dp[i][j + a] = true;
                }
            }
        }
    }
    int ans = 0;
    for (int a = 0; a <= M; a++) {
        for (int b = 0; b <= M; b++) {
            if (dp[a][b]) {
                ans = max(ans, min({a, b, sum - a - b}));
            }
        }
    }
    cout << ans << '\n';
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 4950
memory_kb: 4352
final_rank: 14

code_snippet: #line 1 "2021D.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2021D.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(x)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

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

//const int m = 1700;


int solve(){
    int n; cin >> n;
    if(n==0)return 1;
    auto a = i64_vec_IN(n);
    int m = 0;
    rep(i,n) m += a[i];

    vector dp(m+1, vector(m+1, -1));
    vector ep(m+1,vector(m+1,-1));

    dp[0][0] = 0;
    rep(i,n) {
        rep(j,m+1) {
            rep(k,m+1) {
                if(dp[j][k] == -1) continue;
                
                chmax(ep[j+a[i]][k], dp[j][k]);
                chmax(ep[j][k+a[i]], dp[j][k]);
                chmax(ep[j][k], int(dp[j][k]+a[i]));
            }
        }
        dp=ep;
        fill(all(ep), vector(m+1,-1));
    }

    int ans = 0;
    rep(i,m+1) rep(j,m+1) {
        chmax(ans, min(int(i),min(int(j),dp[i][j])));
    }
    cout << ans << '\n';
    return 0;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(!solve());
}
accuracy: 1
time_ms: 740
memory_kb: 42376
final_rank: 11

code_snippet: #line 1 "2021D.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2021D.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(x)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

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

const int m = 2500;


vector dp(m+1, vector(m+1, -1));
vector ep(m+1,vector(m+1,-1));

int solve(){
    int n; cin >> n;
    if(n==0)return 1;
    auto a = i64_vec_IN(n);
    fill(all(dp), vector(m+1,-1));

    dp[0][0] = 0;
    rep(i,n) {
        rep(j,m+1) {
            rep(k,m+1) {
                if(dp[j][k] == -1) continue;
                
                chmax(ep[j+a[i]][k], dp[j][k]);
                chmax(ep[j][k+a[i]], dp[j][k]);
                chmax(ep[j][k], int(dp[j][k]+a[i]));
            }
        }
        dp=ep;
        fill(all(ep), vector(m+1,-1));
    }

    int ans = 0;
    rep(i,m+1) rep(j,m+1) {
        chmax(ans, min(int(i),min(int(j),dp[i][j])));
    }
    cout << ans << '\n';
    return 0;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(!solve());
}
accuracy: 1
time_ms: 6000
memory_kb: 52608
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
bool solve();

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

bool solve() {
  int n;cin>>n;
  if (n==0) return 0;
  vi b(n);
  rep(i,0,n)cin>>b[i];
  int sum=accumulate(all(b),0);
  const int m=50*50/3+10;
  auto dp(vector(m,vi(m,0)));
  dp[0][0]=true;
  rep(i,0,n){
    auto old(vector(m,vi(m,0)));
    swap(old,dp);
    rep(a,0,m)rep(c,0,m){
      if(a+b[i]<m)dp[a+b[i]][c]|=old[a][c];
      if(c+b[i]<m)dp[a][c+b[i]]|=old[a][c];
      dp[a][c]|=old[a][c];
    }
  }
  int ans=0;
  rep(a,0,m)rep(c,0,m)if(dp[a][c]){
    int d=sum-a-c;
    ans=max(ans,min({a,c,d}));
  }
  cout<<ans<<endl;
  return 1;
}
accuracy: 1
time_ms: 1290
memory_kb: 8968
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for(ll i = 0; i < (ll)n; ++i)
#define rrep(i, n) for(ll i = n - 1; i >= 0; --i)
#define loop(i, a, b) for(ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
#define nC2(n) n * (n - 1) / 2
constexpr ll INF = 9009009009009009009LL;
constexpr int INF32 = 2002002002;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

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

template <class T>
inline bool chmax(T &a, const T &b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmin(T &a, const T &b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename Container,
          typename = std::enable_if_t<
              !std::is_same_v<Container, std::string> &&
              std::is_convertible_v<decltype(std::declval<Container>().begin()),
                                    typename Container::iterator>>>
ostream &operator<<(ostream &os, const Container &container) {
    auto it = container.begin();
    auto end = container.end();

    if (it != end) {
        os << *it;
        ++it;
    }
	for (; it != end; ++it) {
		os << " " << *it;
	}
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {
	for (size_t i = 0; i < vv.size(); ++i) {
		os << vv[i];
		if (i != vv.size() - 1) os << "\n";
    }
    return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	assert(v.size() > 0);
	for (size_t i = 0; i < v.size(); ++i) is >> v[i];
	return is;
}
template <typename T>
istream& operator>>(istream& is, vector<vector<T>>& vv) {
	assert(vv.size() > 0);
	for (size_t i = 0; i < vv.size(); ++i) is >> vv[i];
	return is;
}

struct phash {
	template<class T1, class T2>
    inline size_t operator()(const pair<T1, T2> & p) const {
        auto h1 = hash<T1>()(p.first);
        auto h2 = hash<T2>()(p.second);

		size_t seed = h1 + h2; 
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = (h1 >> 16) ^ h1;
        seed ^= h1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = (h2 >> 16) ^ h2;
        seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        return seed;
    }
};





int solve() {
	ll n; cin >> n;
	if (n == 0) return 1;

	vll b(n); cin >> b;
	ll sum = 0;
	rep(i, n) sum += b[i];

	const int SIZE = sum + 1;
	vvll dp(SIZE, vll(SIZE, INF));
	dp[0][0] = 0;
	rep(i, n) {
		vvll old(SIZE, vll(SIZE, INF));
		swap(dp, old);

		rep(j, SIZE) {
			rep(k, SIZE) {
				if (0 <= j - b[i] && old[j - b[i]][k] != INF) dp[j][k] = old[j - b[i]][k];
				if (0 <= k - b[i] && old[j][k - b[i]] != INF) dp[j][k] = old[j][k - b[i]];
				if (old[j][k] != INF) {
					dp[j][k] = old[j][k] + b[i];
				}
			}
		}
	}

	ll ans = 0;
	ll mx = -INF;
	loop(i, 0, SIZE - 1) {
		loop(j, 0, SIZE - 1) {
			if (dp[i][j] == INF) continue;
			ll tmp = min({i, j, dp[i][j]});
			if (chmax(mx, tmp)) {
				ans = tmp;
			}
		}
	}

	cout << ans << "\n";

	return 0;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	while (!solve()) { }

	return 0;
}
accuracy: 1
time_ms: 2660
memory_kb: 80892
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for(ll i = 0; i < (ll)n; ++i)
#define rrep(i, n) for(ll i = n - 1; i >= 0; --i)
#define loop(i, a, b) for(ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
#define nC2(n) n * (n - 1) / 2
constexpr ll INF = 9009009009009009009LL;
constexpr int INF32 = 2002002002;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

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

template <class T>
inline bool chmax(T &a, const T &b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmin(T &a, const T &b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename Container,
          typename = std::enable_if_t<
              !std::is_same_v<Container, std::string> &&
              std::is_convertible_v<decltype(std::declval<Container>().begin()),
                                    typename Container::iterator>>>
ostream &operator<<(ostream &os, const Container &container) {
    auto it = container.begin();
    auto end = container.end();

    if (it != end) {
        os << *it;
        ++it;
    }
	for (; it != end; ++it) {
		os << " " << *it;
	}
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << " ";
    }
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {
	for (size_t i = 0; i < vv.size(); ++i) {
		os << vv[i];
		if (i != vv.size() - 1) os << "\n";
    }
    return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	assert(v.size() > 0);
	for (size_t i = 0; i < v.size(); ++i) is >> v[i];
	return is;
}
template <typename T>
istream& operator>>(istream& is, vector<vector<T>>& vv) {
	assert(vv.size() > 0);
	for (size_t i = 0; i < vv.size(); ++i) is >> vv[i];
	return is;
}

struct phash {
	template<class T1, class T2>
    inline size_t operator()(const pair<T1, T2> & p) const {
        auto h1 = hash<T1>()(p.first);
        auto h2 = hash<T2>()(p.second);

		size_t seed = h1 + h2; 
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
        h1 = (h1 >> 16) ^ h1;
        seed ^= h1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
        h2 = (h2 >> 16) ^ h2;
        seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        return seed;
    }
};





int solve() {
	ll n; cin >> n;
	if (n == 0) return 1;

	vll b(n); cin >> b;
	ll sum = 0;
	rep(i, n) sum += b[i];

	const int SIZE = sum + 1;
	vector<vector<bool>> dp(SIZE, vector<bool>(SIZE, false));
	dp[0][0] = true;
	rep(i, n) {
		vector<vector<bool>> old(SIZE, vector<bool>(SIZE, false));
		swap(dp, old);

		rep(j, SIZE) {
			rep(k, SIZE) {
				if (0 <= j - b[i] && old[j - b[i]][k]) dp[j][k] = true;
				if (0 <= k - b[i] && old[j][k - b[i]]) dp[j][k] = true;
				if (old[j][k]) dp[j][k] = true;
			}
		}
	}

	ll ans = 0;
	ll mx = -INF;
	loop(i, 0, SIZE - 1) {
		loop(j, 0, SIZE - 1) {
			if (!dp[i][j]) continue;
			ll tmp = min({i, j, sum - (i + j)});
			if (chmax(mx, tmp)) {
				ans = tmp;
			}
		}
	}

	cout << ans << "\n";

	return 0;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	while (!solve()) { }

	return 0;
}
accuracy: 1
time_ms: 2130
memory_kb: 4348
final_rank: 7

code_snippet: #include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cfloat>
#include <cassert>
#include <ctime>
#include <cctype>
#include <cwctype>
#include <cstdint>
#include <type_traits>
#include <initializer_list>
#include <utility>
#include <bitset>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iterator>
#include <tuple>
#include <array>
#include <new>
#include <memory>
#include <limits>
#include <random>
#include <exception>
#include <stdexcept>
#include <regex>
#include <complex>
#include <chrono>
#include <future>
#include <thread>
#include <mutex>
#include <atomic>
#include <atcoder/all>
// #include <boost/multiprecision/cpp_int.hpp>
using namespace std;
using namespace atcoder;
// using mint = modint;
using mint = modint998244353;
// using mint = modint1000000007;
// using namespace boost::multiprecision;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using T3 = tuple<int, int, int>;
using G = vector<vector<int>>;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rep2(i, a, b) for (ll i = a; i < (b); ++i)
#define rrep2(i, a, b) for (ll i = a-1; i >= (b); --i)
#define rep3(i, a, b, c) for (ll i = a; i < (b); i+=c)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define popcount __builtin_popcount
#define popcount_ll __builtin_popcountll
#define fi first
#define se second
#define UNIQUE(v) sort(rng(v)), v.erase(unique(rng(v)), v.end())
#define MIN(v) *min_element(rng(v))
#define MAX(v) *max_element(rng(v))
#define SUM(v) accumulate(rng(v),0LL)
#define IN(v, x) (find(rng(v),x) != v.end())
template<class T> bool chmin(T &a,T b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,T b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void printv(vector<T> &v){rep(i,v.size())cout<<v[i]<<" \n"[i==v.size()-1];}
template<class T> void printvv(vector<vector<T>> &v){rep(i,v.size())rep(j,v[i].size())cout<<v[i][j]<<" \n"[j==v[i].size()-1];cout<<endl;}
const ll dx[] = {-1, 0, 1, 0};
const ll dy[] = {0, 1, 0, -1};
const ll dxx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
const ll dyy[] = {0, 1, 1, 1, 0, -1, -1, -1};
const ll LINF = 3001002003004005006ll;
const int INF = 1001001001;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(1){
        int n; cin >> n;
        if (n == 0) return 0;
        vector<int> x(n);
        rep(i, n) cin >> x[i];
        vector<vector<bool>> dp(2510, vector<bool>(2510, false));
        dp[0][0] = true;
        rep(i, n){
            vector<vector<bool>> old(2510, vector<bool>(2510, false)); swap(old, dp);
            rep(a, 2501)rep(b, 2501){
                if (old[a][b] == false) continue;
                dp[a+x[i]][b] = true;
                dp[a][b+x[i]] = true;
                dp[a][b] = true;
            }
        }
        int ans = 0;
        int sum = SUM(x);
        rep(a, 2501)rep(b, 2501){
            if (dp[a][b] == false) continue;
            int c = sum-a-b;    
            chmax(ans, min({(int)a, (int)b, c}));
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 4520
memory_kb: 5248
final_rank: 13

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fast std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr)
#define eb emplace_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
using u64 = uint64_t;
using u128 = __uint128_t;
using ull = unsigned long long;
constexpr ll inf = 2e18;
constexpr ll mod = 998244353;
#ifdef LOCAL
#define debug(x) std::cerr << #x << " = " << (x) << std::endl;
#else
#define debug(x)
#endif
static void judge(bool c) {
    std::cout << (c ? "Yes" : "No") << '\n';
}
ll ppow(ll a, ll b, ll m) {
    ll res = 1;
    a %= m;
    while (b > 0) {
        if (b & 1) res = (res * a) % m;
        a = (a * a) % m;
        b >>= 1;
    }
    return res;
}


int n,b[50],dp[2501][2501];
int main() {
    fast;
    while(1){
        cin >> n;
        if(n == 0){
            return 0;
        }
        int sum = 0;
        
        for(int i = 0; i < n; i++){
            cin >> b[i];
            sum += b[i];
        }
        for(int i = 0; i <= 2500; i++){
            for(int j = 0; j <= 2500; j++){
                dp[i][j] = 0;
            }
        }
        dp[0][0] = 1; 
        for(int i = 0; i < n; i++){
            for(int j = 2500; j >= 0; j--){
                for(int k = 2500; k >= 0; k--){
                    if(dp[j][k]){
                        dp[j + b[i]][k] = 1;
                        dp[j][k + b[i]] = 1;
                    }
                }
            }
        }
        int ans = -1;
        for(int i = 0; i <= 2500; i++){
            for(int j = 0; j <= 2500; j++){
                if(dp[i][j]) ans = max(ans,min(i,min(j,sum - i - j)));
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 2940
memory_kb: 27812
final_rank: 15

code_snippet: #include <bits/extc++.h>

#include <atcoder/all>

using mint = atcoder::modint1000000007;

using ll = long long;

using pii = std::pair<int, int>;
using pil = std::pair<int, ll>;

template <class T>
using pq_rev = std::priority_queue<T, std::vector<T>, std::greater<>>;

template <class T>
bool chmax(T& x, const T& v) {
  if (x < v) {
    x = v;
    return true;
  } else {
    return false;
  }
}
template <class T>
bool chmin(T& x, const T& v) {
  if (x > v) {
    x = v;
    return true;
  } else {
    return false;
  }
}

bool solve() {
  int N;
  std::cin >> N;

  if (N == 0) {
    return false;
  }

  std::vector<int> A(N);
  for (auto& a : A) {
    std::cin >> a;
  }

  int K = std::accumulate(A.begin(), A.end(), 0);

  std::vector dp(K + 1, std::vector(K + 1, false));

  dp[0][0] = true;

  for (int i = 0; i < N; i++) {
    auto next = dp;

    for (int x = 0; x <= K; x++) {
      for (int y = 0; y <= K; y++) {
        if (x + A[i] <= K) {
          next[x + A[i]][y] = next[x + A[i]][y] || dp[x][y];
        }
        if (y + A[i] <= K) {
          next[x][y + A[i]] = next[x][y + A[i]] || dp[x][y];
        }
      }
    }

    std::swap(next, dp);
  }

  int ans = 0;

  for (int x = 0; x <= K; x++) {
    for (int y = 0; y <= K; y++) {
      if (dp[x][y]) {
        chmax(ans, std::min({x, y, K - x - y}));
      }
    }
  }

  std::cout << ans << '\n';

  return true;
}

int main() {
  while (solve());
}
accuracy: 1
time_ms: 2820
memory_kb: 4736
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;

#define rep(i,n) for(ll i=0;i<n;++i)
#define all(a) (a).begin(),(a).end()
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> T div_floor(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); }
template<class T> T div_ceil(T a, T b) { return a / b + ((a ^ b) > 0 && a % b); }
template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }
template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &a){
	if (a.empty()) return os;
	os << a.front();
	for (auto e : a | views::drop(1)){
		os << ' ' << e;
	}
	return os;
}
void dump(auto... vs) {
	((cout << vs << ' '), ...) << endl;
}


void solve(ll N) {
	vector<ll> A(N);
	rep(i,N)cin>>A[i];
	ll sum=0;
	rep(i,N){
		sum+=A[i];
	}
	ll L=(sum/2)+20;
	vector<vector<bool>> dp(L,vector<bool> (L,false));
	dp[0][0]=true;
	ll now=0;
	rep(i,N){
		vector<vector<bool>> ndp(L,vector<bool> (L,false));
		rep(j,L){
			for (ll k=j;k<L;k++){
				if (!dp[j][k])continue;
				ll l=now-j-k;
				if (l<k)break;
				ndp[j][k]=true;
				ll nk=k+A[i];
				if (nk<=l){
					ndp[j][nk]=true;
				}
				else{
					ndp[j][l]=true;
				}
				ll nj=j+A[i];
				if (nj<=k){
					ndp[nj][k]=true;
				}
				else if (nj<=l){
					ndp[k][nj]=true;
				}
				else{
					ndp[k][l]=true;
				}
			}
		}
		now+=A[i];
		swap(dp,ndp);
	}
	ll ans=0;
	rep(i,L){
		rep(j,L){
			ll k=sum-i-j;
			if (dp[i][j]){
				chmax(ans,min(i,min(j,k)));
			}
		}
	}
	cout<<ans<<endl;
    return;
}


int main() {
    while (true){
		ll N;
		cin>>N;
		if (N==0)break;
        solve(N);
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3968
final_rank: 1

code_snippet: // MARK: - コード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;

const ll MOD = 1000000007;
// const ll MOD = 998244353;
const int dx[8] = {0, -1, 1, 0, -1, 1, -1, 1};
const int dy[8] = {-1, 0, 0, 1, -1, -1, 1, 1};

template <class T>
istream &operator>>(istream &is, vector<T> &v)
{
  for (auto &e : v)
    is >> e;
  return is;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v)
{
  for (auto &e : v)
    os << e << ' ';
  return os;
}

#define reps(i, l, r) for (std::decay_t<decltype(r)> i##_right = (r), i = (l); i < i##_right; i++)
#define rep(i, n) reps(i, 0, n)

template <class T>
inline bool chmax(T &a, T &b)
{
  if (a < b)
  {
    a = b;
    return true;
  }
  else
    return false;
}
template <class T>
inline bool chmin(T &a, T &b)
{
  if (a > b)
  {
    a = b;
    return true;
  }
  else
    return false;
}

int main()
{
  while (true)
  {
    int N;
    cin >> N;
    if (N == 0)
      break;

    vector<int> A(N);
    rep(i, N) cin >> A[i];
    int sum = 0;
    rep(i, N) sum += A[i];

    vector<vector<bool>> DP(sum + 1, vector<bool>(sum + 1, false));
    DP[0][0] = true;
    rep(i, N)
    {
      for (int a = sum; a >= 0; a--)
      {
        for (int b = sum; b >= 0; b--)
        {
          if (DP[a][b])
          {
            DP[a + A[i]][b] = true;
            DP[a][b + A[i]] = true;
          }
        }
      }
    }
    int ans = 0;
    rep(a, sum + 1)
    {
      rep(b, sum + 1)
      {
        if (DP[a][b])
        {
          ans = max(ans, min(a, min(b, sum - a - b)));
        }
      }
    }
    cout << ans << endl;
  }
}
/*
MARK: - メモ



*/
accuracy: 1
time_ms: 900
memory_kb: 3796
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for(ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)

#define TT template<typename T>
TT using vec = vector<T>;
template<class T1, class T2> bool chmin(T1 &x, T2 y) { return x > y ? (x = y, true) : false; }
template<class T1, class T2> bool chmax(T1 &x, T2 y) { return x < y ? (x = y, true) : false; }

struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    while(1){
        int N;
        cin>>N;
        if(N==0)return 0;
        vector<int>B(N);
        rep(i,0,N)cin>>B[i];
        vector dp(1,vector<bool>(1));
        dp[0][0]=true;
        int sum=0;
        rep(i,0,N){
            sum+=B[i];
            vector nxt(sum+1,vector<bool>(sum+1));
            rep(j,0,sum-B[i]+1)rep(k,0,sum-B[i]+1){
                if(!dp[j][k])continue;
                nxt[j+B[i]][k]=true;
                nxt[j][k+B[i]]=true;
                nxt[j][k]=true;
            }
            swap(dp,nxt);
        }
        int ans=0;
        rep(i,0,sum+1)rep(j,0,sum+1){
            if(dp[i][j]){
                chmax(ans,min(i,min(j,sum-i-j)));
            }
        }
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 420
memory_kb: 4864
final_rank: 3

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

const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
#define all(v) v.begin(), v.end()
#define rall(a) a.rbegin(), a.rend()
#define fi first
#define se second
#define endl "\n"

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

template <typename T>
using vc = vector<T>; // prioriy_queueに必要なのでここにこれ書いてます
template <typename T>
using vv = vc<vc<T>>;
#define int long long
using ll = long long;
ll INF = 2e18;

#ifdef ONLINE_JUDGE
// ジャッジ環境ではデバッグマクロを無効化
#define debug_x(x) \
    do             \
    {              \
    } while (0)
#define debug_vc(v) \
    do              \
    {               \
    } while (0)
#define debug_vv(v) \
    do              \
    {               \
    } while (0)
#else
// ローカルではデバッグ出力
#define debug_x(x) cout << #x << " = " << (x) << endl
#define debug_vc(v)                    \
    {                                  \
        cout << #v << endl;            \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << ' '; \
        cout << endl;                  \
    } // 一次元配列を出力する
#define debug_vv(v)                                        \
    {                                                      \
        cout << #v << endl;                                \
        ll n = size(v);                                    \
        rep(i, n)                                          \
        {                                                  \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    } // 二次元配列を出力する
#endif

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (ll i = 1; i <= (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)        // i=s,s+1...n-1 ノーマルfor
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--) // s-1スタートでnまで落ちる

using ld = long double;
using bl = bool;

template <class T>
using pq = priority_queue<T, vc<T>>; // 大きい順
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>; // 小さい順

using vl = vc<ll>;
using vvl = vv<ll>;
using vvvl = vv<vl>;
using vvvvl = vv<vvl>;
using vs = vc<string>;
using vvs = vv<string>;
using vb = vc<bl>;
using vvb = vv<bl>;
using vvvb = vv<vb>;
using vld = vc<ld>;
using vvld = vv<ld>;
using vvvld = vv<vld>;
using P = pair<ll, ll>;
using vP = vc<P>;
using vvP = vc<vP>;
using vvvP = vv<vP>;

#define pb push_back

#define YES cout << "Yes" << endl
#define NO cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    } // if(a==b)YN;
#define dame cout << -1 << endl

string dir = "DRUL";   // 第4象限の場合
vl di = {1, 0, -1, 0}; // vl di={1,1,0,-1,-1,-1,0,1};
vl dj = {0, 1, 0, -1}; // vl dj={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w)
{ // trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

ll n;
vl b;

void gutyoku()
{
    vl p(n);
    iota(all(p), 0);
    ll ans = -1;
    vl maxP;
    do
    {
        ll cnt = 0;
        vl tmp = b;
        rep(i, n - 2)
        {
            ll dec = min(min(tmp[p[i]], tmp[p[i + 1]]), tmp[p[i + 2]]);
            cnt += dec;
            rep(j, 3)
            {
                tmp[p[i + j]] -= dec;
            }
            if (tmp[p[i + 1]] > tmp[p[i + 2]])
                swap(tmp[p[i + 1]], tmp[p[i + 2]]);
            if (tmp[p[i]] > tmp[p[i + 1]])
                swap(tmp[p[i]], tmp[p[i + 1]]);
            if (tmp[p[i + 1]] > tmp[p[i + 2]])
                swap(tmp[p[i + 1]], tmp[p[i + 2]]);
        }
        if (cnt == 9)
        {
            cout << "b:" << endl;
            rep(i, n)
            {
                cout << b[p[i]] << ' ';
            }
            cout << endl;
            cout << "mod:" << endl;
            rep(i, n)
            {
                cout << b[p[i]] % 3 << ' ';
            }
            cout << endl;
        }
    } while (next_permutation(all(p)));
    // debug_x(ans);
}

void solve()
{
    b.resize(n);
    ll sum = 0;
    rep(i, n)
    {
        cin >> b[i];
        sum += b[i];
    }
    // gutyoku();
    // dp[k][x][y] = "{b1, ..., bk} を 3 分割して和が (x, y, (Σki=1 bi)-x-y) となるようにできるか否か"
    vvvb dp(n + 1, vvb(sum + 1, vb(sum + 1)));
    dp[0][0][0] = true;
    rep(i, n)
    {
        rep(j, sum + 1)
        {
            rep(k, sum + 1)
            {
                if (dp[i][j][k])
                {
                    dp[i + 1][j + b[i]][k] = true;
                    dp[i + 1][j][k + b[i]] = true;
                    dp[i + 1][j][k] = true;
                }
            }
        }
    }
    ll ans = 0;
    rep(j,sum+1){
        rep(k,sum+1){
            if(dp[n][j][k]){
                ans = max(ans,min(j,min(k,sum-(j+k))));
            }
        }
    }
    cout << ans << endl;
    return;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    while (true)
    {
        cin >> n;
        if (n == 0)
            break;
        solve();
    }
    return 0;
}

/*
shift+alt+Fで成形
f2で変数名変更

スニペット
basic
 m:atcoder以外用
 ma:ABC/ARC用
 mahc:AHC用
math
 floor:床関数
 ceil:天井関数
 comv:二項係数
 modpow: a^b mod m
 GCD:最大公約数
 extGCD:拡張ユークリッド互除法
 PFD:素因数分解
 isprime:エラトステネスの篩
 matrixpow:行列累乗
data_structure
 seg:セグメント木
technic
 Compress:座標圧縮
 runlength:ランレングス圧縮
graph
 warshall:ワーシャルフロイド法
 dfs:深さ優先探索
 bfs:幅優先探索
 LCA:最近共通祖先
*/
accuracy: 1
time_ms: 1300
memory_kb: 37964
final_rank: 12

code_snippet: #line 2 "/home/nixos/workspace/CompPro-Make/library/KowerKoint/stl-expansion.hpp"
#include <bits/stdc++.h>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& p) {
    is >> p.first >> p.second;
    return is;
}
template <typename T, size_t N>
std::istream& operator>>(std::istream& is, std::array<T, N>& a) {
    for (size_t i = 0; i < N; ++i) {
        is >> a[i];
    }
    return is;
}
template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto& e : v) is >> e;
    return is;
}
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
    os << p.first << " " << p.second;
    return os;
}
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& os, const std::array<T, N>& a) {
    for (size_t i = 0; i < N; ++i) {
        os << a[i] << (i + 1 == a.size() ? "" : " ");
    }
    return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
#line 3 "/home/nixos/workspace/CompPro-Make/library/KowerKoint/base.hpp"
using namespace std;

#define REP(i, n) for(int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for(ll i = a; i < (ll)(b); i++)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define END(...) { print(__VA_ARGS__); return; }

using VI = vector<int>;
using VVI = vector<VI>;
using VVVI = vector<VVI>;
using ll = long long;
using VL = vector<ll>;
using VVL = vector<VL>;
using VVVL = vector<VVL>;
using ull = unsigned long long;
using VUL = vector<ull>;
using VVUL = vector<VUL>;
using VVVUL = vector<VVUL>;
using VD = vector<double>;
using VVD = vector<VD>;
using VVVD = vector<VVD>;
using VS = vector<string>;
using VVS = vector<VS>;
using VVVS = vector<VVS>;
using VC = vector<char>;
using VVC = vector<VC>;
using VVVC = vector<VVC>;
using P = pair<int, int>;
using VP = vector<P>;
using VVP = vector<VP>;
using VVVP = vector<VVP>;
using LP = pair<ll, ll>;
using VLP = vector<LP>;
using VVLP = vector<VLP>;
using VVVLP = vector<VVLP>;

template <typename T>
using PQ = priority_queue<T>;
template <typename T>
using GPQ = priority_queue<T, vector<T>, greater<T>>;

constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr int DX[] = {1, 0, -1, 0};
constexpr int DY[] = {0, 1, 0, -1};

void print() { cout << '\n'; }
template<typename T>
void print(const T &t) { cout << t << '\n'; }
template<typename Head, typename... Tail>
void print(const Head &head, const Tail &... tail) {
    cout << head << ' ';
    print(tail...);
}

#ifdef DEBUG
void dbg() { cerr << '\n'; }
template<typename T>
void dbg(const T &t) { cerr << t << '\n'; }
template<typename Head, typename... Tail>
void dbg(const Head &head, const Tail &... tail) {
    cerr << head << ' ';
    dbg(tail...);
}
#else
template<typename... Args>
void dbg(const Args &... args) {}
#endif

template<typename T>
vector<vector<T>> split(typename vector<T>::const_iterator begin, typename vector<T>::const_iterator end, T val) {
    vector<vector<T>> res;
    vector<T> cur;
    for(auto it = begin; it != end; it++) {
        if(*it == val) {
            res.push_back(cur);
            cur.clear();
        } else cur.push_back(*it);
    }
    res.push_back(cur);
    return res;
}

vector<string> split(typename string::const_iterator begin, typename string::const_iterator end, char val) {
    vector<string> res;
    string cur = "";
    for(auto it = begin; it != end; it++) {
        if(*it == val) {
            res.push_back(cur);
            cur.clear();
        } else cur.push_back(*it);
    }
    res.push_back(cur);
    return res;
}

template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template <typename T>
pair<VI, vector<T>> compress(const vector<T> &a) {
    int n = a.size();
    vector<T> x;
    REP(i, n) x.push_back(a[i]);
    sort(ALL(x)); x.erase(unique(ALL(x)), x.end());
    VI res(n);
    REP(i, n) res[i] = lower_bound(ALL(x), a[i]) - x.begin();
    return make_pair(res, x);
}

template <typename It>
auto rle(It begin, It end) {
    vector<pair<typename It::value_type, int>> res;
    if(begin == end) return res;
    auto pre = *begin;
    int num = 1;
    for(auto it = begin + 1; it != end; it++) {
        if(pre != *it) {
            res.emplace_back(pre, num);
            pre = *it;
            num = 1;
        } else num++;
    }
    res.emplace_back(pre, num);
    return res;
}

template <typename It>
vector<pair<typename It::value_type, int>> rle_sort(It begin, It end) {
    vector<typename It::value_type> cloned(begin, end);
    sort(ALL(cloned));
    auto e = rle(ALL(cloned));
    sort(ALL(e), [](const auto& l, const auto& r) { return l.second < r.second; });
    return e;
}

template <typename T>
pair<vector<T>, vector<T>> factorial(int n) {
    vector<T> res(n+1), rev(n+1);
    res[0] = 1;
    REP(i, n) res[i+1] = res[i] * (i+1);
    rev[n] = 1 / res[n];
    for(int i = n; i > 0; i--) {
        rev[i-1] = rev[i] * i;
    }
    return make_pair(res, rev);
}
#line 2 "main.cpp"

int simulate(const vector<int>& b){
    vector<int> v;
    v.push_back(b[0]);
    v.push_back(b[1]);
    v.push_back(b[2]);
    int ans = 0;
    int nxt = 3;
    while(ssize(v) == 3) {
        int mn = *ranges::min_element(v);
        ans += mn;
        vector<int> nv;
        for(int i = 0; i < 3; i++) {
            v[i] -= mn;
            if(v[i] > 0) nv.push_back(v[i]);
        }
        while(nxt < ssize(b) && ssize(nv) < 3) {
            nv.push_back(b[nxt++]);
        }
        v.swap(nv);
    }
    return ans;
}

int solve(const vector<int>& b) {
    int n = ssize(b);
    constexpr int SUM = 50*50;
    vector<bitset<SUM+1>> dp(SUM+1);
    dp[0][0] = 1;
    REP(i, n) {
        vector<bitset<SUM+1>> ndp(SUM+1);
        REP(j, SUM+1) {
            if(j+b[i] <= SUM) ndp[j+b[i]] |= dp[j];
            ndp[j] |= dp[j] << b[i];
            ndp[j] |= dp[j];
        }
        dp.swap(ndp);
    }
    int ans = 0;
    int sumb = accumulate(ALL(b), 0);
    REP(i, SUM+1) REP(j, SUM+1) {
        if(dp[i][j]) chmax(ans, min(min(i, j), sumb-i-j));
    }
    return ans;
}

void expr() {
    mt19937 mt(0);
    while(1) {
        cout << "expr" << endl;
        int n = mt() % 4 + 3;
        vector<int> b(n);
        for(int i = 0; i < n; i++) {
            b[i] = mt() % 10;
        }
        ranges::sort(b);
        int mx = 0;
        vector<int> best;
        do {
            if(chmax(mx, simulate(b))) {
                best = b;
            }
        } while(next_permutation(ALL(b)));
        ranges::sort(b | views::reverse);
        if(mx != solve(b)) {
            for(int i = 0; i < n; i++) {
                cout << ' ' << best[i];
            }
            cout << endl;
            cout << mx << endl;
            cout << solve(b) << endl;
            return;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    while(1) {
        int n; cin >> n;
        if(n==0) return 0;
        vector<int> b(n);
        for(int i = 0; i < n; i++) cin >> b[i];
        cout << solve(b) << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 4992
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
bool solve();

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

bool solve() {
  int N;cin>>N;
  if (N==0) return 0;
  vi B(N);
  rep(i,0,N)cin>>B[i];
  const int M=50*(N+1);
  vector dp(M,vector<int>(M));
  dp[0][0]=true;
  int bsum=0;
  rep(bi,0,N){
    vector old(M,vector<int>(M));
    swap(old,dp);
    rep(i,0,M)rep(j,0,M){
      if(i+B[bi]<M)dp[i+B[bi]][j] |= old[i][j];
      if(j+B[bi]<M)dp[i][j+B[bi]] |= old[i][j];
      dp[i][j] |=old[i][j];
    }
    bsum+=B[bi];
  }
  int ans=0;
  rep(i,0,M)rep(j,0,M){
    if(dp[i][j]){
      ans=max(ans,min({i,j,bsum-i-j}));
    }
  }
  cout<<ans<<endl;
  return 1;
}
accuracy: 1
time_ms: 7650
memory_kb: 54364
final_rank: 20

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
#define rep(i, a, b) for(int i = (a); i < (b); i++) // [a, b)を昇順に
#define drep(i, a, b) for(int i = (b) - 1; i >= a; i--) // [a, b)を降順に
#define all(v) v.begin(), v.end() // 昇順sortに
#define rall(v) v.rbegin(), v.rend() // 降順sortに
#define sz(x) (int)(x).size()
#define decimal(n) cout << fixed << setprecision(n);
#define debug(x) cerr << #x << " = " << x << endl;
#define Yes cout << "Yes" << endl;
#define No cout << "No" << endl;
#define yesno(condition) { if (condition) cout << "Yes" << endl; else cout << "No" << endl; }
using vi = vector<int>; using vvi = vector<vi>; using vs = vector<string>;
using ll = long long; using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>;
using lll = __int128;
// using mint = modint998244353;
const ll MOD = 998244353;
// using mint = modint;
// const ll MOD = 998244353;
// using mint = modint1000000007;
// const ll MOD = 1000000007;
// using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>;
using P = pair<ll, ll>; using T = tuple<ll, ll, ll>;
using vc = vector<char>;
const ll MAX = 5'000'009; const ll llINF = 2e18;
const int intINF = 2e9; const long double pi = acos(-1);
ll di[] = {0, -1, 0, 1, -1, -1, 1, 1};
ll dj[] = {1, 0, -1, 0, 1, -1, -1, 1};
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
template<class T> using pq = priority_queue<T, vector<T>>; //大きい順
template<class T> using pq_g = priority_queue<T, vector<T>, greater<T>>; //小さい順

bool isin(ll i, ll j, ll n, ll m) { return (0 <= i && i < n && 0 <= j && j < m); }
bool is_multipul_overflow(ll a, ll b, ll c) {
    // a * b > cかを判定する
    if (a == 0 || b == 0) return false;
    return (a <= c / b ? false : true);
}



void solve(ll &n) {
    vector<int> b(n);
    rep(i, 0, n) cin >> b[i];

    int maxsum = n * 50;
    vector<vector<bool>> dp(maxsum + 1, vector<bool>(maxsum + 1));
    dp[0][0] = true;
    rep(i, 0, n) {
        vector<vector<bool>> ndp(maxsum + 1, vector<bool>(maxsum + 1));
        rep(sum1, 0, maxsum + 1) {
            rep(sum2, 0, maxsum + 1) {
                if(!dp[sum1][sum2]) continue;

                ndp[sum1 + b[i]][sum2] = true;
                ndp[sum1][sum2 + b[i]] = true;
                ndp[sum1][sum2] = true;
            }
        }

        swap(ndp, dp);
    }

    int ans = 0;
    int sumb = accumulate(all(b), 0);
    rep(sum1, 0, maxsum + 1) {
        rep(sum2, 0, maxsum + 1) {
            if(!dp[sum1][sum2]) continue;

            chmax(ans, min({sum1, sum2, sumb - (sum1 + sum2)}));
        }
    }

    cout << ans << endl;
}

int main() {
    ll n;
    while(true) {
        cin >> n;
        if(n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 3320
memory_kb: 5012
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <cassert>
using namespace std;
using ll = long long;
template<class T> inline bool chmax(T& a, const T& b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, const T& b) {if (b<a) {a=b; return true;} return false;}
constexpr int INTINF = 1000001000;
constexpr int INTMAX = 2147483647;
constexpr ll LLMAX = 9223372036854775807;
constexpr ll LLINF = 4450000000011100000;

void solve(int N) {
  vector<int>B(N);
  int MX = 0;
  for (int i=0; i<N; i++) {
    cin >> B[i];
    MX += B[i];
  }

  vector<vector<vector<bool>>>dp(N+1, vector(MX+1, vector(MX+1, false)));
  // dp[i][x][y] := [0,i)を見て、チーム1の総和がx,チーム2の総和がyとなるように和を分解することができるか

  dp[0][0][0] = true;

  for (int i=0; i<N; i++) {
    for (int x=0; x<=MX; x++) {
      for (int y=0; y<=MX; y++) {
        if (!dp[i][x][y]) continue;
        int b = B[i];
        // teamAにjoinさせる
        dp[i+1][x+b][y] = true;

        // teamBにjoinさせる
        dp[i+1][x][y+b] = true;
      
        // A,Bにjoinさせない
        dp[i+1][x][y] = true;
      }
    }
  }

  int ans = 0;

  for (int x=0; x<=MX; x++) {
    for (int y=0; y<=MX; y++) {
      int z = MX - x - y;
      if (dp[N][x][y]) chmax(ans,  min(x,min(y,z)));
    }
  }
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  while (true) {
    int n; cin >> n;
    if (n == 0) break;
    solve(n);
  }
  return 0;
}
accuracy: 1
time_ms: 960
memory_kb: 38404
final_rank: 10

code_snippet: //#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pli = pair<ll,int>;
#define AMARI 998244353
//#define AMARI 1000000007
#define el '\n'
#define El '\n'
#define YESNO(x) ((x) ? "Yes" : "No")
#define YES YESNO(true)
#define NO YESNO(false)
#define REV_PRIORITY_QUEUE(tp) priority_queue<tp,vector<tp>,greater<tp>>
#define EXIT_ANS(x) {cout << (x) << '\n'; return;}
template <typename T> void inline SORT(vector<T> &v){sort(v.begin(),v.end()); return;}
template <typename T> void inline VEC_UNIQ(vector<T> &v){sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); return;}
template <typename T> T inline MAX(vector<T> &v){return *max_element(v.begin(),v.end());}
template <typename T> T inline MIN(vector<T> &v){return *min_element(v.begin(),v.end());}
template <typename T> T inline SUM(vector<T> &v){T ans = 0; for(int i = 0; i < (int)v.size(); i++)ans += v[i]; return ans;}
template <typename T> void inline DEC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]--; return;}
template <typename T> void inline INC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]++; return;}
void inline TEST(void){cerr << "TEST" << endl; return;}
template <typename T> bool inline chmin(T &x,T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}
template <typename T> bool inline chmax(T &x,T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}
template <typename T = long long> vector<T> inline get_vec(int n){
    vector<T> ans(n);
    for(int i = 0; i < n; i++)cin >> ans[i];
    return ans;
}
template <typename T> void inline print_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cout << vec[i];
        if(kaigyou || i == n - 1)cout << '\n';
        else cout << ' ';
    }
    if(!n)cout << '\n';
    return;
}
template <typename T> void inline debug_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cerr << vec[i];
        if(kaigyou || i == n - 1)cerr << '\n';
        else cerr << ' ';
    }
    if(!n)cerr << '\n';
    return;
}
vector<vector<int>> inline get_graph(int n,int m = -1,bool direct = false){
    if(m == -1)m = n - 1;
    vector<vector<int>> g(n);
    while(m--){
        int u,v;
        cin >> u >> v;
        u--; v--;
        g[u].push_back(v);
        if(!direct)g[v].push_back(u);
    }
    return g;
}

vector<int> make_inv(vector<int> p){
    int n = (int)p.size();
    vector<int> ans(n);
    for(int i = 0; i < n; i++)ans[p[i]] = i;
    return ans;
}

#define MULTI_TEST_CASE false
void solve(void){
    ll n;
    cin >> n;
    if(n == 0){exit(0);}
    vector<ll> a(n);
    for(int i=0;i<n;i++){
        cin >> a[i];
    }
    ll m = 50;
    vector<vector<int>> dp(n*m+1,vector<int>(n * m + 1,0));
    dp[0][0] = 1;
    ll s = 0;
    for(int i=0;i<n;i++){
        s += a[i];
        vector<vector<int>> ndp(n*m+1,vector<int>(n * m + 1,0));
        for(int j=0;j<n*m+1;j++){
            for(int k=0;k<n*m+1;k++){
                if(dp[j][k] == 0){continue;}
                ndp[j][k] |= dp[j][k];
                if(j + a[i] <= n*m){
                    ndp[j+a[i]][k] |= dp[j][k];
                }
                if(k + a[i] <= n*m){
                    ndp[j][k+a[i]] |= dp[j][k];
                }
            }
        }
        swap(dp,ndp);
    }
    ll ans = 0;
    for(ll i=0;i<n*m+1;i++){
        for(ll j=0;j<n*m+1;j++){
            ll k =s - i - j;
            if(k < 0){continue;}
            if(dp[i][j]){
                ans = max(ans,min(i,min(j,k)));
            } 
        }
    }
    cout << ans << endl;
    return;
}

void calc(void){
    return;
}

signed main(void){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    calc();
    int t = 1;
    if(MULTI_TEST_CASE)cin >> t;
    while(1){
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 3470
memory_kb: 52508
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}



int main(){
    while(1){
        LL(n);
        if(n == 0){break;}
        VLL(a,n);
        auto solve = [&](){
            ll z = 0;
            for(ll x:a){
                z += x;
            }
            vector<vector<bitset<2501>>> dp(n+1,vector<bitset<2501>>(2501));
            dp[0][0][0] = 1;
            rep(i,n){
                rep(j,n*50+1){
                    rep(k,n*50+1){
                        if(dp[i][j][k] == 0){continue;}
                        if(j+a[i] < n*50+1){
                            dp[i+1][j+a[i]][k] = 1;
                        }
                        if(k+a[i] < n*50+1){
                            dp[i+1][j][k+a[i]] = 1;
                        }
                        dp[i+1][j][k] = 1;
                    }
                }
            }
            ll ans = 0;
            rep(i,n*50+1){
                rep(j,n*50+1){
                    if(dp[n][i][j] == 1){
                        ans = max(ans,min(i,min(j,z-i-j)));
                    }
                    
                }
            }
            print(ans);
        };
        solve();
    }
}
accuracy: 1
time_ms: 2640
memory_kb: 44896
final_rank: 16