/*
分析:
DFS枝剪经典。
2013-03-03
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 111
int n,ans;
int aim,ok;
int len[N],flag[N];
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
void dfs(int now,int finish,int pre)
{
if(finish==aim) {ans=1;return ;}
if(ans) return ;
int i,j;
for(i=pre+1;i<n;i++)
{
if(flag[i]) continue;
if(now+len[i]>ok) continue;
flag[i]=1;
if(now+len[i]==ok) dfs(0,finish+1,-1);
else dfs(now+len[i],finish,i);
flag[i]=0;
if(ans) return ;
/*
这一个很重要,如果以当前这根作为第一根,然后从还某有
用过的木头中来找出合适的,来和它组成一个完整的,失败了,
那么就这种组合方法坑定会失败(因为剩下的还没有用过的木头
中,已经确定这一根无法和其它的组成有效组合),直接return掉
*/
if(!now) return ;
/*
长度相同的没有必要进行重复dfs。
*/
for(j=i+1;j<n;j++) if(len[j]!=len[j-1]) break;
i=j-1;
}
}
int main()
{
int i;
int max,sum;
while(scanf("%d",&n),n)
{
max=sum=0;
for(i=0;i<n;i++)
{
scanf("%d",&len[i]);
sum+=len[i];
if(len[i]>max) max=len[i];
}
qsort(len,n,sizeof(int),cmp);
for(i=n;i>=2;i--)
{
ans=0;
if(sum%i) continue;
if(sum/i<max) continue;
aim=i;ok=sum/i;
memset(flag,0,sizeof(flag));
dfs(0,0,-1);
if(ans) break;
}
printf("%d\n",sum/i);
}
return 0;
}