#include <bits/stdc++.h>
#include <random>
#include <bitset>
using namespace std;
#define M 1000000007
#define pb emplace_back
#define F first
#define S second
#define PI acosl(-1.0)
#define mp(a, b) make_pair(a, b)
#define eps 1e-9
#define all(vec) vec.begin(), vec.end()
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
const int N = 2e6 + 10;
const int INF = 1LL << 60;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

void solve()
{
	int n, m;
	int y;
	cin >> n >> y;
	vector<int> a(n);
	for(int i=0; i<n; i++) cin >> a[i];
	cin >> m >> y;
	vector<int> b(m);
	int ans = 0;
	for(int i=0; i<m; i++) cin >> b[i];
	for(int i=0; i<=30; i++){
		int d = (1 << i);
		d = d * 2;
		map<int,int> mp;
		for(int j=0; j<n; j++){
			mp[a[j]%d]++;
		}
		for(int j=0; j<m; j++){
			mp[(b[j]+d/2)%d]++;
		}
		int mx = 0;
		for(auto x: mp){
			chmax(mx, x.second);
		}
		chmax(ans, mx);
	}
	map<int,int> mp;
	for(int j=0; j<n; j++) mp[a[j]]++;
	for(int j=0; j<m; j++) mp[b[j]]++;
	for(auto x: mp) chmax(ans, x.second);
	cout << ans << '\n';
}

signed main()
{
    FAST
    int Tests = 1;
    //cin>>Tests;
    while(Tests--)
    {
		//cout<<"Case #"<<(t++)<<": ";
        solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <random>
#include <bitset>
using namespace std;
#define M 1000000007
#define pb emplace_back
#define F first
#define S second
#define PI acosl(-1.0)
#define mp(a, b) make_pair(a, b)
#define eps 1e-9
#define all(vec) vec.begin(), vec.end()
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
const int N = 2e6 + 10;
const int INF = 1LL << 60;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

void solve()
{
	int n, m;
	int y;
	cin >> n >> y;
	vector<int> a(n);
	for(int i=0; i<n; i++) cin >> a[i];
	cin >> m >> y;
	vector<int> b(m);
	int ans = 0;
	for(int i=0; i<m; i++) cin >> b[i];
	for(int i=0; i<=30; i++){
		int d = (1 << i);
		d = d * 2;
		map<int,int> mp;
		for(int j=0; j<n; j++){
			mp[a[j]%d]++;
		}
		for(int j=0; j<m; j++){
			mp[(b[j]+d/2)%d]++;
		}
		int mx = 0;
		for(auto x: mp){
			chmax(mx, x.second);
		}
		chmax(ans, mx);
	}
	cout << ans << '\n';
}

signed main()
{
    FAST
    int Tests = 1;
    //cin>>Tests;
    while(Tests--)
    {
		//cout<<"Case #"<<(t++)<<": ";
        solve();
    }
    return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <deque>
#include <algorithm>
#include <iomanip>
using namespace std;

int n, m, y;

vector<long long>a;
vector<long long>b;

void Solve()
{
	cin >> n >> y;
	a.resize(n);
	for (auto &i : a)
		cin >> i;
	cin >> m >> y;
	b.resize(m);
	for (auto &i : b)
		cin >> i;
	int bestanswer = 2;
	for (int i = 0; i < 60; i++)
	{
		long long mod = 1ll << i + 1;
		map<long long, int>m;
		for (auto &i : a)
			m[i % mod]++;
		for (auto &i : a)
			m[(i + mod / 2) % mod]++;
		for (auto const& [k, v] : m)
		{
			bestanswer = max(bestanswer, v);
		}
	}
	cout << bestanswer << endl;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	//freopen("shelves.in", "r", stdin);
	//freopen("output.txt", "w", stdout);
	/*int t;
	cin >> t;
	for (int i = 0; i < t; i++)*/
		Solve();
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <deque>
#include <algorithm>
#include <iomanip>
using namespace std;

int n, m, y;

vector<long long>a;
vector<long long>b;

void Solve()
{
	cin >> n >> y;
	a.resize(n);
	for (auto &i : a)
		cin >> i;
	cin >> m >> y;
	b.resize(m);
	for (auto &i : b)
		cin >> i;
	int bestanswer = 2;
	for (int i = 0; i < 60; i++)
	{
		long long mod = 1ll << i + 1;
		map<long long, int>m;
		for (auto &i : a)
			m[i % mod]++;
		for (auto &i : b)
			m[(i + mod / 2) % mod]++;
		for (auto const& [k, v] : m)
		{
			bestanswer = max(bestanswer, v);
		}
	}
	cout << bestanswer << endl;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	//freopen("shelves.in", "r", stdin);
	//freopen("output.txt", "w", stdout);
	/*int t;
	cin >> t;
	for (int i = 0; i < t; i++)*/
		Solve();
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <deque>
#include <algorithm>
#include <iomanip>
using namespace std;

int n, m, y;

vector<long long>a;
vector<long long>b;

void Solve()
{
	cin >> n >> y;
	a.resize(n);
	for (auto &i : a)
		cin >> i;
	cin >> m >> y;
	b.resize(m);
	for (auto &i : b)
		cin >> i;
	int bestanswer = 2;
	for (int i = 0; i < 30; i++)
	{
		long long mod = 1ll << i + 1;
		map<long long, int>m;
		for (auto &i : a)
			m[i % mod]++;
		for (auto &i : b)
			m[(i + mod / 2) % mod]++;
		for (auto const& [k, v] : m)
		{
			bestanswer = max(bestanswer, v);
		}
	}
	cout << bestanswer << endl;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	//freopen("shelves.in", "r", stdin);
	//freopen("output.txt", "w", stdout);
	/*int t;
	cin >> t;
	for (int i = 0; i < t; i++)*/
		Solve();
}


#include <bits/stdc++.h>

using namespace std;

inline void Boost() {
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
}
typedef long long int ll;
typedef long double ld;

const int INF = 1e9;

void Read(int &n, vector < int > &A) {
	int y; cin >> n >> y;
	A.assign(n, 0);
	for (int i = 0; i < n; ++i) cin >> A[i];
}

int main() {
	Boost();

	int n, m;
	vector < int > A, B;

	Read(n, A);
	Read(m, B);

	int ans = 2;
	for (int d = 1; d <= INF; d *= 2) {
		int mod = 2 * d;
		int total = 0;
		map < int, int > Map;
		for (int i = 0; i < n; ++i) {
			++Map[A[i] % mod];
			total = max(total, Map[A[i] % mod]);
		}
		for (int i = 0; i < m; ++i) {
			++Map[(B[i] + d) % mod];
			total = max(total, Map[(B[i] + d) % mod]);
		}

		ans = max(ans, total);
	}

	cout << ans;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

inline void Boost() {
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
}
typedef long long int ll;
typedef long double ld;

const int INF = 1e9;

void Read(int &n, vector < int > &A) {
	int y; cin >> n >> y;
	A.assign(n, 0);
	for (int i = 0; i < n; ++i) cin >> A[i];
}

int main() {
	Boost();

	int n, m;
	vector < int > A, B;

	Read(n, A);
	Read(m, B);

	int ans = 0;
	for (int d = 2; d <= INF; d *= 2) {
		int total = 0;
		map < int, int > Map;
		for (int i = 0; i < n; ++i) {
			++Map[A[i] % d];
			total = max(total, Map[A[i] % d]);
		}
		for (int i = 0; i < m; ++i) {
			++Map[(B[i] + d / 2) % d];
			total = max(total, Map[(B[i] + d / 2) % d]);
		}

		ans = max(ans, max(total, n + m - total));
	}

	cout << ans;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

inline void Boost() {
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
}
typedef long long int ll;
typedef long double ld;

int main() {
	Boost();

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

inline void Boost() {
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
}
typedef long long int ll;
typedef long double ld;

const int INF = 1e9;

void Read(int &n, vector < int > &A) {
	int y; cin >> n >> y;
	A.assign(n, 0);
	for (int i = 0; i < n; ++i) cin >> A[i];
}

int main() {
	Boost();

	int n, m;
	vector < int > A, B;

	Read(n, A);
	Read(m, B);

	int ans = 0;
	for (int d = 1; d <= INF; d *= 2) {
		int total = 0;
		map < int, int > Map;
		for (int i = 0; i < n; ++i) {
			++Map[A[i] % (2 * d)];
			total = max(total, Map[A[i] % (2 * d)]);
		}
		for (int i = 0; i < m; ++i) {
			++Map[(B[i] + d) % (2 * d)];
			total = max(total, Map[(B[i] + d) % (2 * d)]);
		}

		ans = max(ans, total);
	}

	cout << ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=17000010;
int n,m,k,a[maxn],b[maxn],y,dpa[maxm],dpb[maxm],tot=0;
int main()
{
//	for(int i=1;i<=30;i++)
//	{
//		int p=pow(2,i);
//		printf("%12d\n",p);
//	}
	cin>>n>>y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	cin>>m>>y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
	}
	for(int i=1;i<=n;i++)
	{
		if(upper_bound(b+1,b+1+m,a[i])-lower_bound(b+1,b+1+m,a[i])!=0)
		{
			tot=2;
			break;
		}
	}
//	for(int i=2;i<=1e9;i*=2)
//	{
//		memset(dpa,0,sizeof(dpa));
//		memset(dpb,0,sizeof(dpb));
//		for(int j=1;j<=n;j++)
//		{
//			dpa[j]=a[j]%i;
//		}
//		for(int j=1;j<=m;j++)
//		{
//			dpb[j]=b[j]%i;
//		}
//		sort(dpa+1,dpa+1+n);
//		sort(dpb+1,dpb+1+n);
//
//	}
	for(k=2;k<=maxm;k*=2)
	{
		memset(dpa,0,sizeof(dpa));
		memset(dpb,0,sizeof(dpb));
		for(int j=1;j<=n;j++)
		{
			dpa[a[j]%k]++;
		}
		for(int j=1;j<=m;j++)
		{
			dpb[b[j]%k]++;
		}
		for(int j=0;j<k/2;j++)
		{
			if(dpa[j]+dpb[j+k/2]>tot)
				tot=dpa[j]+dpb[j+k/2];
			if(dpb[j]+dpa[j+k/2]>tot)
				tot=dpb[j]+dpa[j+k/2];
		}
	}
	for(k=16777216;k<1e9;k*=2)
	{
		for(int i=1;i<=n;i++)
		{
			int tent=a[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			tent=a[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
			}
			if(sum>tot) tot=sum;
		}
		for(int i=1;i<=m;i++)
		{
			int tent=b[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
				//cout<<upper_bound(b+1,b+1+m,tent)<<endl;
			}
			tent=b[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			if(sum>tot) tot=sum;
		}
	}
	cout<<tot;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=17000010;
int n,m,k,a[maxn],b[maxn],y,dpa[maxm],dpb[maxm],tot=0;
int main()
{
//	for(int i=1;i<=30;i++)
//	{
//		int p=pow(2,i);
//		printf("%12d\n",p);
//	}
	cin>>n>>y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	cin>>m>>y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
	}
//	for(int i=2;i<=1e9;i*=2)
//	{
//		memset(dpa,0,sizeof(dpa));
//		memset(dpb,0,sizeof(dpb));
//		for(int j=1;j<=n;j++)
//		{
//			dpa[j]=a[j]%i;
//		}
//		for(int j=1;j<=m;j++)
//		{
//			dpb[j]=b[j]%i;
//		}
//		sort(dpa+1,dpa+1+n);
//		sort(dpb+1,dpb+1+n);
//
//	}
	for(k=2;k<=maxm;k*=2)
	{
		memset(dpa,0,sizeof(dpa));
		memset(dpb,0,sizeof(dpb));
		for(int j=1;j<=n;j++)
		{
			dpa[a[j]%k]++;
		}
		for(int j=1;j<=m;j++)
		{
			dpb[b[j]%k]++;
		}
		for(int j=0;j<k/2;j++)
		{
			if(dpa[j]+dpb[j+k/2]>tot)
				tot=dpa[j]+dpb[j+k/2];
			if(dpb[j]+dpa[j+k/2]>tot)
				tot=dpb[j]+dpa[j+k/2];
		}
	}
	for(k=33554432;k<1e9;k*=2)
	{
		for(int i=1;i<=n;i++)
		{
			int tent=a[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			tent=a[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
			}
			if(sum>tot) tot=sum;
		}
		for(int i=1;i<=m;i++)
		{
			int tent=b[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
				//cout<<upper_bound(b+1,b+1+m,tent)<<endl;
			}
			tent=b[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			if(sum>tot) tot=sum;
		}
	}
	cout<<tot;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

int n,m,a[maxn],b[maxn],y,dpa[(int)1e7+10],dpb[(int)1e7+10],tot=0;
int main()
{
//	for(int i=1;i<=30;i++)
//	{
//		int p=pow(2,i);
//		printf("%12d\n",p);
//	}
	cin>>n>>y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	cin>>m>>y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
	}
	for(int i=2;i<=1e7+10;i*=2)
	{
		memset(dpa,0,sizeof(dpa));
		memset(dpb,0,sizeof(dpb));
		for(int j=1;j<=n;j++)
		{
			dpa[a[j]%i]++;
		}
		for(int j=1;j<=m;j++)
		{
			dpb[b[j]%i]++;
		}
		for(int j=0;j<i/2;j++)
		{
			if(dpa[j]+dpb[j+i/2]>tot)
				tot=dpa[j]+dpb[j+i/2];
			if(dpb[j]+dpa[j+i/2]>tot)
				tot=dpb[j]+dpa[j+i/2];
		}
	}
	cout<<tot;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=17000010;
int n,m,k,a[maxn],b[maxn],y,dpa[maxm],dpb[maxm],tot=0;
int main()
{
//	for(int i=1;i<=30;i++)
//	{
//		int p=pow(2,i);
//		printf("%12d\n",p);
//	}
	cin>>n>>y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	cin>>m>>y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
	}
//	for(int i=2;i<=1e9;i*=2)
//	{
//		memset(dpa,0,sizeof(dpa));
//		memset(dpb,0,sizeof(dpb));
//		for(int j=1;j<=n;j++)
//		{
//			dpa[j]=a[j]%i;
//		}
//		for(int j=1;j<=m;j++)
//		{
//			dpb[j]=b[j]%i;
//		}
//		sort(dpa+1,dpa+1+n);
//		sort(dpb+1,dpb+1+n);
//
//	}
	for(k=2;k<=maxm;k*=2)
	{
		memset(dpa,0,sizeof(dpa));
		memset(dpb,0,sizeof(dpb));
		for(int j=1;j<=n;j++)
		{
			dpa[a[j]%k]++;
		}
		for(int j=1;j<=m;j++)
		{
			dpb[b[j]%k]++;
		}
		for(int j=0;j<k/2;j++)
		{
			if(dpa[j]+dpb[j+k/2]>tot)
				tot=dpa[j]+dpb[j+k/2];
			if(dpb[j]+dpa[j+k/2]>tot)
				tot=dpb[j]+dpa[j+k/2];
		}
	}
	for(k=16777216;k<1e9;k*=2)
	{
		for(int i=1;i<=n;i++)
		{
			int tent=a[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			tent=a[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
			}
			if(sum>tot) tot=sum;
		}
		for(int i=1;i<=m;i++)
		{
			int tent=b[i],sum=1;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(b+1,b+1+m,tent)-lower_bound(b+1,b+1+m,tent);
				//cout<<upper_bound(b+1,b+1+m,tent)<<endl;
			}
			tent=b[i]-k;
			while(tent<1e9)
			{
				tent+=k*2;
				sum+=upper_bound(a+1,a+1+n,tent)-lower_bound(a+1,a+1+n,tent);
			}
			if(sum>tot) tot=sum;
		}
	}
	cout<<tot;
	return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    hashmap<ll, ll> st1, st2;
    while (curr <= 1 << 29) {
        st1.clear();
        st2.clear();
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1) checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2) checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

#define ll int

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    hashmap<ll, ll> st1, st2;
    while (curr <= 1 << 28) {
        st1.clear();
        st2.clear();
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1) checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2) checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    while (curr <= 1 << 29) {
        map<ll, ll> st1, st2;
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1) checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2) checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

    #define ll int

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    while (curr <= 1 << 30) {
        hashmap<ll, ll> st1, st2;
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1) checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2) checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    while (curr <= 1 << 30) {
        hashmap<ll, ll> st1, st2;
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1)
            checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2)
            checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops")

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

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(9)
#define RANDOM srand(time(NULL))
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define hashmap unordered_map
#define hashset unordered_set
#define ll long long
#define ld long double
#define ui unsigned int
#define ull unsigned ll
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define intinf ((1 << 31) - 1)
#define f first
#define s second
#define checkmin(x, y) if (x > y) x = y
#define checkmax(x, y) if (x < y) x = y
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(a) int(a.size())
#define shuffle(a) \
    for (int i = -sz(a); i < sz(a); ++i) \
        swap(a[rand() % sz(a)], a[rand() % sz(a)])

template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }

#define ll int

int main() {
    FAST; FIXED; RANDOM;
    ll n, y;
    cin >> n >> y;
    vector<ll> arr(n);
    for (auto &i : arr) cin >> i;
    cin >> n >> y;
    vector<ll> brr(n);
    for (auto &i : brr) cin >> i;
    ll ans = 2, curr = 1;
    while (curr <= 1 << 29) {
        hashmap<ll, ll> st1, st2;
        for (auto i : arr) st1[i % (2 * curr)]++;
        for (auto i : brr) st2[(i + curr) % (2 * curr)]++;
        for (auto i : st1) checkmax(ans, i.s + st2[i.f]);
        for (auto i : st2) checkmax(ans, i.s + st1[i.f]);
        curr *= 2;
    }
    cout << ans;
    return 0;
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using Pi = Pair<int, int>;

class Solver
{
    public void Solve(Scanner sc)
    {
        var N = sc.Int;
        var B = sc.ArrInt;
        var max = 2750132;
        var p = new bool[max];
        var idx = 0;
        var nth = new int[200200];
        var div = new int[max];
        for(int i=2;i<max;i++)
        {
            if (!p[i])
            {
                nth[idx++] = i;
            }
            for(int j=i<<1;j<max;j+=i)
            {
                p[j] = true;
                div[j] = i;
            }
        }
        var set = new Set<int>((a, b) =>
          {
              if (!p[a] && p[b]) return 1;
              if (!p[b] && p[a]) return -1;
              if (!p[a]) return a-b;
              else return b-a;
          });
        set.IsMultiSet = true;
        for (var i = 0; i < 2*N; i++)
        {
            set.Add(B[i]);
        }
        var res = new List<int>();
        while (set.Count > 0)
        {
            var now = set[0];
            res.Add(now);
            set.Remove(now);
            if (!p[now])
            {
                set.Remove(nth[now - 1]);
            }else
            {
                set.Remove(div[now]);
            }
        }
        Console.WriteLine(string.Join(" ", res));
    }
}

public class Set<T>
{
    Node root;
    readonly IComparer<T> comparer;
    readonly Node nil;
    public bool IsMultiSet { get; set; }
    public Set(IComparer<T> comparer)
    {
        nil = new Node(default(T));
        root = nil;
        this.comparer = comparer;
    }
    public Set(Comparison<T> comaprison) : this(Comparer<T>.Create(comaprison)) { }
    public Set() : this(Comparer<T>.Default) { }
    public bool Add(T v)
    {
        return insert(ref root, v);
    }
    public bool Remove(T v)
    {
        return remove(ref root, v);
    }
    public T this[int index] { get { return find(root, index); } }
    public int Count { get { return root.Count; } }
    public void RemoveAt(int k)
    {
        if (k < 0 || k >= root.Count) throw new ArgumentOutOfRangeException();
        removeAt(ref root, k);
    }
    public T[] Items
    {
        get
        {
            var ret = new T[root.Count];
            var k = 0;
            walk(root, ret, ref k);
            return ret;
        }
    }
    void walk(Node t, T[] a, ref int k)
    {
        if (t.Count == 0) return;
        walk(t.lst, a, ref k);
        a[k++] = t.Key;
        walk(t.rst, a, ref k);
    }

    bool insert(ref Node t, T key)
    {
        if (t.Count == 0) { t = new Node(key); t.lst = t.rst = nil; t.Update(); return true; }
        var cmp = comparer.Compare(t.Key, key);
        bool res;
        if (cmp > 0)
            res = insert(ref t.lst, key);
        else if (cmp == 0)
        {
            if (IsMultiSet) res = insert(ref t.lst, key);
            else return false;
        }
        else res = insert(ref t.rst, key);
        balance(ref t);
        return res;
    }
    bool remove(ref Node t, T key)
    {
        if (t.Count == 0) return false;
        var cmp = comparer.Compare(key, t.Key);
        bool ret;
        if (cmp < 0) ret = remove(ref t.lst, key);
        else if (cmp > 0) ret = remove(ref t.rst, key);
        else
        {
            ret = true;
            var k = t.lst.Count;
            if (k == 0) { t = t.rst; return true; }
            if (t.rst.Count == 0) { t = t.lst; return true; }

            t.Key = find(t.lst, k - 1);
            removeAt(ref t.lst, k - 1);
        }
        balance(ref t);
        return ret;
    }
    void removeAt(ref Node t, int k)
    {
        var cnt = t.lst.Count;
        if (cnt < k) removeAt(ref t.rst, k - cnt - 1);
        else if (cnt > k) removeAt(ref t.lst, k);
        else
        {
            if (cnt == 0) { t = t.rst; return; }
            if (t.rst.Count == 0) { t = t.lst; return; }

            t.Key = find(t.lst, k - 1);
            removeAt(ref t.lst, k - 1);
        }
        balance(ref t);
    }
    void balance(ref Node t)
    {
        var balance = t.lst.Height - t.rst.Height;
        if (balance == -2)
        {
            if (t.rst.lst.Height - t.rst.rst.Height > 0) { rotR(ref t.rst); }
            rotL(ref t);
        }
        else if (balance == 2)
        {
            if (t.lst.lst.Height - t.lst.rst.Height < 0) rotL(ref t.lst);
            rotR(ref t);
        }
        else t.Update();
    }

    T find(Node t, int k)
    {
        if (k < 0 || k > root.Count) throw new ArgumentOutOfRangeException();
        for (; ; )
        {
            if (k == t.lst.Count) return t.Key;
            else if (k < t.lst.Count) t = t.lst;
            else { k -= t.lst.Count + 1; t = t.rst; }
        }
    }
    public int LowerBound(T v)
    {
        var k = 0;
        var t = root;
        for (; ; )
        {
            if (t.Count == 0) return k;
            if (comparer.Compare(v, t.Key) <= 0) t = t.lst;
            else { k += t.lst.Count + 1; t = t.rst; }
        }
    }
    public int UpperBound(T v)
    {
        var k = 0;
        var t = root;
        for (; ; )
        {
            if (t.Count == 0) return k;
            if (comparer.Compare(t.Key, v) <= 0) { k += t.lst.Count + 1; t = t.rst; }
            else t = t.lst;
        }
    }
    public bool Contains(T v)
    {
        var k = 0;
        var t = root;
        for (; ; )
        {
            if (t.Count == 0) return false;
            if (comparer.Compare(t.Key, v) == 0) return true;
            if (comparer.Compare(t.Key, v) < 0) { k += t.lst.Count + 1; t = t.rst; }
            else t = t.lst;
        }
    }
    void rotR(ref Node t)
    {
        var l = t.lst;
        t.lst = l.rst;
        l.rst = t;
        t.Update();
        l.Update();
        t = l;
    }
    void rotL(ref Node t)
    {
        var r = t.rst;
        t.rst = r.lst;
        r.lst = t;
        t.Update();
        r.Update();
        t = r;
    }
    public T[] ToArray()
    {
        var rt = new T[Count]; var idx = 0;
        Action<Node> dfs = null;
        dfs = a =>
        {
            if (a.lst != nil) dfs(a.lst);
            rt[idx++] = a.Key;
            if (a.rst != nil) dfs(a.rst);
        };
        dfs(root);
        return rt;
    }

    class Node
    {
        public Node(T key)
        {
            Key = key;
        }
        public int Count { get; private set; }
        public sbyte Height { get; private set; }
        public T Key { get; set; }
        public Node lst, rst;
        public void Update()
        {
            Count = 1 + lst.Count + rst.Count;
            Height = (sbyte)(1 + Math.Max(lst.Height, rst.Height));
        }
        public override string ToString()
        {
            return string.Format("Count = {0}, Key = {1}", Count, Key);
        }
    }
}
#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) == 1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) == -1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Shuffle<T>(this IList<T> A) { T[] rt = A.ToArray(); Random rnd = new Random(); for (int i = rt.Length - 1; i >= 1; i--) swap(ref rt[i], ref rt[rnd.Next(i + 1)]); return rt; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static int MaxElement<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static void PopBack<T>(this List<T> A) => A.RemoveAt(A.Count - 1);
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    //public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Deconstruct(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication12
{
    class Program
    {
        static void Main(string[] args)
        {
            var max = 2750200;
            var setS = new HashSet<int>();
            var arrB = new bool[max];
            var minD = new int[max];

            for (int i = 2; i < max; i++)
            {
                if (!arrB[i])
                {
                    setS.Add(i);
                    for (int j = i; j < max; j += i)
                    {
                        arrB[j] = true;
                        if (minD[j] == 0)
                        {
                            minD[j] = i;
                        }
                    }
                }
            }

            var dictS = new Dictionary<int, int>();
            var index = 1;
            foreach (var e in setS)
            {
                dictS.Add(e, index);
                index++;
            }

            var input = Console.ReadLine();
            var n = int.Parse(input) * 2;

            input = Console.ReadLine();
            var inputArr = input.Split();
            var arr = new int[n];
            for (int i = 0; i < n; i++)
            {
                arr[i] = int.Parse(inputArr[i]);
            }

            Array.Sort(arr);
            arr = arr.Reverse().ToArray();

            var d = new Dictionary<int, int>();
            for (int i = 0; i < n; i++)
            {
                var c = arr[i];
                if (d.ContainsKey(c))
                {
                    d[c] += 1;
                }
                else
                {
                    d.Add(c, 1);
                }
            }

            var a = new HashSet<int>();
            for (int i = 0; i < n; i++)
            {
                var c = arr[i];
                if (d.ContainsKey(c) && d[c] > 0)
                {
                    if (setS.Contains(c))
                    {
                        if (d.ContainsKey(c))
                        {
                            var index2 = dictS[c];

                            d[c]--;
                            d[index2]--;

                            a.Add(index2);
                        }
                    }
                    else
                    {
                        var c2 = c / minD[c];

                        d[c]--;
                        d[c2]--;

                        a.Add(c);

                    }
                }
            }
            var sb = new StringBuilder();
            foreach (var e in a)
            {
                sb.Append(string.Format("{0} ", e));
            }
            Console.WriteLine(sb);
            //Console.ReadLine();
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication12
{
    class Program
    {
        static void Main(string[] args)
        {
            var max = 2750200;
            var setS = new HashSet<int>();
            var arrB = new bool[max];
            var minD = new int[max];

            for (int i = 2; i < max; i++)
            {
                if (!arrB[i])
                {
                    setS.Add(i);
                    for (int j = i; j < max; j += i)
                    {
                        arrB[j] = true;
                        if (minD[j] == 0)
                        {
                            minD[j] = i;
                        }
                    }
                }
            }

            var dictS = new Dictionary<int, int>();
            var index = 1;
            foreach (var e in setS)
            {
                dictS.Add(e, index);
                index++;
            }

            var input = Console.ReadLine();
            var n = int.Parse(input) * 2;

            input = Console.ReadLine();
            var inputArr = input.Split();
            var arr = new int[n];
            for (int i = 0; i < n; i++)
            {
                arr[i] = int.Parse(inputArr[i]);
            }

            Array.Sort(arr);
            arr = arr.Reverse().ToArray();

            var d = new Dictionary<int, int>();
            for (int i = 0; i < n; i++)
            {
                var c = arr[i];
                if (d.ContainsKey(c))
                {
                    d[c] += 1;
                }
                else
                {
                    d.Add(c, 1);
                }
            }

            var a = new List<int>();
            for (int i = 0; i < n; i++)
            {
                var c = arr[i];
                if (d.ContainsKey(c) && d[c] > 0)
                {
                    if (setS.Contains(c))
                    {
                        if (d.ContainsKey(c))
                        {
                            var index2 = dictS[c];

                            d[c]--;
                            d[index2]--;

                            a.Add(index2);
                        }
                    }
                    else
                    {
                        var c2 = c / minD[c];

                        d[c]--;
                        d[c2]--;

                        a.Add(c);

                    }
                }
            }
            var sb = new StringBuilder();
            foreach (var e in a)
            {
                sb.Append(string.Format("{0} ", e));
            }
            Console.WriteLine(sb);
            //Console.ReadLine();
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

class Solution
{
	static bool[] PrimeSieve (int n)
	{
		bool[] prime = new bool[n + 1];
		for (int i = 2; i <= n; i++) {
			prime [i] = true;
		}
		for (int i = 2; i <= n / 2; i++) {
			if (!prime [i])
				continue;
			for (int k = 2 * i; k <= n; k += i) {
				prime [k] = false;
			}
		}
		return prime;
	}

	static int LargestDivisor (int n)
	{
		for (int i = 2; i * i <= n; i++) {
			if (n % i == 0)
				return n / i;
		}
		return -1;
	}

	public static void Main (string[] args)
	{
		Console.ReadLine ();
		List<int> nums = Console.ReadLine ().Split (' ').Select (int.Parse).OrderByDescending (n => n).ToList ();
		bool[] isPrime = PrimeSieve (2750131);
		List<int> primeList = new List<int> ();
		for (int i = 0; i < isPrime.Length; i++) {
			if (isPrime [i])
				primeList.Add (i);
		}
		int[] primePos = new int[isPrime.Length];
		for (int i = 0; i < primeList.Count; i++) {
			primePos [primeList [i]] = i + 1;
		}

		List<int> a = new List<int> ();
		Dictionary<int, int> ignore = new Dictionary<int, int> ();
		foreach (int i in nums) {
			if (ignore.ContainsKey (i)) {
				ignore [i]--;
				if (ignore [i] == 0)
					ignore.Remove (i);
				continue;
			}
			if (isPrime [i]) {
				a.Add (primePos [i]);
				if (ignore.ContainsKey (primePos [i]))
					ignore [primePos [i]]++;
				else
					ignore [primePos [i]] = 1;
			} else {
				int d = LargestDivisor (i);
				a.Add (i);
				if (ignore.ContainsKey (d))
					ignore [d]++;
				else
					ignore [d] = 1;
			}
		}
		Console.WriteLine (string.Join (" ", a));
	}
}


#[allow(unused_imports)]
use std::io::{BufWriter, stdin, stdout, Write};
use std::cmp::{min, max};
use std::collections::{VecDeque, HashMap, BTreeMap, HashSet, BTreeSet, BinaryHeap};

fn main() {
	let mut inp = my_input::default();
	let out = &mut BufWriter::new(stdout());
	let mut P = vec![0; 2800000];
	let mut C = vec![0; 2800000];
	let mut V = vec![0];
	for i in 2..2800000 {
		if P[i] != 0 {
			continue;
		}
		V.push(i);
		C[i] += 1;
		let mut j = i + i;
		while j < 2800000 {
			let mut x = j;
			while x % i == 0 {
				x /= i;
				C[j] += 1;
			}
			P[j] = i;
			j += i;
		}
	}
	let mut A = vec![0; 2800000];
	let n = inp.scan::<usize>();
	for it in 0..n + n {
		let a = inp.scan::<usize>();
		A[a] += 1;
	}
	for it in (2..30).rev() {
		for i in 2..2800000 {
			if C[i as usize] != it {
				continue;
			}
			for jt in 0..A[i as usize] {
				write!(out, "{} ", i);
				A[P[i as usize] as usize] -= 1;
			}
			A[i as usize] = 0;
		}
	}
	for i in 2..2800000 {
		for jt in 0..A[i as usize] {
			write!(out, "{} ", i);
			A[V[i as usize] as usize] -= 1;
		}
	}
}

#[derive(Default)]
struct my_input {
	buffer: Vec<String>
}

impl my_input {
	fn scan<T: std::str::FromStr>(&mut self) -> T {
		loop {
			if let Some(token) = self.buffer.pop() {
				return token.parse().ok().expect("Parsing Error");
			}
			let mut s = String::new();
			stdin().read_line(&mut s).expect("Reading Error");
			self.buffer = s.split_whitespace().rev().map(String::from).collect();
		}
	}
}


#[allow(unused_imports)]
use std::io::{BufWriter, stdin, stdout, Write};
use std::cmp::{min, max};
use std::collections::{VecDeque, HashMap, BTreeMap, HashSet, BTreeSet, BinaryHeap};

fn main() {
	let mut inp = my_input::default();
	let out = &mut BufWriter::new(stdout());
	let mut P = vec![0; 2800000];
	let mut C = vec![0; 2800000];
	let mut V = vec![0];
	for i in 2..2800000 {
		if P[i] != 0 {
			P[i] = i / P[i];
			continue;
		}
		V.push(i);
		C[i] += 1;
		let mut j = i + i;
		while j < 2800000 {
			let mut x = j;
			while x % i == 0 {
				x /= i;
				C[j] += 1;
			}
			if P[j] == 0 {
				P[j] = i;
			}
			j += i;
		}
	}
	let mut A = vec![0; 2800000];
	let n = inp.scan::<usize>();
	for it in 0..n + n {
		let a = inp.scan::<usize>();
		A[a] += 1;
	}
	for it in (2..30).rev() {
		for i in 2..2800000 {
			if C[i as usize] != it {
				continue;
			}
			for jt in 0..A[i as usize] {
				write!(out, "{} ", i);
				A[P[i as usize] as usize] -= 1;
			}
			A[i as usize] = 0;
		}
	}
	for i in 2..2800000 {
		for jt in 0..A[i as usize] {
			write!(out, "{} ", i);
			A[V[i as usize] as usize] -= 1;
		}
	}
}

#[derive(Default)]
struct my_input {
	buffer: Vec<String>
}

impl my_input {
	fn scan<T: std::str::FromStr>(&mut self) -> T {
		loop {
			if let Some(token) = self.buffer.pop() {
				return token.parse().ok().expect("Parsing Error");
			}
			let mut s = String::new();
			stdin().read_line(&mut s).expect("Reading Error");
			self.buffer = s.split_whitespace().rev().map(String::from).collect();
		}
	}
}


#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };

    ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

#[allow(unused_imports)]
use std::cmp::{min, max};

#[allow(unused_imports)]
use std::io::Write;

const MAX: u64 = 2750131;

pub fn gen_prime_table(n: u64) -> Vec<bool> {
    let mut is_prime = vec![true; n as usize + 1];
    is_prime[0] = false;
    is_prime[1] = false;
    let mut i = 2;
    while i * i <= n as usize {
        if is_prime[i] {
            let mut j = 2;
            while i * j <= n as usize {
                is_prime[i * j] = false;
                j += 1;
            }
        }
        i += 1;
    }
    is_prime
}

fn get_g_divisor(n: usize) -> usize {
    let mut i = 2;
    while i*i <= n {
        if n%i == 0 {
            return n/i;
        }
        i += 1;
    }
    1
}

fn solve() {
    input!{
      n: usize,
      mut aa: [usize; 2*n],
    }
    let is_primes = gen_prime_table(MAX);
    let mut all_primes = vec![];
    for v in 2..MAX+1 {
        if is_primes[v as usize] {
            all_primes.push(v);
        }
    }

    use std::collections::HashMap;
    let mut map = HashMap::new();

    let mut primes = vec![];
    let mut not_primes = vec![];
    for &a in aa.iter() {
        let e = map.entry(a).or_insert(0);
        *e += 1;
        if is_primes[a] {
            primes.push(a);
        } else {
            not_primes.push(a);
        }
    }
    // debug!(map);
    primes.sort();
    not_primes.sort();
    let mut ans = vec![];
    for &v in not_primes.iter().rev() {
        let mut cnt = 0;
        {
            let e = map.entry(v).or_insert(0);
            if *e == 0 {
                continue;
            }
            cnt = *e;
        }
        if cnt >= 1 {
            ans.push(v);
            {
                let e = map.entry(v).or_insert(0);
                *e -= 1;
            }
            let gv = get_g_divisor(v);
            {
                let e = map.entry(gv).or_insert(0);
                *e -= 1;
            }
            // debug!(v, gv, map);
        }
    }

    for &v in primes.iter() {
        let mut cnt = 0;
        {
            let e = map.entry(v).or_insert(0);
            if *e == 0 {
                continue;
            }
            cnt = *e;
        }
        if cnt >= 1 {
            ans.push(v);
            {
                let e = map.entry(v).or_insert(0);
                *e -= 1;
            }
            let np = all_primes[v-1];
            {
                let e = map.entry(np as usize).or_insert(0);
                *e -= 1;
            }
            // debug!(v, np, map);
        }
    }
    for a in ans {
        print!("{} ", a);
    }
    println!();
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: usize,
        a: [usize; 2 * n],
    }
    const W: usize = 2750132;
    let mut pr = vec![true; W];
    let mut fac = vec![0; W];
    pr[0] = false;
    pr[1] = false;
    for i in 2..W {
        if !pr[i] { continue; }
        fac[i] = i;
        let mut j = 2 * i;
        while j < W {
            pr[j] = false;
            if fac[j] == 0 { fac[j] = i; }
            j += i;
        }
    }
    let primes: Vec<_> = (2..W).filter(|&x| pr[x]).collect();
    let mut pidx = vec![0; W];
    for i in 0..primes.len() {
        pidx[primes[i]] = i;
    }
    let mut a = a;
    a.sort(); a.reverse();
    let mut hm = HashMap::new();
    for &a in &a {
        *hm.entry(a).or_insert(0) += 1;
    }
    let mut ans = vec![];
    for &a in &a {
        if hm[&a] == 0 { continue; }
        if !pr[a] {
            let maxdiv = a / fac[a];
            ans.push(a);
            *hm.get_mut(&a).unwrap() -= 1;
            *hm.get_mut(&maxdiv).unwrap() -= 1;
        }
    }
    for &a in &a {
        if hm[&a] == 0 { continue; }
        assert!(pr[a]);
        let idx = pidx[a] + 1;
        ans.push(idx);
        *hm.get_mut(&a).unwrap() -= 1;
        *hm.get_mut(&idx).unwrap() -= 1;
    }
    for i in 0..n {
        puts!("{}{}", ans[i], if i + 1 == n { "\n" } else { " " });
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)
	fmt.Println("hola1")
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}
	fmt.Println("hola2")
	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int64
var indices [total]int64
var repeticionesIn [total]int64

func init() {
	for i := int64(0); i < total; i++ {
		primos[i] = i
	}
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int64) {

	for i := int64(2); i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			primos[j] = min(i, primos[i])
		}
	}

}

func main() {

	SieveOfEratosthenes(total)

	r := make([]int64, 0)

	for i, count := int64(1), int64(0); i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := int64(total - 1); i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	fmt.Println(primos[1630])

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int64
var indices [total]int64
var repeticionesIn [total]int64

func init() {
	for i := int64(0); i < total; i++ {
		primos[i] = i
	}
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int64) {

	for i := int64(2); i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			primos[j] = min(i, primos[j])
		}
	}

}

func main() {

	SieveOfEratosthenes(total)

	r := make([]int64, 0)

	for i, count := int64(1), int64(0); i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := int64(total - 1); i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	const (
		total = 2750131 + 8
	)

	var primos [total]int
	var indices [total]int
	var repeticionesIn [total]int
	for i := 0; i < total; i++ {
		primos[i] = i
	}
	for i := 2; i < total; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < total; j = j + i {
			primos[j] = i
		}
	}
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

// func BinarySearch(a int) int {
// 	var indice, inferior, superior int
// 	superior = len(primos)
// 	for inferior <= superior {
// 		indice = inferior + superior/2
// 		if primos[indice] == a {
// 			return indice
// 		}
// 		if a < primos[indice] {
// 			superior = indice - 1
// 		} else {
// 			inferior = indice + 1
// 		}
// 	}
// 	return -1
// }

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	input := strings.Split(sc.Text(), " ")
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}
	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	defer fmt.Println(2)

	SieveOfEratosthenes(total)
	fmt.Println("hola1")
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}
	fmt.Println("hola2")
	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(total)

		}
	}()
	fmt.Println()
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {

}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Split(sc.Text(), " ")
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}
	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int64
var indices [total]int64
var repeticionesIn [total]int64

func init() {
	for i := int64(0); i < total; i++ {
		primos[i] = i
	}
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int64) {

	for i := int64(2); i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			primos[j] = min(i, primos[j])
		}
	}

}

func main() {

	SieveOfEratosthenes(total)

	r := make([]int64, 0)

	for i, count := int64(1), int64(0); i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.ParseUint(input[i], 10, 0)
		if val < 0 || val > uint64(len(repeticionesIn)) {
			fmt.Println(val)
		}
		repeticionesIn[val]++
	}

	for i := int64(total - 1); i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {

	const (
		total = 2750131 + 8
	)

	var primos [total]int
	var indices [total]int
	var repeticionesIn [total]int

	for i := 0; i < total; i++ {
		primos[i] = i
	}
	for i := 2; i < total; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < total; j = j + i {
			primos[j] = i
		}
	}
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Split(sc.Text(), " ")
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}
	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

// func BinarySearch(a int) int {
// 	var indice, inferior, superior int
// 	superior = len(primos)
// 	for inferior <= superior {
// 		indice = inferior + superior/2
// 		if primos[indice] == a {
// 			return indice
// 		}
// 		if a < primos[indice] {
// 			superior = indice - 1
// 		} else {
// 			inferior = indice + 1
// 		}
// 	}
// 	return -1
// }

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Split(sc.Text(), " ")
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}
	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	// "strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	// r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	// for i := 0; i < len(input); i++ {
	// 	val, _ := strconv.Atoi(input[i])
	// 	repeticionesIn[val]++
	// }

	// for i := total - 1; i >= 0; i-- {
	// 	for repeticionesIn[i] > 0 {
	// 		if i == primos[i] {
	// 			repeticionesIn[indices[i]]--
	// 			r = append(r, indices[i])
	// 		} else {
	// 			repeticionesIn[primos[i]]--
	// 			r = append(r, i)
	// 		}
	// 		repeticionesIn[i]--
	// 	}
	// }
	// fmt.Print(r[0])
	// for i := 1; i < len(r); i++ {
	// 	fmt.Printf(" %d", r[i])
	// }
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	fmt.Println(limite)
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j += i {
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Split(sc.Text(), " ")
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}
	fmt.Println(repeticionesIn)
	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int64
var indices [total]int64
var repeticionesIn [total]int64

func init() {
	for i := int64(0); i < total; i++ {
		primos[i] = i
	}
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int64) {

	for i := int64(2); i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			primos[j] = min(i, primos[j])
		}
	}

}

func main() {

	SieveOfEratosthenes(total)

	r := make([]int64, 0)

	for i, count := int64(1), int64(0); i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.ParseUint(input[i], 10, 0)
		if val < 0 || val > uint64(len(repeticionesIn)) {
			fmt.Println(val)
		}
		repeticionesIn[val]++
	}

	for i := int64(total - 1); i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	// for i := 1; i < len(r); i++ {
	// 	fmt.Printf(" %d", r[i])
	// }

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {

	SieveOfEratosthenes(total)
	fmt.Println("hola1")
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}
	fmt.Println("hola2")
	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//SieveOfEratosthenes of earth
// func SieveOfEratosthenes(limite int) {

// 	for i := 2; i < limite; i++ {

// 		if primos[i] != i {
// 			primos[i] = i / primos[i]
// 			continue
// 		}
// 		for j := i * i; j < limite; j += i {
// 			if j > len(primos) {

// 			}
// 			primos[j] = i
// 		}
// 	}
// }

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()
	fmt.Println("hola1")
	for i := 0; i < total; i++ {
		primos[i] = i
	}
	fmt.Println("hola2")
	// SieveOfEratosthenes(total)
	for i := 2; i < total; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < total; j += i {
			if j > len(primos) {

			}
			primos[j] = i
		}
	}

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int64
var indices [total]int64
var repeticionesIn [total]int64

func init() {
	for i := int64(0); i < total; i++ {
		primos[i] = i
	}
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int64) {

	for i := int64(2); i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			if j > int64(len(primos)) {

			}
			primos[j] = i
		}
	}

}

func main() {

	SieveOfEratosthenes(total)

	r := make([]int64, 0)

	for i, count := int64(1), int64(0); i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := int64(total - 1); i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	// fmt.Print(r[0])
	// for i := 1; i < len(r); i++ {
	// 	fmt.Printf(" %d", r[i])
	// }
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//SieveOfEratosthenes of earth
// func SieveOfEratosthenes(limite int) {

// 	for i := 2; i < limite; i++ {

// 		if primos[i] != i {
// 			primos[i] = i / primos[i]
// 			continue
// 		}
// 		for j := i * i; j < limite; j += i {
// 			if j > len(primos) {

// 			}
// 			primos[j] = i
// 		}
// 	}
// }

func main() {
	var auxi, auxj int
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
			fmt.Println(auxi, auxj)
		}
	}()
	fmt.Println("hola1")
	for i := 0; i < total; i++ {
		primos[i] = i
	}
	fmt.Println("hola2")
	// SieveOfEratosthenes(total)
	for auxi = 2; auxi < total; auxi++ {

		if primos[auxi] != auxi {
			primos[auxi] = auxi / primos[auxi]
			continue
		}
		for auxj = auxi * auxi; auxj < total; auxj += auxi {
			primos[auxj] = auxi
		}
	}

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int) {

	for i := 2; i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j += i {
			if j > len(primos) {

			}
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {

	for i := 2; i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j += i {
			if j > len(primos) {
				fmt.Println(j)
			}
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {

	for i := 2; i < limite; i++ {
		if i > len(primos) {
			fmt.Println(i)
		}
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j += i {
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {

	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(total)

		}
	}()
	fmt.Println()
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//SieveOfEratosthenes of earth
func SieveOfEratosthenes(limite int) {

	for i := 2; i < limite; i++ {

		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite && j > 0; j += i {
			if j > len(primos) {

			}
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("hola3")
		}
	}()

	SieveOfEratosthenes(total)

	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 512 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	total = 2750131 + 8
)

var primos [total]int
var indices [total]int
var repeticionesIn [total]int

func init() {
	for i := 0; i < total; i++ {
		primos[i] = i
	}
}

//Sieve of earth
func SieveOfEratosthenes(limite int) {
	for i := 2; i < limite; i++ {
		if primos[i] != i {
			primos[i] = i / primos[i]
			continue
		}
		for j := i * i; j < limite; j = j + i {
			primos[j] = i
		}
	}

}

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
		}
	}()
	SieveOfEratosthenes(total)
	r := make([]int, 0)

	for i, count := 1, 0; i < total; i++ {
		if primos[i] == i {
			indices[i] = count
			count++
		}
	}

	sc := bufio.NewScanner(os.Stdin)
	maxCap := 5120 * 1024
	buff := make([]byte, maxCap)
	sc.Buffer(buff, maxCap)
	sc.Scan()
	sc.Text()
	sc.Scan()
	input := strings.Fields(sc.Text())
	fmt.Println(input)
	for i := 0; i < len(input); i++ {
		val, _ := strconv.Atoi(input[i])
		repeticionesIn[val]++
	}

	for i := total - 1; i >= 0; i-- {
		for repeticionesIn[i] > 0 {
			if i == primos[i] {
				repeticionesIn[indices[i]]--
				r = append(r, indices[i])
			} else {
				repeticionesIn[primos[i]]--
				r = append(r, i)
			}
			repeticionesIn[i]--
		}
	}
	fmt.Print(r[0])
	for i := 1; i < len(r); i++ {
		fmt.Printf(" %d", r[i])
	}
	fmt.Println()
}