#include <cstdio>
#include <cstring>
#include <algorithm>
#define repu(i,x,y) for (int i=x; i<=y; ++i)
#define repd(i,x,y) for (int i=x; i>=y; --i)
using namespace std;

int n,a[2010];
bool flag[2010];
struct edge
{
    int v;
    edge *nxt;
} pool[4000100],*tp=pool,*fst[2010];
struct data
{
    int n,a[2010];
    void add(int x)
    {
        repd(i,n,1)
            a[i+1]=a[i];
        a[1]=x,++n;
    }
    void merge(data &b)
    {
        static int c[2010];
        int m=0;
        for (int i=1,j=1; i<=n || j<=b.n;)
            if (i<=n && (j>b.n || a[i]>b.a[j]))
                c[++m]=a[i++];
            else
                c[++m]=b.a[j++];
        memcpy(a,c,sizeof(a)),n=m;
    }
} f[2010],ans;

int gcd(int x,int y)
{
    for (int t; t=x%y; x=y,y=t);
    return y;
}

void dfs(int x)
{
    flag[x]=1;
    for (edge *i=fst[x]; i; i=i->nxt)
        if (!flag[i->v])
            dfs(i->v),f[x].merge(f[i->v]);
    f[x].add(x);
}

int main()
{
    scanf("%d",&n);
    repu(i,1,n)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    repu(i,1,n)
        repd(j,n,1)
            if (i!=j && gcd(a[i],a[j])>1)
                *tp=(edge){j,fst[i]},fst[i]=tp++;
    repu(i,1,n)
        if (!flag[i])
            dfs(i),ans.merge(f[i]);
    repu(i,1,n)
        printf("%d ",a[ans.a[i]]);
    return 0;
}