#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>

using namespace std;

mt19937 mrand(random_device{} ()); 

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

typedef long double ld;
typedef long long ll;

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

#define pb push_back
#define mp make_pair
#define sz(x) ((int) (x).size())
#define TASK "text"

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

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

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

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

int myPower(int x, int pw) {
  int res = 1;
  for (; pw; pw >>= 1) {
    if (pw & 1) {
      res = mult(res, x);
    }
    x = mult(x, x);
  }
  return res;
}

void precalc() {
}


const int maxn = 2010;
int a[maxn];

int n;

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

vector<int> qs[maxn];

int ans[maxn];
int used[maxn];

map<int, int> pids;
int cnt;

int getpid(int p) {
  auto iter = pids.find(p);
  if (iter == pids.end()) {
    pids[p] = cnt;
    return cnt++;
  }
  return iter->second;
}

const int maxv = maxn * 6;
int pr[maxv], w[maxv];

int get(int v) {
  return pr[v] == v ? v : (pr[v] = get(pr[v]));
}

void myUnion(int a, int b) {
  a = get(a), b = get(b);
  if (a == b) {
    return;
  }

  if (w[a] == w[b]) {
    ++w[a];
  }
  if (w[a] < w[b]) {
    swap(a, b);
  }
  pr[b] = a;
}

int last[maxv];
int where[maxn];

bool was[maxv];

void solve() {
  sort(a, a + n);

  pids.clear();
  cnt = 0;
  for (int i = 0; i < n; ++i) {
    qs[i].clear();

    int x = a[i];
    for (int p = 2; p * p <= x; ++p) {
      if (x % p) {
        continue;
      }
      while (x % p == 0) {
        x /= p;
      }
      qs[i].pb(getpid(p));
    }
    if (x > 1) {
      qs[i].pb(getpid(x));
    }
  }

  for (int i = 0; i < n; ++i) {
    used[i] = 0;
  }

  for (int i = 0; i < cnt; ++i) {
    last[i] = -1;
  }

  for (int iter = 0; iter < n; ++iter) {
    assert(n + cnt <= maxv);
    for (int i = 0; i < n + cnt; ++i) {
      pr[i] = i, w[i] = 0;
      was[i] = 0;
    }

    for (int i = 0; i < n; ++i) {
      if (!used[i]) {
        for (int id : qs[i]) {
          myUnion(i, id + n);
        }
      }
    }

    //eprintf("iter = %d\n", iter);
    ans[iter] = -1;
    int mxlow = -1;
    for (int val = 0; val < n; ++val) {
      if (used[val]) {
        mxlow = max(mxlow, where[val]);
        continue;
      }
      int lastb = -1;
      for (int id : qs[val]) {
        lastb = max(lastb, last[id]);
      }
      if (lastb >= mxlow) {
        int root = get(val);
        if (!was[root]) {
          was[root] = 1;
          ans[iter] = max(ans[iter], val);
        }
      }
    }

    assert(ans[iter] != -1);
    used[ans[iter]] = 1;
    where[ans[iter]] = iter;
    for (int id : qs[ans[iter]]) {
      last[id] = iter;
    }
  }

  for (int i = 0; i < n; ++i) {
    printf("%d%c", a[ans[i]], " \n"[i == n - 1]);
  }
}

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

  while (1) {
    if (!read()) {
      break;
    }
    solve();
#ifdef DEBUG
    eprintf("Time %.2f\n", (double) clock() / CLOCKS_PER_SEC);
#endif
  }
  return 0;
}


Measured memory_bytes: 640