#include <bits/stdc++.h>
using namespace std;
// Define a structure for memoization key
struct MemoKey {
int index;
int count;
int current_gcd;
bool operator<(const MemoKey& other) const {
return tie(index, count, current_gcd) < tie(other.index, other.count, other.current_gcd);
}
};
// Memoization map
unordered_map<long long, int> memo;
// Function to encode the memoization key into a single number
long long encodeKey(int index, int count, int current_gcd) {
// Assuming N <= 40 and current_gcd <= 1e5
return ((long long)index * 1000000LL + (long long)count * 1000LL + current_gcd);
}
// Recursive function to find the maximum GCD
int maxGCD_recursive(int index, int count, int current_gcd, const vector<int>& A, int N) {
// Base Cases
if (count == 0) {
return current_gcd;
}
if (index == N) {
// If not enough elements left to select
return -1; // Indicates invalid
}
// Encode the current state
long long key = encodeKey(index, count, current_gcd);
// Check if the result is already computed
if (memo.find(key) != memo.end()) {
return memo[key];
}
// Choice 1: Skip the current element
int option1 = maxGCD_recursive(index + 1, count, current_gcd, A, N);
// Choice 2: Include the current element
int new_gcd;
if (current_gcd == 0) { // If no elements selected yet
new_gcd = A[index];
} else {
new_gcd = gcd(current_gcd, A[index]);
}
int option2 = maxGCD_recursive(index + 1, count - 1, new_gcd, A, N);
// Choose the maximum GCD
int result = max(option1, option2);
// Store the result in memoization map
memo[key] = result;
return result;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int N;
cin >> N;
vector<int> A(N);
for(auto &x: A){
cin >> x;
}
// Vector to store the maximum GCD for each subset size
vector<int> result(N + 1, 0); // result[k] = max GCD for subset size k
// Iterate over each subset size from 1 to N
for(int k = 1; k <= N; k++) {
// Clear memoization map for each k to save memory
memo.clear();
// Initialize current_gcd to 0 (no elements selected yet)
int current_max_gcd = maxGCD_recursive(0, k, 0, A, N);
// If no valid subset found, default to 0 (though per problem constraints, at least 1 should exist)
if(current_max_gcd == -1){
current_max_gcd = 0;
}
result[k] = current_max_gcd;
}
// Print the results from k=1 to k=N
for(int k = 1; k <= N; k++) {
cout << result[k] << " ";
}
return 0;
}