#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 70;
int n, m;          // n 为输入总数,m 为过滤后的有效木棍数
int a[MAXN];       // 存储各小木棍长度
bool vis[MAXN];    // 标记某根小木棍是否已经被使用
int sum = 0;       // 所有有效小木棍的总长度
int max_len = 0;   // 最长的一根小木棍的长度

// 降序排序比较函数
bool cmp(int x, int y) {
    return x > y;
}

/**
 * 核心 DFS 函数
 * @param cnt:    当前已经成功拼好的原木棍数量
 * @param cur:    当前正在拼的这根原木棍已经拼凑出的长度
 * @param last:   上一根被选中的小木棍的下标(用于规定顺序,避免重复组合)
 * @param target: 我们当前正在尝试的原木棍目标长度
 */
bool dfs(int cnt, int cur, int last, int target) {
    // 边界条件:如果拼出的总长度等于总长度,说明成功了
    if (cnt * target == sum) return true;
    
    // 如果当前正在拼的木棍达到了目标长度,开启下一根的拼凑
    // 下一根的起点长度为0,且由于是新的一根,从头(下标1)开始找小木棍
    if (cur == target) return dfs(cnt + 1, 0, 1, target);

    for (int i = last; i <= m; ++i) {
        // 如果这根木棍用过了,或者加上它会超出目标长度,直接跳过
        if (vis[i] || cur + a[i] > target) continue;

        vis[i] = true;
        if (dfs(cnt, cur + a[i], i + 1, target)) return true;
        vis[i] = false; // 回溯:如果往下走失败了,把这根木棍退回来

        /* ================= 核心剪枝区域 ================= */
        
        // 剪枝 1:失败位置是当前木棍的“第一根”
        // 如果当前正在尝试拼一根新木棍(cur == 0),并且第一根就失败了,
        // 那么这根小木棍迟早要用到某个地方,既然放第一根都不行,放后面更不行,直接放弃整个分支。
        if (cur == 0) return false;

        // 剪枝 2:失败位置是当前木棍的“最后一根”
        // 如果放上这根小木棍刚好达到了 target(cur + a[i] == target),但后续搜索失败了,
        // 说明用这根完美的整木棍都无解,如果把它拆碎用更多更小的木棍来填满这个空隙,只会更没有灵活性,必定也无解。
        if (cur + a[i] == target) return false;

        // 剪枝 3:跳过等效长度的木棍
        // 如果当前长度为 a[i] 的木棍没有成功,那么下一根和它一样长的木棍也肯定不会成功。
        while (i < m && a[i] == a[i + 1]) ++i;
    }
    return false;
}

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

    cin >> n;

    for (int i = 1; i <= n; ++i) {
        int val;
        cin >> val;
        
        a[++m] = val;
        sum += val;
        max_len = max(max_len, val);
    }

    // 剪枝 4:优化搜索顺序(从大到小排序)
    // 优先尝试长木棍,因为长木棍的灵活性差(能填进去的缝隙少),先安排它们能大幅减少搜索分支。
    sort(a + 1, a + m + 1, cmp);

    // 原始木棍的长度 len 最小是切出木棍中的最大值 max_len,最大是所有木棍总和 sum
    for (int len = max_len; len <= sum; ++len) {
        // 剪枝 5:可行性剪枝
        // 如果总长度不能被当前目标长度整除,说明无法拼出整数根,直接跳过
        if (sum % len != 0) continue;

        // 开始尝试目标长度 len。每次 dfs 成功会直接退出,
        // 失败的话 vis 数组会在回溯时清空,所以不需要 memset。
        if (dfs(0, 0, 1, len)) {
            cout << len << "\n";
            break; // 从小到大枚举,遇到的第一个成功的即为最小值
        }
    }

    return 0;
}