Problem:
問題文
正整数列 $X_1,X_2,...,X_N$ がある。数列 $\{1,2,...,N\}$ から部分列 $S$ を選ぶ。ただし $S$ は以下の条件を満たす必要がある。
$T=\{X_s | s \in S\}$ とする。このとき、任意の $x \in T$ について、$x$ の約数(ただし $x$ は除く)は $T$ に含まれない。
条件を満たす $S$ のうち、最も多くの要素を含むものを求めよ。また、そのような $S$ が複数ある場合は辞書式順序で最小のものを求めよ。
入力
入力は以下の形式に従う。与えられる数は全て整数である。
$N$
$X_1$ $X_2$ $...$ $X_N$
制約
$1 \leq N \leq 100$
$1 \leq X_i \leq 10^8$
$i \neq j$ ならば $X_i \neq X_j$
出力
求める $S$ の各要素を1行にスペースを空けて昇順で出力せよ。
Sample Input 1
3
25 125 5
Output for the Sample Input 1
1
$T=\{X_1\}=\{25\}$ は条件を満たす。
Sample Input 2
3
6 3 2
Output for the Sample Input 2
2 3
$T=\{X_2,X_3\}=\{2,3\}$ は条件を満たす。
Sample Input 3
10
10 9 8 7 6 5 4 3 2 1
Output for the Sample Input 3
1 2 3 4 5
$T=\{X_1,X_2,X_3,X_4,X_5\}=\{6,7,8,9,10\}$ は条件を満たす。
$T=\{X_1,X_2,X_4,X_5,X_7\}=\{4,6,7,9,10\}$ も条件を満たすが、$\{1,2,4,5,7\}$は $\{1,2,3,4,5\}$ より辞書順で大きいので答とはならない。

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<utility>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007; 

struct fast_io {
	fast_io(){
		std::cin.tie(nullptr);
		std::ios::sync_with_stdio(false);
	};
} fio;


class ford_fulkerson{
	int maxv;
	struct edge{ int to, cap, rev; };
public:
	vector<vector<edge>> G;
	vector<bool> used;

	
	ford_fulkerson(int maxv = 0) : maxv(maxv){
		resize(maxv);
	}
	
	void init(){
		G.clear();
		used.clear();
	}
	
	void resize(int v){
		G.resize(v);
		used.resize(v);
	}
	
	void add_edge(int from, int to, int cap){
		G[from].push_back((edge){to,cap,(int)G[to].size()});
		G[to].push_back((edge){from, 0, (int)G[from].size()-1});
	}

	int dfs(int v, int t, int f){
		if(v == t) return f;
		used[v] = true;
		for(int i = 0; i < G[v].size(); i++){
			edge &e = G[v][i];
			if(!used[e.to] && e.cap > 0){
				int d = dfs(e.to, t, min(f,e.cap));
				if(d > 0){
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

	int max_flow(int s, int t){
		int flow = 0;
		for(;;){
			fill(used.begin(), used.end(), false);
			int f = dfs(s,t,INF);
			if(f == 0) return flow;
			flow += f;
		}
	}
};

void input(int &N, vector<int> &X){
	cin>>N;
	
	X.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>X[i];
	}
}

void output(vector<int> &ans){
	for(int i = 0; i < ans.size(); i++){
		if(i) cout<<" ";
		cout<<ans[i];
	}
	cout<<endl;
}

void solve(int &N, vector<int> &X, vector<int> &ans){
	int largest_antichain;
	vector<int> used(N);
	
	ford_fulkerson ff(N*2+2);
	
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			if(i != j && X[j] % X[i] == 0) {
				ff.add_edge(i, j + N, 1);
			}
		}
		
		ff.add_edge(2 * N, i, 1);
		ff.add_edge(i + N, 2 * N + 1, 1);
	}
	
	largest_antichain = N - ff.max_flow(2 * N, 2 * N + 1);
	
	for(int k = 0; k < N; k++){
		int con = 0;
		ff.init();
		
		ff.resize(N * 2 + 2);
		
		for(int i = 0; i < N; i++){
			if(X[k]%X[i])ff.add_edge(2 * N, i, 1);
			if(X[i]%X[k])ff.add_edge(i + N, 2 * N + 1, 1);
			
			if(X[k]%X[i] && X[i]%X[k]) con++;
			
			
			for(int j = 0; j < N; j++){
				if(i != j && X[j] % X[i] == 0) {
					ff.add_edge(i, j + N, 1);
				}
			}
			
		}
		
		int flow = ff.max_flow(2 * N, 2 * N + 1);
		
		
		if(con - flow + 1 == largest_antichain && used[k] == false) {
			
			ans.push_back(k+1);
			
			for(int i = 0; i < N; i++){
				if(X[i] % X[k] == 0) used[i] = true;
				if(X[k] % X[i] == 0) used[i] = true;
			}
		}
	}
}

signed main(){
	cout<<fixed<<setprecision(10);
	
	int N;
	vector<int> X, ans;
	
	input(N, X);
	
	solve(N, X, ans);
	
	output(ans);
	
	return 0;
}
accuracy: 0.40425531914893614
time_ms: 10
memory_kb: 3244
final_rank: 4

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<utility>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007; 

struct fast_io {
	fast_io(){
		std::cin.tie(nullptr);
		std::ios::sync_with_stdio(false);
	};
} fio;


class ford_fulkerson{
	int maxv;
	struct edge{ int to, cap, rev; };
public:
	vector<vector<edge>> G;
	vector<bool> used;

	
	ford_fulkerson(int maxv = 0) : maxv(maxv){
		resize(maxv);
	}
	
	void init(){
		G.clear();
		used.clear();
	}
	
	void resize(int v){
		G.resize(v);
		used.resize(v);
	}
	
	void add_edge(int from, int to, int cap){
		G[from].push_back((edge){to,cap,(int)G[to].size()});
		G[to].push_back((edge){from, 0, (int)G[from].size()-1});
	}

	int dfs(int v, int t, int f){
		if(v == t) return f;
		used[v] = true;
		for(int i = 0; i < G[v].size(); i++){
			edge &e = G[v][i];
			if(!used[e.to] && e.cap > 0){
				int d = dfs(e.to, t, min(f,e.cap));
				if(d > 0){
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

	int max_flow(int s, int t){
		int flow = 0;
		for(;;){
			fill(used.begin(), used.end(), false);
			int f = dfs(s,t,INF);
			if(f == 0) return flow;
			flow += f;
		}
	}
};

void input(int &N, vector<int> &X){
	cin>>N;
	
	X.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>X[i];
	}
}

void output(vector<int> &ans){
	for(int i = 0; i < ans.size(); i++){
		if(i) cout<<" ";
		cout<<ans[i];
	}
	cout<<endl;
}

void solve(int &N, vector<int> &X, vector<int> &ans){
	int largest_antichain;
	vector<int> used(N);
	
	ford_fulkerson ff(N*2+2);
	
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			if(i != j && X[j] % X[i] == 0) {
				ff.add_edge(i, j + N, 1);
			}
		}
		
		ff.add_edge(2 * N, i, 1);
		ff.add_edge(i + N, 2 * N + 1, 1);
	}
	
	largest_antichain = N - ff.max_flow(2 * N, 2 * N + 1);
	
	// cout<<largest_antichain<<" flow = "<<N - largest_antichain<<endl;
	
	for(int k = 0; k < N; k++){
		int con = 0;
		ff.init();
		
		ff.resize(N * 2 + 2);
		
		for(int i = 0; i < N; i++){
			if(X[k]%X[i] == 0 || X[i]%X[k] == 0) continue;
			con++;
			// if(X[k]%X[i] == 0) continue;
			// if(X[i]%X[k] == 0) continue;
			for(int j = 0; j < N; j++){
				if(X[k]%X[j] == 0 || X[j]%X[k] == 0) continue;
				// if(X[k]%X[j] == 0) continue;
				// if(X[j]%X[k] == 0) continue;
				if(i != j && X[j] % X[i] == 0) {
					ff.add_edge(i, j + N, 1);
				}
			}
			
			ff.add_edge(2 * N, i, 1);
			ff.add_edge(i + N, 2 * N + 1, 1);
		}
		// cout<<"k = "<<k<<" flow = "<<ff.max_flow(2 * N, 2 * N + 1)<<endl;
		int flow = ff.max_flow(2 * N, 2 * N + 1);
		// cout<<"[] "<<con - flow<<" flow = "<<flow<<" used "<<used[k]<<" con = "<<con<<endl;
		// cout<<"[] "<<N - flow - 1<<" flow = "<<flow<<" used "<<used[k]<<endl;
		// if(N - flow - 1 == largest_antichain && used[k] == false) { cout<<"k = "<<k<<endl;
		if(con - flow + 1== largest_antichain && used[k] == false) { 
		// cout<<"k = "<<k<<endl;
			ans.push_back(k+1);
			
			
			for(int i = 0; i < N; i++){
				if(X[i] % X[k] == 0) used[i] = true;
				if(X[k] % X[i] == 0) used[i] = true;
			}
		}
	}
}

signed main(){
	cout<<fixed<<setprecision(10);
	
	int N;
	vector<int> X, ans;
	
	input(N, X);
	
	solve(N, X, ans);
	
	output(ans);
	
	return 0;
}
accuracy: 0.40425531914893614
time_ms: 10
memory_kb: 3248
final_rank: 5

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<utility>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007; 

struct fast_io {
	fast_io(){
		std::cin.tie(nullptr);
		std::ios::sync_with_stdio(false);
	};
} fio;


class ford_fulkerson{
	int maxv;
	struct edge{ int to, cap, rev; };
public:
	vector<vector<edge>> G;
	vector<bool> used;

	
	ford_fulkerson(int maxv = 0) : maxv(maxv){
		resize(maxv);
	}
	
	void init(){
		G.clear();
		used.clear();
	}
	
	void resize(int v){
		G.resize(v);
		used.resize(v);
	}
	
	void add_edge(int from, int to, int cap){
		G[from].push_back((edge){to,cap,(int)G[to].size()});
		G[to].push_back((edge){from, 0, (int)G[from].size()-1});
	}

	int dfs(int v, int t, int f){
		if(v == t) return f;
		used[v] = true;
		for(int i = 0; i < G[v].size(); i++){
			edge &e = G[v][i];
			if(!used[e.to] && e.cap > 0){
				int d = dfs(e.to, t, min(f,e.cap));
				if(d > 0){
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

	int max_flow(int s, int t){
		int flow = 0;
		for(;;){
			fill(used.begin(), used.end(), false);
			int f = dfs(s,t,INF);
			if(f == 0) return flow;
			flow += f;
		}
	}
};

void input(int &N, vector<int> &X){
	cin>>N;
	
	X.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>X[i];
	}
}

void output(vector<int> &ans){
	for(int i = 0; i < ans.size(); i++){
		if(i) cout<<" ";
		cout<<ans[i];
	}
	cout<<endl;
}

void solve(int &N, vector<int> &X, vector<int> &ans){
	int largest_antichain;
	vector<int> used(N);
	
	ford_fulkerson ff(N*2+2);
	
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			if(i != j && X[j] % X[i] == 0) {
				ff.add_edge(i, j + N, 1);
			}
		}
		
		ff.add_edge(2 * N, i, 1);
		ff.add_edge(i + N, 2 * N + 1, 1);
	}
	
	largest_antichain = N - ff.max_flow(2 * N, 2 * N + 1);
	
	// cout<<largest_antichain<<" flow = "<<N - largest_antichain<<endl;
	
	for(int k = 0; k < N; k++){
		ff.init();
		
		ff.resize(N * 2 + 2);
		
		for(int i = 0; i < N; i++){
			if(X[k]%X[i] == 0 || X[i]%X[k] == 0) continue;
			// if(X[k]%X[i] == 0) continue;
			// if(X[i]%X[k] == 0) continue;
			for(int j = 0; j < N; j++){
				if(X[k]%X[j] == 0 || X[j]%X[k] == 0) continue;
				// if(X[k]%X[j] == 0) continue;
				// if(X[j]%X[k] == 0) continue;
				if(X[j] % X[i] == 0) {
					ff.add_edge(i, j + N, 1);
				}
			}
			
			ff.add_edge(2 * N, i, 1);
			ff.add_edge(i + N, 2 * N + 1, 1);
		}
		// cout<<"k = "<<k<<" flow = "<<ff.max_flow(2 * N, 2 * N + 1)<<endl;
		int flow = ff.max_flow(2 * N, 2 * N + 1);
		// cout<<"[] "<<N - flow - 1<<" flow = "<<flow<<" used "<<used[k]<<endl;
		// if(N - flow - 1 == largest_antichain && used[k] == false) { cout<<"k = "<<k<<endl;
		if(flow + 1 >= largest_antichain && used[k] == false) { 
		// cout<<"k = "<<k<<endl;
			ans.push_back(k+1);
			
			
			for(int i = 0; i < N; i++){
				if(X[i] % X[k] == 0) used[i] = true;
				if(X[k] % X[i] == 0) used[i] = true;
			}
		}
	}
}

signed main(){
	cout<<fixed<<setprecision(10);
	
	int N;
	vector<int> X, ans;
	
	input(N, X);
	
	solve(N, X, ans);
	
	output(ans);
	
	return 0;
}
accuracy: 0.10638297872340426
time_ms: 10
memory_kb: 3176
final_rank: 6

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

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using ll=long long;
using R=long double;
const R EPS=1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r){return(r > EPS)-(r < -EPS);}
inline R sq(R x){return sqrt(max(x,0.0L));}

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

// Problem Specific Parameter:

int n,x[110];

// Description: ??°??????????????????(?????????????°??????¨???)
// Verifyed: Many Diffrent Problem 

//Appropriately Changed
using edge=struct{int to;};
using G=vector<vector<edge>>;

//Appropriately Changed
void add_edge(G &graph,int from,int to){ 
	graph[from].push_back({to});
	graph[to].push_back({from});
}

// Description: 2??¨??°???????????????????????§??????????????°
// TimeComplexity: $ \mathcal{O}(EV) $ 
// Verifyed: AOJ GRL_7_A

int bipartite_matching(const G &graph){
	int res=0,n=graph.size();
	vector<int> match(n,-1),used(n,0);

	auto dfs=[&](int v){
        auto func=[&](int v,auto func)->int{
        	used[v]=true;
			for(auto &e:graph[v]){
				const int u=e.to,w=match[u];
				if(w<0||(!used[w] && func(w,func))){
					match[v]=u,match[u]=v;
					return true;
				}
			}
			return false;
        };
        return func(v,func);
    };

	rep(v,n){
		if(match[v]>=0) continue;
		fill(_all(used),false);
		if(dfs(v)) res++;
	}
	return res;
}


int main(void){
	cin >> n;
	rep(i,n) cin >> x[i];
	
	vector<int> ans;
	G ograph(2*n);
	
	rep(i,n)rep(j,n){
		if(i==j or x[j]%x[i]) continue;
		add_edge(ograph,i,j+n);
	}

	const int all=n-bipartite_matching(ograph);
	//cout << all << endl;

	rep(loop,all){
		rep(i,n){
			bool ok=true;			
			for(auto &it:ans){
				if(it==i) ok=false;
				if(x[i]%x[it]==0) ok=false;
				if(x[it]%x[i]==0) ok=false;
			}

			if(ok==false) continue;			
			ans.push_back(i);
			
			int y[110],m=0;

			rep(j,n){
				bool can=true;
				for(auto &it:ans){
					if(it==j) can=false;
					if(x[j]%x[it]==0) can=false;
					if(x[it]%x[j]==0) can=false;
				}
				if(can) y[m++]=x[j];
			}

			G graph(2*m);
			rep(j,m)rep(k,m){
				if(j==k or y[k]%y[j]) continue;
				add_edge(graph,j,k+m);
			}

			const int cur=m-bipartite_matching(graph);
			//cout << cur << endl;
			if(ans.size()+cur>=all) break;
			ans.pop_back();
		}
	}


	bool first=true;
	for(auto &it:ans) cout << (first?"":" ") << it+1,first=false;
	cout << endl;

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3176
final_rank: 3

code_snippet: //include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <queue>

using namespace std;

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

//repetition
//------------------------------------------
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);



void add_edge(VVI& graph, int u, int v){
  graph[u].push_back(v);
  graph[v].push_back(u);
}

bool dfs(VVI& biG, VI& match, int v, vector<bool>& used){
  used[v] = true;
  for(int i=0;i<biG[v].size();++i){
	int u = biG[v][i], w = match[u];
	if(w < 0 || (!used[w] && dfs(biG, match, w, used))){
	  match[v] = u;
	  match[u] = v;
	  return true;
	}
  }
  return false;
}

int bipartite_matching(VVI& biG, VI& match){
  int res = 0;
  int V = SZ(biG);
  fill(ALL(match), -1);
  for(int v=0;v<V;++v){
	if(match[v] < 0){
	  vector<bool> used(V, false);
	  if(dfs(biG, match, v, used))
		++res;
	}
  }
  return res;
}

int findMinPathCover(VVI& dag){
  if(dag.empty()) return 0;
  
  int N = SZ(dag);
  int V = SZ(dag) * 2;

  VVI biG(V);  
  REP(i,N) REP(j,SZ(dag[i]))
	add_edge(biG, i, N+dag[i][j]);

  VI match(V);
  int res = bipartite_matching(biG, match);
  return N - res;
}

void dfs(vector<PII>& buf, VI& ans){
  if(buf.empty()) return;
  int x = buf[0].first, idx = buf[0].second;
  buf.erase(buf.begin());
  
  vector<PII> rest;
  REP(i,SZ(buf))
	if(buf[i].first % x != 0 && x % buf[i].first != 0)
	  rest.PB(buf[i]);

  VVI dag1(SZ(rest)), dag2(SZ(buf));
  REP(i,SZ(rest)) REP(j,SZ(rest)){
	if(i == j) continue;
	if(rest[i].first % rest[j].first == 0)
	  dag1[i].PB(j);
	if(rest[j].first % rest[i].first == 0)
	  dag1[j].PB(i);
  }
  REP(i,SZ(buf)) REP(j,SZ(buf)){
	if(i == j) continue;
	if(buf[i].first % buf[j].first == 0)
	  dag2[i].PB(j);
	if(buf[j].first % buf[i].first == 0)
	  dag2[j].PB(i);
  }

  if(1 + findMinPathCover(dag1) >= findMinPathCover(dag2)){
	ans.PB(idx);
	buf = rest;
  }

  dfs(buf, ans);
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N; cin >> N;
  vector<PII> xs(N);
  REP(i,N){
	cin >> xs[i].first;
	xs[i].second = i+1;
  }

  VI ans;
  dfs(xs, ans);

  cout << ans[0];
  FOR(i,1,SZ(ans))
	cout << " " << ans[i];
  cout << endl;
  
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1468
final_rank: 2

code_snippet: #include<iostream>
#include<queue>
using namespace std;
//for maximum flow
const int N = 210;
#define INF (1 << 21)//#define INF (1LL << 60)
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
int cap[N][N];
bool visited[N];
int parent[N];
int flow[N][N];
int layer[N];
 
void make_layer(int n,int s,int t){
 queue<int> Q;
 Q.push(s);
 layer[s]=0;
 while(!Q.empty()){
   int now = Q.front();Q.pop();
   rep(i,n){
     if ( cap[now][i]-flow[now][i]>0 &&layer[i]==-1){
    layer[i]=layer[now]+1;
    Q.push(i);
     }
   }
 }
}
 
int augment(int now,int t,int n,int f){
 if ( now == t||f==0)return f;
 if ( visited[now])return 0;
 visited[now]=true;
 rep(i,n){
   if ( layer[now]<layer[i] ){
     int tmp=  augment(i,t,n,min(f,cap[now][i]-flow[now][i]));
     if ( tmp > 0){
    flow[now][i]+=tmp;
    flow[i][now]=-flow[now][i];
    visited[now]=false;
    return tmp;
     }
   }
 }
 return 0;
}
 
int dinic(int n,int s,int t){
 int ansflow=0;
 bool flag=true;
 rep(i,n)rep(j,n)flow[i][j]=0;
 while(flag){
   fill(layer,layer+n,-1);
   fill(visited,visited+n,false);
   flag = false;
   //make layer
   make_layer(n,s,t);
   if (layer[t]==-1)break;//if no such path to go to sink
 
   //find blocking flow
   for(int f=1;f;flag=true){
     f = augment(s,t,n,INF);
     if ( f == 0)break;
     ansflow+=f;
   }
 }
 return ansflow;
}

/*
  与えられた入力から二部グラフを作って、最小パス被覆の本数を求める。
*/
int solve(vector<int> &in){
  int n = in.size();
  int src = 2*n,dst = 2*n+1,node = dst+1;
  rep(i,2*n+2)rep(j,2*n+2)cap[i][j] = 0;
  rep(i,n)cap[src][i] = cap[n+i][dst] = 1;
  rep(i,n){
    rep(j,n){
      if (i != j && in[j] % in[i] == 0){
	cap[i][n+j] = 1;
      }
    }
  }
  return n-dinic(node,src,dst);
}

main(){
  int n;
  while(cin>>n && n){
    vector<int> in(n),ans;
    rep(i,n)cin>>in[i];
    int num = solve(in);
    rep(i,n){/*i番目の要素を含むかどうか。*/
      bool isok=true;
      rep(j,ans.size())if (in[i] % in[ans[j]] == 0 || in[ans[j]] % in[i] == 0)isok=false;
      if (!isok)continue;
      /*すでに選ばれた要素とi番目の要素、の倍数は自明に含んではいけないので消去しておく。*/
      vector<int> tin;
      vector<int> tmp = ans;
      tmp.push_back(i);
      REP(j,i+1,n){
	rep(k,(int)tmp.size()){
	  if (in[j] % in[tmp[k]] == 0 || in[tmp[k]] % in[j] == 0)goto end;
	}
	tin.push_back(in[j]);
      end:;
      }
      rep(j,tmp.size())tin.push_back(in[tmp[j]]);
      int tans = solve(tin);
      if (tans == num)ans.push_back(i);
    }
    rep(i,ans.size()){
      if (i)cout << " " ;
      cout << ans[i]+1;
    }
    cout << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1