#!/usr/bin/env python
from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

def prime_sieve(n):
    """returns a sieve of primes >= 5 and < n"""
    flag = n % 6 == 2
    sieve = bytearray((n // 3 + flag >> 3) + 1)
    for i in range(1, int(n**0.5) // 3 + 1):
        if not (sieve[i >> 3] >> (i & 7)) & 1:
            k = (3 * i + 1) | 1
            for j in range(k * k // 3, n // 3 + flag, 2 * k):
                sieve[j >> 3] |= 1 << (j & 7)
            for j in range(k * (k - 2 * (i & 1) + 4) // 3, n // 3 + flag, 2 * k):
                sieve[j >> 3] |= 1 << (j & 7)
    return sieve

def prime_list(n):
    """returns a list of primes <= n"""
    res = []
    if n > 1:
        res.append(2)
    if n > 2:
        res.append(3)
    if n > 4:
        sieve = prime_sieve(n + 1)
        res.extend(3 * i + 1 | 1 for i in range(1, (n + 1) // 3 + (n % 6 == 1)) if not (sieve[i >> 3] >> (i & 7)) & 1)
    return res

from collections import defaultdict
def main():
    n = read_int()
    nums = read_int_array()
    nums.sort()
    primes = prime_list(2750131)
    prime_index = {x: i+1 for i, x in enumerate(primes)}
    out = []
    to_del = defaultdict(int)
    while nums:
        x = nums.pop()
        if to_del.get(x, 0) > 0:
            to_del[x] -= 1
            continue
        if x in prime_index:
            i = prime_index[x]
            out.append(i)
            to_del[i] += 1
        else:
            out.append(x)
            for i, y in enumerate(primes):
                if x % y == 0:
                    to_del[x // y] += 1
                    break
    print(' '.join(str(x) for x in out))

# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

# endregion

if __name__ == "__main__":
    main()


#!/usr/bin/env python
from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

def prime_sieve(n):
    """returns a sieve of primes >= 5 and < n"""
    flag = n % 6 == 2
    sieve = bytearray((n // 3 + flag >> 3) + 1)
    for i in range(1, int(n**0.5) // 3 + 1):
        if not (sieve[i >> 3] >> (i & 7)) & 1:
            k = (3 * i + 1) | 1
            for j in range(k * k // 3, n // 3 + flag, 2 * k):
                sieve[j >> 3] |= 1 << (j & 7)
            for j in range(k * (k - 2 * (i & 1) + 4) // 3, n // 3 + flag, 2 * k):
                sieve[j >> 3] |= 1 << (j & 7)
    return sieve

def prime_list(n):
    """returns a list of primes <= n"""
    res = []
    if n > 1:
        res.append(2)
    if n > 2:
        res.append(3)
    if n > 4:
        sieve = prime_sieve(n + 1)
        res.extend(3 * i + 1 | 1 for i in range(1, (n + 1) // 3 + (n % 6 == 1)) if not (sieve[i >> 3] >> (i & 7)) & 1)
    return res

from collections import defaultdict
def main():
    _ = read_int()
    nums = sorted(read_int_array())
    primes = prime_list(2750131)
    prime_index = {x: i+1 for i, x in enumerate(primes)}
    out = []
    to_del = defaultdict(int)
    for x in reversed(nums):
        if to_del.get(x, 0) > 0:
            to_del[x] -= 1
            continue
        if x in prime_index:
            i = prime_index[x]
            out.append(i)
            to_del[i] += 1
        else:
            out.append(x)
            for i, y in enumerate(primes):
                if x % y == 0:
                    to_del[x // y] += 1
                    break
    print(' '.join(str(x) for x in out))

# region fastio

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

# endregion

if __name__ == "__main__":
    main()


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

import collections,math

n=int(input())
a=list(map(int, input().split()))
a.sort(reverse=True)
primes_arr=[-1]
maxi = 2750131+1
primes_sieve=[0 for _ in range(maxi)]
def sieve():
    for i in range(2, maxi):
        if not primes_sieve[i]:
            primes_arr.append(i)
            primes_sieve[i] = 1
            for j in range(i*i, maxi, i):
                if not primes_sieve[j]:
                    primes_sieve[j] = i

sieve()
# print(primes_sieve[:20])
d=collections.defaultdict(int)
z=collections.defaultdict(int)

ans=[]
primes = []
for i in range(n*2):
    x=a[i]//primes_sieve[a[i]]
    if d[a[i]] > 0:
        d[a[i]]-=1
    elif x!=a[i]:
        d[x]+=1
        ans.append(a[i])
    else:
        primes.append(a[i])
primes=primes[::-1]
for i in range(len(primes)):
    if z[primes[i]]>0:
        z[primes[i]]-=1
    else:
        z[primes_arr[primes[i]]]+=1
        ans.append(primes[i])

print(' '.join([str(x) for x in ans]))


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

from collections import Counter
def rwh_primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

primes = rwh_primes(2750132)
sprimes = set(primes)

def dl(x):
  if x in sprimes:
    return None
  for p in primes:
    if x % p == 0:
      return x // p
    elif p * p > x:
      return None

n = int(input())
a = sorted(map(int, input().split()), reverse = True)
sa = set(a)
r = []
x = Counter()
p1 = []
p2 = []
for v in a:
  if v in x and x[v] > 0:
    x[v] -= 1
    continue
  d = dl(v)
  if d and d in sa:
    x[d] += 1
    r.append(v)
  elif v in sprimes:
    p1.append(v)
  else:
    p2.append(v)
x = Counter()
y = 0
for v in reversed(p1):
  if v in x and x[v] > 0:
    x[v] -= 1
    continue
  r.append(v)
  if v < len(primes)+1:
    x[primes[v-1]] += 1
  else:
    y += 1
z = (len(p2) - y)//2
r.extend(p2[::-1][y:y+z])
print(*r)


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

def chuli(n):
    global sushu
    if (n in sushu):
        return 0
    for i in sushu:
        if (i*i > n):
            break
        if (n%i == 0):
            return (n//i)

sushu = [2,3]
l = 1
i = 4
while (l < 200000):
    i += 1
    j = 0
    k = 1
    while(k*k <= i):
        k = sushu[j]
        j += 1
        if (i%k == 0):
            break
    else:
        sushu.append(i)
    l += 1

n = read_int
l = read_int_array()
li = []
l2 = []

l = sorted(l)

for i in range(2*n):
    if (l):
        c = l[-1]
    elif (c == 3):
        break
    else:
        break
    if (c>200000):
        l2.append(l.pop())
        continue
    chu = chuli(c)
    if (chu):
        l.remove(chu)
        li.append(l.pop())
    else:
        l2.append(l.pop())

le = len(l2)
for _ in range(le):
    if (l2):
        i = l2[-1]
    else:
        break
    if (i<17985):
        l2.remove(sushu[i-1])
        li.append(l2.pop())
    else:
        break
while(len(li)<n):
    li.append(l2.pop())
print(' '.join([str(i) for i in li]))


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

import sys
sys.setrecursionlimit(10**5+1)

inf     =  int(10 ** 20)
max_val =  inf
min_val = -inf

RW  = lambda : sys.stdin.readline().strip()
RI  = lambda : int(RW())
RMI = lambda : [int(x) for x in sys.stdin.readline().strip().split()]
RWI = lambda : [x for x in sys.stdin.readline().strip().split()]

LIMIT = 2750132
primes = [0] * LIMIT
pindex = [0] * LIMIT

index = 1
for i in range(2, LIMIT):
    if primes[i] == 0:
        pindex[i] = index
        index += 1
        for j in range(i*i, LIMIT, i):
            if primes[j] == 0:
                primes[j] = i

lens = RI()
arrs = sorted(RMI())[::-1]
d = dict()
for x in arrs:
    if d.get(x, 0) == 0:
        if primes[x] == 0:
            print(pindex[x], end = " ")
            d[pindex[x]] = d.get(pindex[x], 0) + 1
        else:
            print(x, end = " ")
            d[x//primes[x]] = d.get(x//primes[x], 0) + 1
    else:
        d[x] = d.get(x, 0) - 1


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

def chuli(n):
    global sushu
    if (n in sushu):
        return 0
    for i in sushu:
        if (i*i > n):
            break
        if (n%i == 0):
            return (n//i)

sushu = [2,3]
l = 1
i = 4
while (l < 200000):
    i += 1
    j = 0
    k = 1
    while(k*k <= i):
        k = sushu[j]
        j += 1
        if (i%k == 0):
            break
    else:
        sushu.append(i)
    l += 1

n = int(input())
l = readnumbers()
li = []
l2 = []

l = sorted(l)

for i in range(2*n):
    if (l):
        c = l[-1]
    elif (c == 3):
        break
    else:
        break
    if (c>200000):
        l2.append(l.pop())
        continue
    chu = chuli(c)
    if (chu):
        l.remove(chu)
        li.append(l.pop())
    else:
        l2.append(l.pop())

le = len(l2)
for _ in range(le):
    if (l2):
        i = l2[-1]
    else:
        break
    if (i<17985):
        l2.remove(sushu[i-1])
        li.append(l2.pop())
    else:
        break
while(len(li)<n):
    li.append(l2.pop())
print(' '.join([str(i) for i in li]))


#Python 2 and 3 footer by Pajenegod and c1729

#Note because cf runs old PyPy3 version which doesn't have the sped up
#unicode strings, PyPy3 strings will many times be slower than pypy2.
#There is a way to get around this by using binary strings in PyPy3
#but its syntax is different which makes it kind of a mess to use.

#So on cf, use PyPy2 for best string performance.

from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

# region fastio

BUFSIZE = 8192
input = lambda: sys.stdin.readline().rstrip("\r\n")

read = input
read_int = lambda: int(input())
read_array = lambda sep=None, maxsplit=-1: input().split(sep, maxsplit)
read_int_array = lambda: [int(a) for a in read_array()]

def readnumbers(zero = 0):
    conv = ord
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

def chuli(n):
    global sushu
    if (n in sushu):
        return 0
    for i in sushu:
        if (i*i > n):
            break
        if (n%i == 0):
            return (n//i)

sushu = [2,3]
l = 1
i = 4
while (l < 200000):
    i += 1
    j = 0
    k = 1
    while(k*k <= i):
        k = sushu[j]
        j += 1
        if (i%k == 0):
            break
    else:
        sushu.append(i)
    l += 1

n = read_int()
l = read_int_array()
li = []
l2 = []

l = sorted(l)
for i in range(2*n):
    if (l):
        c = l[-1]
    elif (c == 3):
        break
    else:
        break
    if (c>200000):
        l2.append(l.pop())
        continue
    chu = chuli(c)
    if (chu):
        l.remove(chu)
        li.append(l.pop())
    else:
        l2.append(l.pop())

le = len(l2)
for _ in range(le):
    if (l2):
        i = l2[-1]
    else:
        break
    if (i<17985):
        l2.remove(sushu[i-1])
        li.append(l2.pop())
    else:
        break
while(len(li)<n):
    li.append(l2.pop())
print(' '.join([str(i) for i in li]))


#!/usr/bin/env python
from collections import Counter
from math import sqrt
m = 2750131 + 100

f = list(range(m))

for d in range(2, int(sqrt(m)) + 10):
    if f[d] == d:
        i, k = 2, d << 1
        while k < m:
            if f[k] == k:
                f[k] = i
            k += d
            i += 1

np = list(range(m))
c = 1
for i in range(2, m):
    if f[i] == i:
        np[i] = c
        c += 1

n = int(input())
b = sorted(list(map(int, input().split())), reverse=True)
d = Counter(b)
a = []
i, la = 0, 0
while la < n:
    if d[b[i]] > 0:
        la += 1
        if f[b[i]] == b[i]:
            a.append(np[b[i]])
            d[b[i]] -= 1
            d[np[b[i]]] -= 1
        else:
            a.append(b[i])
            d[b[i]] -= 1
            d[f[b[i]]] -= 1
    i += 1
print(*a)


n = int(input())
t = map(int, input().split())
n = 2*n
M = 2750131 + 10
d = [0]*M
nr = [0]*M
akt_nr = 1

for i in range(2, M):
	if d[i] == 0:
		d[i] = 1
		nr[i] = akt_nr
		akt_nr += 1
		for j in range(i*i, M, i):
			if d[j] == 0:
				d[j] = j//i

count = [0]*M
numbers = []
for x in t:
	if count[x] == 0:
		numbers.append(x)
	count[x] += 1
numbers.sort()
ans = []
for i in range(len(numbers)-1, 0, -1):
	x = numbers[i]
	#print(x)
	while count[x] > 0:
		count[x] -= 1
		if d[x] == 1:
			ans.append(nr[x])
			count[nr[x]] -= 1
			#print(nr[x])
		else:
			ans.append(x)
			count[d[x]] -= 1
			#print(d[x])

print(*ans)


n = int(input())
t = map(int, input().split())
n = 2*n
M = 2750131 + 10
d = [0]*M
nr = [0]*M
akt_nr = 1

for i in range(2, M):
	if d[i] == 0:
		d[i] = 1
		nr[i] = akt_nr
		akt_nr += 1
		for j in range(i*i, M, i):
			d[j] = j//i

count = [0]*M
numbers = []
for x in t:
	if count[x] == 0:
		numbers.append(x)
	count[x] += 1
numbers.sort()
ans = []
for i in range(len(numbers)-1, 0, -1):
	x = numbers[i]
	#print(x)
	while count[x] > 0:
		count[x] -= 1
		if d[x] == 1:
			ans.append(nr[x])
			count[nr[x]] -= 1
		else:
			ans.append(x)
			count[d[x]] -= 1

print(*ans)


from collections import Counter

lim = 2750131 + 10# 2 * 10**6 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            arr[i] = primes[i]
    return arr

if __name__ == '__main__':
    n = int(input())
    bb = list(map(int, input().split()))
    bb.sort(reverse=True)
    cnt = Counter(bb)
    e = erato()
    res = []
    for b in bb:
        if cnt[e[b]] > 0 and cnt[b] > 0:
            res.append(str(b))
            cnt.subtract({b:1, e[b]:1})

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


from collections import Counter

lim = 2750131 + 10# 2 * 10**6 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            arr[i] = primes[i]
    return arr

if __name__ == '__main__':
    n = int(input())
    bb = list(map(int, input().split()))
    bb.sort()
    cnt = Counter(bb)
    e = erato()
    res = []
    for b in bb:
        if cnt[e[b]] > 0 and cnt[b] > 0:
            res.append(str(b))
            cnt.subtract({b:1, e[b]:1})

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


from collections import Counter

lim = 2750131 + 10# 2 * 10**6 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            arr[i] = primes[i]
    return arr

if __name__ == '__main__':
    n = int(input())
    bb = list(map(int, input().split()))
    cnt = Counter(bb)
    e = erato()
    res = []
    for b in bb:
        if cnt[e[b]] > 0 and cnt[b] > 0:
            res.append(str(b))
            cnt.subtract({b:1, e[b]:1})

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


lim = 2750131 + 10# 2 * 10**6 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            arr[i] = primes[i]
    return arr

if __name__ == '__main__':
    n = int(input())
    bb = set(map(int, input().split()))
    e = erato()
    res = []
    for b in bb:
        if e[b] in bb:
            res.append(str(b))

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


lim = 2750131 + 10# 2 * 10**6 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    d = {}
    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            d[i] = primes[i]
        else:
            d[i] = arr[i]

    return d

if __name__ == '__main__':
    n = int(input())
    bb = set(map(int, input().split()))
    e = erato()
    res = []
    for b in bb:
        if b in e.keys() and e[b] in bb:
            res.append(str(b))

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


lim = 2 * 10**7 + 2

def erato():
    arr = [None] * lim
    arr[1] = 1
    primes = [1]
    for i in range(2, lim):
        if not arr[i]:
            primes.append(i)
            arr[i] = 1
            for j in range(i * 2, lim, i):
                if not arr[j]:
                    arr[j] = j // i

    d = {}
    s = set(primes)
    for i in range(1, len(primes)):
        if i in s:
            d[i] = primes[i]
        else:
            d[i] = arr[i]

    return d

if __name__ == '__main__':
    n = int(input())
    bb = set(map(int, input().split()))
    e = erato()
    res = []
    for b in bb:
        if b in e.keys() and e[b] in bb:
            res.append(str(b))

    # res = list(map(lambda x: str(e[x]), bb))
    print(" ".join(res))


from sys import stdin, stdout
import collections
import math
import heapq

def primes(n):
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

p = primes(2750132)

look_up = {}

i = 1
for num in p:
    look_up[num] = i
    i += 1

N = int(input())
#N,M = [int(x) for x in stdin.readline().split()]

arr = [int(x) for x in stdin.readline().split()]

arr.sort()

h = []

freq = {}

for num in arr:
    heapq.heappush(h, -num)
    freq[num] = 0

#ans = []
while h:
    num = -heapq.heappop(h)
    if freq[num]>0:
        freq[num] -= 1
        continue

    if num in look_up:
        #ans.append(look_up[num])
        print(look_up[num],end=' ')
        freq[look_up[num]] += 1
    else:
        for i in range(2,num):
            if num%i==0:
                print(num,end=' ')
                freq[num//i] += 1
                break


# @author

import sys

class DRecoverIt:
    def gd(selfs, x):
        for i in range(2, int(x ** .5) + 1):
            if x % i == 0:
                return x // i

    def sieve(self, prime):
        for i in range(2, int(len(prime) ** .5) + 1):
            if not prime[i]: continue
            m = 2
            while m * i < len(prime):
                prime[m * i] = False
                m += 1

        return prime

    def solve(self):
        is_prime = [True] * 2750135
        is_prime[0] = False
        is_prime[1] = False
        self.sieve(is_prime)
        p = [-1]
        for i in range(len(is_prime)):
            if is_prime[i]:
                p.append(i)

        n = int(input())
        b = [int(item) for item in input().split()]
        b.sort(reverse=True)
        cnt = {x : 0 for x in b}
        for x in b:
            cnt[x] += 1

        p_order = {}
        for i in range(1, len(p)):
            p_order[p[i]] = i

        res = []
        # print(p[:10])
        for i in range(2 * n):
            if cnt[b[i]] == 0:
                continue
            if is_prime[b[i]]:
                # print(b[i], cnt[b[i]], res)
                if b[i] < len(p) and p[b[i]] in cnt and cnt[p[b[i]]] > 0:
                    # print(p[b[i]], "*")
                    res.append(b[i])
                    cnt[p[b[i]]] -= 1
                    cnt[b[i]] -= 1
                elif p_order[b[i]] in cnt and cnt[p_order[b[i]]] > 0:
                    # print(p_order[b[i]])
                    res.append(p_order[b[i]])
                    cnt[p_order[b[i]]] -= 1
                    cnt[b[i]] -= 1
            else:
                d = self.gd(b[i])
                assert(d in cnt)
                res.append(b[i])
                cnt[b[i]] -= 1
                cnt[d] -= 1

        print(*res)

solver = DRecoverIt()
input = sys.stdin.readline

solver.solve()


from bisect import bisect_left, bisect_right
from collections import Counter
import sys
input = sys.stdin.readline

N = int(input())
B = list(map(int, input().split()))

# Mまでの素数全列挙(エラトステネスの篩)
def primes(M):
    is_prime = [-1 for _ in range(M+1)]
    for m in range(2, M+1):
        if is_prime[m] == -1:
            is_prime[m] = 1
            l = 2
            while m*l <= M:
                is_prime[m*l] = 0
                l += 1
    primes = []
    for p in range(2, M+1):
        if is_prime[p] == 1:
            primes.append(p)
    return primes, is_prime

primes, is_prime = primes(2750140)

B.sort(reverse=True)
C = Counter(B)

A = []
for b in B:
    if C[b] == 0:
        continue
    if is_prime[b]:
        a = bisect_right(primes, b)
        C[a] -= 1
        C[b] -= 1
        A.append(a)
    else:
        for p in primes:
            if b % p == 0:
                a = b//p
                break
        C[a] -= 1
        C[b] -= 1
        A.append(b)

for a in A:
    print(a, end=' ')
print()


n= int(input())
a = [int(i) for i in input().split()]
N = 3000000
prime = [True]*N
ind = [0]*N
gf = [i for i in range(N)]
def sieve(n):
    p = 2
    while (p * p <= n):

        # If prime[p] is not changed, then it is a prime
        if (prime[p] == True):

            # Update all multiples of p
            for i in range(p * p, n+1, p):
                prime[i] = False
                gf[i] = min(p,gf[i])
        p += 1
    for i in range(2,N):
        ind[i] = ind[i-1]+prime[i]
        gf[i] = i//gf[i]

sieve(N-1)

ans = []
cnt = [0]*N
for i in a:
    cnt[i]+=1
for i in range(N-1,0,-1):
    while(cnt[i]>0):
        if prime[i]:
            cnt[ind[i]] -=1
            ans.append(ind[i])
        else:
            cnt[gf[i]] -=1
            ans.append(i)
        cnt[i]-=1
print(" ".join(str(x) for x in ans))


n= int(input())
a = [int(i) for i in input().split()]
N = 3000000
prime = [True]*N
ind = [0]*N
gf = [i for i in range(N)]
def sieve(n):
    p = 2
    while (p * p <= n):

        # If prime[p] is not changed, then it is a prime
        if (prime[p] == True):

            # Update all multiples of p
            for i in range(p * p, n+1, p):
                prime[i] = False
                gf[i] = min(i,gf[i])
        p += 1
    for i in range(2,N):
        ind[i] = ind[i-1]+prime[i]
        gf[i] = i//gf[i]

sieve(N-1)

ans = []
cnt = [0]*N
for i in a:
    cnt[i]+=1
for i in range(N-1,0,-1):
    while(cnt[i]>0):
        if prime[i]:
            cnt[ind[i]] -=1
            ans.append(ind[i])
        else:
            cnt[gf[i]] -=1
            ans.append(i)
        cnt[i]-=1
print(" ".join(str(x) for x in ans))


from collections import *
N = int(3e6)
prime = [0 for i in range(N+8)]
p = [0 for i in range(N+8)]
ct = 1
i = 2
while(i*i <= N):
	if(prime[i] == 0):
		p[i] = ct
		ct += 1
		for j in range(i*i,N,i):
			if(prime[j] == 0):
				prime[j] = i
	i += 1
for i in range(i,N+8):
	if(prime[i] == 0):
		p[i] = ct
		ct += 1

n = int(input())
n = 2*n
b = list(map(int,input().split()))
b.sort()
d = Counter(b)
a = []
for i in range(n-1,-1,-1):
	if(d[b[i]] == 0): continue
	if(prime[b[i]] == 0):
		a.append(p[b[i]])
		d[p[b[i]]] -= 1
	else:
		a.append(b[i])
		d[b[i]//prime[b[i]]] -= 1
	d[b[i]] -= 1
	#print(b[i],a)
for i in a:
	print(i,end = " ")
print()


#include<bits/stdc++.h>
using namespace std;

#define boost ios_base::sync_with_stdio(0);cin.tie(NULL);
#define v  vector
#define li long long int
#define mod 1000000007

int main() {

	int a1[11] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };

	int t;
	cin >> t;
	while (t--) {
		int pp[11] = { 0 };
		int n, a2, i;
		cin >> n;
		int a3[n];
		int count = 0;
		for (int j = 0; j < n; j++) {
			i = 0;
			cin >> a2;
			while (a2 % a1[i] != 0)
				i++;

			if (pp[i] == 0) {
				pp[i] = 1;
				count++;
			}
			a3[j] = i + 1;

		}

		cout << count << endl;
		for (int x : a3)
			cout << x << " ";
		cout << endl;

	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define boost ios_base::sync_with_stdio(0);cin.tie(NULL);
#define v  vector
#define li long long int
#define mod 1000000007

int main() {

	int a1[11] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };

	int t;
	cin >> t;
	while (t--) {
		int pp[11] = { 0 };
		int pp1[11];
		int n, a2, i;

		cin >> n;
		int a3[n];
		int count = 0;
		for (int j = 0; j < n; j++) {
			i = 0;
			cin >> a2;

			while (a2 % a1[i] != 0)
				i++;

			if (pp[i] == 0) {
				pp[i] = 1;
				count++;
			}
			a3[j] = i + 1;

		}
		int j = 1;
		for (int i = 0; i < 11; i++)
			if (pp[i])
				pp1[i] = j++;

		cout << count << endl;
		cout << pp1[a3[0] - 1];
		for (int i = 1; i < n; i++)
			cout << " " << pp1[a3[i] - 1];
		cout << endl;

	}

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j);
            }
        }
        int col = 1;
        for (int i = 2; i <= 1000; i++) {
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        assert(col - 1 <= 11);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define int ll
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int32_t main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 0; i < MN; i++) s[i].clear();
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (a[j] % i == 0) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        col = 0;
        for (int i = 1; i <= n; i++) col = max(col, ans[i]);
        assert(col <= 11);
        printf("%lld\n", col);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        assert(col - 1 <= 11);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define int ll
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int32_t main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            for (int j = 2; j <= a[i]; j++) {
                if (a[i] % j == 0) freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (a[j] % i == 0) cnt++, ans[j] = col;
            }
            col++;
        }
        col = 0;
        for (int i = 1; i <= n; i++) col = max(col, ans[i]);
        assert(col <= 11);
        printf("%lld\n", col);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define int ll
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int32_t main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 0; i < MN; i++) s[i].clear();
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (ans[j]) continue;
                if (a[j] % i == 0) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        col = 0;
        for (int i = 1; i <= n; i++) col = max(col, ans[i]);
        assert(col <= 11);
        printf("%lld\n", col);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) ans[j] = col;
            }
            col++;
        }
        assert(col - 1 <= 11);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
        printf("\n");
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j);
            }
        }
        int col = 1;
        for (int i = 2; i <= 1000; i++) {
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        assert(col - 1 <= 11);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j);
            }
        }
        int col = 1;
        for (int i = 2; i <= 1000; i++) {
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define int ll
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int32_t main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 0; i < MN; i++) s[i].clear();
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        col = 0;
        for (int i = 1; i <= n; i++) col = max(col, ans[i]);
        assert(col <= 10);
        printf("%lld\n", col);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        assert(col - 1 <= 9);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        for (int i = 1; i <= n; i++) {
            s[i].clear();
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        assert(col - 1 <= 11);
        printf("%d\n", col - 1);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

#define ll long long
#define ld long double
#define int ll
#define pii pair<int, int>
#define f first
#define s second
#define readl(_s) getline(cin, (_s));
#define boost() cin.tie(0); cin.sync_with_stdio(0)

const int MN = 1005;
int n, m, a[MN], ans[MN], freq[MN];
set<int> s[MN];

bool prime(int b) {
    for (int i = 2; i * i <= b; i++) if (b % i== 0) return false;
    return true;
}

int32_t main() {
    boost();

    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        memset(freq, 0, sizeof(freq));
        memset(ans, 0, sizeof(ans));
        memset(a, 0, sizeof(a));
        for (int i = 0; i < MN; i++) s[i].clear();
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            for (int j = 2; j * j <= a[i]; j++) {
                if (a[i] % j == 0) s[i].insert(j), freq[j]++;
            }
        }
        vector<pii> v;
        for (int i = 2; i <= 1000; i++) v.push_back({freq[i], i});
        sort(v.begin(), v.end(), greater<>());
        int col = 1;
        for (pii p : v) {
            //printf("%d %d\n", p.f, p.s);
            int i = p.s;
            if (!p.f) break;
            if (!prime(i)) continue;
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                if (s[j].count(i)) cnt++, ans[j] = col;
            }
            if (cnt) col++;
        }
        col = 0;
        for (int i = 1; i <= n; i++) col = max(col, ans[i]);
        assert(col <= 11);
        printf("%lld\n", col);
        for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
    }

    return 0;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1005;
const ll MOD = 1e9+7;
ll color[N];

void build(){
	memset(color, -1, sizeof(color));
	ll c = 1;
	rep(i, 2, N){
		if(color[i]==-1){
			color[i]=c++;
			for(ll j=i*i;j<N;j+=i){
				color[j] = color[i];
			}
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	rep(i, 0, n)cin>>a[i];
	set<ll> c;
	rep(i, 0, n)c.insert(color[a[i]]);
	cout<<c.size()<<"\n";
	rep(i, 0, n)cout<<color[a[i]]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1001;
const ll MOD = 1e9+7;
ll prime[N];

void build(){
	memset(prime, 0, sizeof(prime));
	rep(i, 2, N){
		if(prime[i]==0){
			for(ll j=i*i;j<N;j+=i)
				prime[j] = i;
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	ll c[n];
	memset(c, 0, sizeof(c));
	rep(i, 0, n)cin>>a[i];
	map<ll, vi> fact;
	rep(i, 0, n){
		ll x = a[i];
		while(prime[x]!=0){
			fact[prime[x]].push_back(i);
			x/=prime[x];
		}
		fact[x].push_back(i);
	}
	ll color = 1;
	for(auto i:fact){
		ll tcolor = color;
		for(auto index:i.S){
			if(c[index]!=0){
				tcolor=c[index];
				break;
			}
		}
		if(tcolor==color)color++;
		for(auto index:i.S){
			c[index] = tcolor;
		}
	}
	set<ll> ans;
	rep(i, 0, n)ans.insert(c[i]);
	cout<<ans.size()<<"\n";
	rep(i, 0, n)cout<<c[i]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1001;
const ll MOD = 1e9+7;
ll prime[N];

void build(){
	memset(prime, 0, sizeof(prime));
	rep(i, 2, N){
		if(prime[i]==0){
			for(ll j=i*i;j<N;j+=i)
				prime[j] = i;
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	ll c[n];
	memset(c, 0, sizeof(c));
	rep(i, 0, n)cin>>a[i];
	ll color = 1;
	rep(i, 0, n){
		if(c[i]==0)c[i]=color++;
		rep(j, i+1, n){
			if(__gcd(a[i], a[j])!=1)c[j] = c[i];
		}
	}
	set<ll> ans;
	rep(i, 0, n)ans.insert(c[i]);
	cout<<ans.size()<<"\n";
	rep(i, 0, n)cout<<c[i]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1001;
const ll MOD = 1e9+7;
ll prime[N];

void build(){
	memset(prime, 0, sizeof(prime));
	rep(i, 2, N){
		if(prime[i]==0){
			for(ll j=i*i;j<N;j+=i)
				prime[j] = i;
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	ll c[n];
	memset(c, 0, sizeof(c));
	rep(i, 0, n)cin>>a[i];
	map<ll, ll> m;
	ll color = 1;
	rep(i, 0, n){
		ll sp = prime[a[i]];
		if(m[sp]==0)m[sp] = color++;
		c[i] = m[sp];
	}
	cout<<m.size()<<"\n";
	rep(i, 0, n)cout<<c[i]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1001;
const ll MOD = 1e9+7;
ll prime[N];

void build(){
	memset(prime, 0, sizeof(prime));
	rep(i, 2, N){
		if(prime[i]==0){
			for(ll j=i*i;j<N;j+=i)
				prime[j] = i;
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	ll c[n];
	memset(c, 0, sizeof(c));
	rep(i, 0, n)cin>>a[i];
	ll color = 1;
	c[0]=1;
	rep(i, 0, n){
		rep(j, i+1, n){
			if(__gcd(a[i], a[j])==1)c[j] = c[i]+1;
			else c[j] = c[i];
		}
	}
	set<ll> ans;
	rep(i, 0, n)ans.insert(c[i]);
	cout<<ans.size()<<"\n";
	rep(i, 0, n)cout<<c[i]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


// Problem: B. Composite Coloring
// Contest: Codeforces - Codeforces Round #630 (Div. 2)
// URL: https://codeforces.com/contest/1332/problem/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

//Mayank
#include "bits/stdc++.h"

#pragma GCC optimize("O2")
using namespace std;
// comment pending
#define MK_DEBUG

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef MK_DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
    #define dbg(...)
#endif

#define F first
#define S second
#define ll long long int
#define rep(i, a, b) for(ll i = (a); i < (b); i++)
#define sz(x) ((ll) (x).size())
#define all(x) (x).begin(), (x).end()
#define pii pair<ll, ll>
#define vi vector<ll>
//remember this
const ll INF = 1e18;
const ll N = 1001;
const ll MOD = 1e9+7;
ll prime[N];

void build(){
	memset(prime, 0, sizeof(prime));
	rep(i, 2, N){
		if(prime[i]==0){
			for(ll j=i*i;j<N;j+=i)
				prime[j] = i;
		}
	}
}

void solve(){
	ll n;
	cin>>n;
	ll a[n];
	ll c[n];
	memset(c, 0, sizeof(c));
	rep(i, 0, n)cin>>a[i];
	map<ll, vi> fact;
	rep(i, 0, n){
		ll x = a[i];
		while(prime[x]!=0){
			fact[prime[x]].push_back(i);
			x/=prime[x];
		}
		fact[x].push_back(i);
	}
	ll color = 1;
	for(auto i:fact){
		ll tcolor = color;
		ll f=1;
		for(auto index:i.S){
			if(c[index]!=0){
				f=0;
				tcolor=c[index];
				break;
			}
		}
		color+=f;
		for(auto index:i.S){
			c[index] = tcolor;
		}
	}
	set<ll> ans;
	rep(i, 0, n)ans.insert(c[i]);
	cout<<ans.size()<<"\n";
	rep(i, 0, n)cout<<c[i]<<" ";
	cout<<"\n";
}

int main(){
    ios_base::sync_with_stdio(false);
    #ifndef MK_DEBUG
        cin.tie(NULL);
    #endif
    ll T=1;
    build();
    cin>>T;
    rep(test, 1, T+1){
        // cout<<"Case #"<<test<<": ";
        solve();
    }
    return 0 ;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    vi v{-1,2,3,5,7,11,13,17,19,23,29,31};
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi num(n);
      vi ans(n);
      FOR(i,0,n)
        cin>>num[i];
      FOR(i,1,12)
      {
        FOR(j,0,n)
        {
            if(num[j]>v[i] && num[j]%v[i]==0 && ans[j]==0)
                ans[j]=i;
        }
      }
      FOR(i,0,n)
        cout<<ans[i]<<' ';
    cout<<endl;

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    {
      int n,k=-1;cin>>n;
      vi v(n),b(n,0);
      FOR(i,0,n)
        cin>>v[i];
      for(int i=1;i<=11;i++)
      {
        int j=0;
        while(b[j]!=0 && j<n)
            j++;
        if(j>=n)
        {
            k=i;
            break;
        }
        b[j]=i;
        for(int k=j+1;k<n;k++)
        {
            if(gcd(v[k],v[j])>1)
                b[k]=i;
        }
      }
      if(k==-1)
        cout<<11;
        else
            cout<<k-1;
        cout<<'\n';
      FOR(i,0,n)
        cout<<b[i]<<' ';
    cout<<'\n';

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int power(int x, int y, int p)
{
    int res = 1;

    x = x % p;

    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1; // y = y/2
        x = (x*x) % p;
    }
    return res;
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi v(n),b(n,0);
      FOR(i,0,n)
        cin>>v[i];
      for(int i=1;i<=11;i++)
      {
        int j=0;
        while(b[j]!=0)
            j++;
        if(j==n)
            break;
        b[j]=i;
        for(int k=j+1;k<n;k++)
        {
            if(gcd(v[k],v[j])>1)
                b[k]=i;
        }
      }
      FOR(i,0,n)
        cout<<b[i]<<' ';
    cout<<'\n';

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    vi v{-1,2,3,5,7,11,13,17,19,23,29,31};
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi num(n);
      vi ans(n);
      FOR(i,0,n)
        cin>>num[i];
      int county=0;
      int i=1;
      for(i;i<=12;i++)
      {
        FOR(j,0,n)
        {
            if(num[j]>v[i] && num[j]%v[i]==0 && ans[j]==0)
            {
                county++;
                ans[j]=i;
            }
            if(county==n)
                break;
        }
        if(county==n)
            break;
      }
      cout<<i<<'\n';
      FOR(j,0,n)
        cout<<ans[j]<<' ';
    cout<<endl;

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi v(n),b(n,0);
      FOR(i,0,n)
        cin>>v[i];
      for(int i=1;i<=11;i++)
      {
        int j=0;
        while(b[j]!=0)
            j++;
        b[j]=i;
        for(int k=j+1;k<n;k++)
        {
            if(gcd(v[k],v[j])>1)
                b[k]=i;
        }
      }
      FOR(i,0,n)
        cout<<b[i]<<' ';
    cout<<'\n';

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    vi v{LLONG_MAX,2,3,5,7,11,13,17,19,23,29,31};
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi num(n);
      vi ans(n);
      FOR(i,0,n)
        cin>>num[i];
      int i=1;
      mii m;
      int count =0;
      for(i;i<12;i++)
      {
        FOR(j,0,n)
        {
            if(num[j]>v[i] && num[j]%v[i]==0 && ans[j]==0)
            {
                if(m[v[i]]==0)
                {
                m[v[i]]++;
                count++;
                ans[j]=count;
                }
                else
                    ans[j]=count;
            }
        }

      }

      cout<<count<<'\n';
      FOR(j,0,n)
        cout<<ans[j]<<' ';
    cout<<endl;

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    vi v{LLONG_MAX,2,3,5,7,11,13,17,19,23,29,31};
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi num(n);
      vi ans(n);
      FOR(i,0,n)
        cin>>num[i];
      int i=1;
      mii m;
      for(i;i<12;i++)
      {
        FOR(j,0,n)
        {
            if(num[j]>v[i] && num[j]%v[i]==0 && ans[j]==0)
            {
                m[v[i]]++;
                ans[j]=i;
            }
        }

      }

      cout<<m.size()<<'\n';
      FOR(j,0,n)
        cout<<ans[j]<<' ';
    cout<<endl;

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi v(n),b(n,0);
      FOR(i,0,n)
        cin>>v[i];
      for(int i=1;i<=11;i++)
      {
        int j=0;
        while(b[j]!=0 && j<n)
            j++;
        if(j>=n)
            break;
        b[j]=i;
        for(int k=j+1;k<n;k++)
        {
            if(gcd(v[k],v[j])>1)
                b[k]=i;
        }
      }
      FOR(i,0,n)
        cout<<b[i]<<' ';
    cout<<'\n';

    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long int
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define mii map<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define MOD 1000000007
#define FOR(i,a,n) for(int i=a;i<n;i++)
#define FORD(i,a,n) for(int i=n-1;i>=0;i--)
#define MAX LLONG_MAX
#define MIN LLONG_MIN

using namespace std;
int gcd(int a,int b)
{
    if(a==0)
        return b;
    else
        return gcd(b%a,a);
}
int32_t main(){

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;cin>>t;
    while(t--)
    {
      int n;cin>>n;
      vi v(n),b(n);
      FOR(i,0,n)
        cin>>v[i];
      for(int i=1;i<=11;i++)
      {
        int j=0;
        while(b[j]!=0)
            j++;
        b[j]=i;
        for(int k=j+1;k<n;k++)
        {
            if(gcd(v[k],v[j])>1)
                b[k]=i;
        }
      }
      FOR(i,0,n)
        cout<<b[i]<<' ';
    cout<<'\n';

    }
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        int m = 1;
        vector<int> prime = {2,3,5,7,11,13,17,19,23,29,31};
        vector<int> ans(n);
        for(int i=0;i<prime.size();i++){
            for(int j=0;j<n;j++){
                if(arr[j]%prime[i]==0){
                    ans[j] = i+1;
                }
            }
        }
        int mini = *min_element(ans.begin(), ans.end());
        int maxi = *max_element(ans.begin(), ans.end());
        cout << maxi-mini+1 << "\n";
        for(auto it: ans)
            cout << it-mini+1 << " ";
        cout << "\n";

    }
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961
*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        int m = 1;
        vector<bool> visited(n,false);
        vector<int> ans(n,-1);
        for(int i=0;i<n;i++){
            // if(!visited[i]){
            if(ans[i]==-1){
                ans[i] = m;
                m++;
            }
            for(int j=i+1;j<=n;j++){
                if(!visited[j] && __gcd(arr[i],arr[j])!=1){
                    ans[j] = ans[i];
                    visited[j] = true;
                }
            }
            // m++;
            // }
        }
        cout << m-1 << "\n";
        for(auto it: ans)
            cout << it << " ";
        cout << "\n";
    }
    // cout << __gcd(781,497);
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        // int m = 1;
        vector<int> prime = {2,3,5,7,11,13,17,19,23,29,31};
        int count = 1;
        vector<int> ans(n,-1);
        for(int i=0;i<prime.size();i++){
            bool flag = false;
            for(int j=0;j<n;j++){
                if(ans[j]==-1 && (arr[j]%prime[i])==0){
                    // ans[j] = i+1;
                    // cout << arr[j] << " " << count << "--\n";
                    ans[j] = count;
                    flag = true;
                }
            }
            if(flag)
                count++;
        }
        // int mini = *min_element(ans.begin(), ans.end());
        // int maxi = *max_element(ans.begin(), ans.end());
        // cout << maxi-mini+1 << "\n";
        cout << count-1 << "\n";
        for(auto it: ans)
            cout << it << " ";
        cout << "\n";

    }
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        int m = 1;
        vector<bool> visited(n,false);
        vector<int> ans(n,-1);
        for(int i=0;i<n;i++){
            // if(!visited[i]){
            if(ans[i]==-1){
                ans[i] = m;
                visited[i] = true;
                m++;
            }
            for(int j=i+1;j<n;j++){
                if(!visited[j] && __gcd(arr[i],arr[j])!=1){
                    ans[j] = ans[i];
                    visited[j] = true;
                }
            }
            // m++;
            // }
        }
        cout << m-1 << "\n";
        for(auto it: ans)
            cout << it << " ";
        cout << "\n";
    }
    // cout << __gcd(781,497);
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        int m = 1;
        vector<bool> visited(n,false);
        vector<int> ans(n,-1);
        for(int i=0;i<n;i++){
            if(!visited[i]){
            for(int j=i;j<n;j++){
                if(!visited[j] && __gcd(arr[i],arr[j])!=1){
                    ans[j] = m;
                    visited[j] = true;
                }
            }
            m++;
            }
        }
        cout << m-1 << "\n";
        for(auto it: ans)
            cout << it << " ";
        cout << "\n";
    }
    // cout << __gcd(781,497);
    return 0;
}


/*input
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961

*/

#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i=0;i<n;i++) cin >> arr[i];
        int m = 1;
        vector<bool> visited(n,false);
        vector<int> ans(n,-1);
        for(int i=0;i<n;i++){
            // if(!visited[i]){
            if(ans[i]==-1){
                ans[i] = m;
                visited[i] = true;
                m++;
            }
            for(int j=i+1;j<=n;j++){
                if(!visited[j] && __gcd(arr[i],arr[j])!=1){
                    ans[j] = ans[i];
                    visited[j] = true;
                }
            }
            // m++;
            // }
        }
        cout << m-1 << "\n";
        for(auto it: ans)
            cout << it << " ";
        cout << "\n";
    }
    // cout << __gcd(781,497);
    return 0;
}


/*
	*	Created By: 'Present_Sir'
	*	Created On: Saturday 25 July 2020 10:19:17 AM IST
*/

#include<bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(false); cin.tie(NULL)
#define int long long
using namespace std;

void solve(){
    int n;
    cin>>n;
    vector<int> v(n);
    for(int i=0; i<n; i++){
        cin>>v[i];
    }
    vector<int> co(n,-1);
    co[0] = 1;
    int k = 1;
    for(int i=0; i<n; i++){
        if(co[i] == -1) co[i] = k+1;
        for(int j=i+1; j<n; j++){
            if(__gcd(v[i],v[j]) > 1){
                    co[j] = co[i];
            }
            k = max(k,co[j]);
        }
    }
    cout<<k<<endl;
    for(int i=0; i<n; i++){
        cout<<co[i]<<" ";
    }
    cout<<endl;
}

int32_t main(){
    IOS;
    int t; cin>>t; while(t--)
    {
        solve();
    }
    return 0;
}