#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define sz(s) ((int) ((s).size()))

#ifdef DEBUG
#define eprintf(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#else
#define eprintf(...) ;
#endif

typedef long long ll;
typedef long double ld;

const int inf = (int) 1.01e9;
const ld eps = 1e-11;
const ld pi = acos(-1.0L);

mt19937 mrand(random_device{} ());
int rnd(int x) {
  return mrand() % x;
}

const int mod = (int) 1e9 + 7;

void add(int & x, int y) {
  if ((x += y) >= mod) {
    x -= mod;
  }
}

int sum(int x, int y) {
  add(x, y);
  return x;
}

int mult(int x, int y) {
  return (ll) x * y % mod;
}

int power(int x, ll p) {
  int res = 1;
  while (p) {
    if (p & 1) {
      res = mult(res, x);
    }
    x = mult(x, x);
    p >>= 1;
  }
  return res;
}

void precalc() {
}

const int maxn = 2e3 + 100;

int n;
int a[maxn];

bool read() {
  if (scanf("%d", &n) < 1) {
    return false;
  }
  for (int i = 0; i < n; i++) {
    scanf("%d", a + i);
  }
  return true;
}

int par[maxn], ranks[maxn];
int waiting[maxn];
int alive[maxn];
int mns[maxn];
int maxu;

int getpar(int a) {
  if (par[a] == a) {
    return a;
  } else {
    return par[a] = getpar(par[a]);
  }
}

void myUnion(int a, int b) {
  a = getpar(a);
  b = getpar(b);
  if (a == b) {
    return;
  }
  if (ranks[a] == ranks[b]) {
    ++ranks[a];
  }
  if (ranks[a] < ranks[b]) {
    swap(a, b);
  }
  par[b] = a;
}

int g[maxn][maxn];

void solve() {
  sort(a, a + n);
  map<int, vector<int> > comps;
  for (int i = 0; i < n; i++) {
    int cur = a[i];
    for (int j = 2; j * j <= cur; j++) {
      if (cur % j == 0) {
        comps[j].pb(i);
        while (cur % j == 0) {
          cur /= j;
        }
      }
    }
    if (cur > 1) {
      comps[cur].pb(i);
    }
  }
  for (auto & v : comps) {
    for (auto i : v.second) {
      for (auto j : v.second) {
        g[i][j] = 1;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    alive[i] = 1;
    waiting[i] = 0;
  }
  vector<int> ans;
  for (int it = 0; it < n; it++) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      ranks[i] = 0;
    }
    for (auto & v : comps) {
      int was = -1;
      for (auto i : v.second) {
        if (!alive[i]) {
          continue;
        }
        if (was != -1) {
          myUnion(was, i);
        }
        was = i;
      }
    }
    for (int i = 0; i < n; i++) {
      mns[i] = 1e9;
    }
    for (int i = 0; i < n; i++) {
      if (alive[i] && !waiting[i]) {
        int p = getpar(i);
        mns[p] = min(mns[p], i);
      }
    }
    int cur = 0;
    for (int i = 0; i < n; i++) {
      if (alive[i]) {
        cur = max(cur, mns[getpar(i)]);
      }
    }
    ans.pb(cur);
    alive[cur] = 0;
    for (int i = 0; i < n; i++) {
      if (alive[i]) {
        if (g[cur][i]) {
          waiting[i] = 0;
        } else if (a[i] > a[cur]) {
          waiting[i] = 1;
        }
      }
    }
  }
  assert(sz(ans) == n);
  for (int i = 0; i < n; i++) {
    printf("%d%c", a[ans[i]], " \n"[i == n - 1]);
  }
}

int main() {
  precalc();
#ifdef DEBUG
  assert(freopen("text.in", "r", stdin));
  assert(freopen("text.out", "w", stdout));
#endif

  while (read()) {
    solve();
#ifdef DEBUG
    eprintf("Time: %.3f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
  }
  return 0;
}



Measured memory_bytes: 16768