#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500000;
// SPF array for precomputing Smallest Prime Factors
vector<int> spf(MAXN + 1);
void computeSPF() {
iota(spf.begin(), spf.end(), 0); // Initialize spf[i] = i
for (int i = 2; i * i <= MAXN; ++i) {
if (spf[i] == i) { // Prime number found
for (int j = i * i; j <= MAXN; j += i) {
if (spf[j] == j) spf[j] = i; // Update smallest prime factor
}
}
}
}
void solve() {
int n;
cin >> n;
vector<int> C(n + 1);
for (int i = 1; i <= n; ++i) cin >> C[i];
// Group indices by their Smallest Prime Factor
unordered_map<int, vector<int>> groups;
for (int i = 1; i <= n; ++i) {
groups[spf[i]].push_back(i);
}
vector<int> A(n + 1, 0);
// Process each SPF group independently
for (auto &[prime, indices] : groups) {
vector<pair<int, int>> indexedC;
for (int idx : indices) {
indexedC.emplace_back(C[idx], idx);
}
// Sort by C[i] (we need to construct valid ordering)
sort(indexedC.begin(), indexedC.end());
int size = indices.size();
vector<int> sortedValues(size);
iota(sortedValues.begin(), sortedValues.end(), 1); // Assign values from 1 to size
for (int i = 0; i < size; ++i) {
int expected = indexedC[i].first;
if (expected != i) {
cout << "NO\n";
return;
}
A[indexedC[i].second] = sortedValues[i] + 1; // Assign increasing values
}
}
cout << "YES\n";
for (int i = 1; i <= n; ++i) cout << A[i] << " ";
cout << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
computeSPF(); // Precompute SPF values
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}