// Slower C++ solution:
#include<iostream>

#include<sstream>

#include<fstream>

#include<cstring>

#include<cmath>

#include<ctime>

#include<cstdio>

#include<cstdlib>

#include<string>

#include<string.h>

#include<math.h>

#include<cassert>

#include<iomanip>

#include<utility>

#include<bitset>

#include<set>

#include<map>

#include<list>

#include<queue>

#include<deque>

#include<stack>

#include<vector>

#include<functional>

#include<algorithm>

//#include<memory.h>

#include<assert.h>

#include<numeric>

#include<limits.h>

using namespace std;

int n;

int a[2005];

bool e[2005][2005];

bool vis[2005];

vector<int>t,res,g[2005],ans[2005];

int gcd(int x,int y){if(x%y)return gcd(y,x%y);else return y;}

void dfs(int x)

{

	if(x==n)

	{

		for(int i=0;i<n;i++)

		{

			if(vis[i])continue;

			g[n].push_back(i);

			t.push_back(i);

			dfs(i);

		}

	}

	vis[x]=1;

	for(int i=0;i<n;i++)if(e[x][i]&&!vis[i])

	{

		g[x].push_back(i);

		t.push_back(i);

		dfs(i);

	}

}

int main()

{

	scanf("%d",&n);

	for(int i=0;i<n;i++)scanf("%d",&a[i]);

	sort(a,a+n);

	for(int i=0;i<n;i++)vis[i]=false;

	for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(gcd(a[i],a[j])!=1)e[i][j]=1;else e[i][j]=0;

	t.push_back(n);

	dfs(n);

	for(int i=n;i>=0;i--)

	{

		int x=t[i];

		for(int j=0;j<g[x].size();j++)

		{

			int y=g[x][j];

			res.clear();

			for(int k1=0,k2=0;k1<ans[x].size()||k2<ans[y].size();)if(k2==ans[y].size()||(k1<ans[x].size()&&ans[x][k1]>ans[y][k2]))res.push_back(ans[x][k1++]);else res.push_back(ans[y][k2++]);

			ans[x]=res;

		}

		ans[x].insert(ans[x].begin(),x);

	}

	for(int i=1;i<=n;i++)

	{

		printf("%d",a[ans[n][i]]);

		if(i==n)puts("");else printf(" ");

	}

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.102832298240238x):
// =================================

//   author: M_sea

//   website: http://m-sea-blog.com/

// =================================

#include <algorithm>

#include <iostream>

#include <cstdlib>

#include <cstring>

#include <cstdio>

#include <cmath>

#include <queue>

#define re register

using namespace std;



inline int read() {

    int X=0,w=1; char c=getchar();

    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }

    while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();

    return X*w;

}



const int N=2000+10;



struct Edge { int v,nxt; } e[N];

int head[N];



inline void addEdge(int u,int v) {

    static int cnt=0;

    e[++cnt]=(Edge){v,head[u]},head[u]=cnt;

}



int n;

int a[N],vis[N],deg[N];

int G[N][N];



inline void dfs(int u) {

    vis[u]=1;

    for (re int i=1;i<=n;++i) {

        if (vis[i]||!G[u][i]) continue;

        ++deg[i],addEdge(u,i);

        dfs(i);

    }

}



inline void topsort() {

    priority_queue<int> Q;

    for (re int i=1;i<=n;++i)

        if (!deg[i]) Q.push(i);

    while (!Q.empty()) {

        int u=Q.top(); Q.pop();

        printf("%d ",a[u]);

        for (re int i=head[u];i;i=e[i].nxt) Q.push(e[i].v);

    }

}



int main() {

    n=read();

    for (re int i=1;i<=n;++i) a[i]=read();

    sort(a+1,a+n+1);

    for (re int i=1;i<=n;++i)

        for (re int j=i+1;j<=n;++j) {

            if (__gcd(a[i],a[j])==1) continue;

            G[i][j]=G[j][i]=1;

        }

    for (re int i=1;i<=n;++i)

        if (!vis[i]) dfs(i);

    topsort();

    return 0;

}