description: This problem is an extension of the problem "Wonderful Coloring - 1". It has quite many differences, so you should read this statement completely.
  
  Recently, Paul and Mary have found a new favorite sequence of integers a_1, a_2, ..., a_n. They want to paint it using pieces of chalk of k colors. The coloring of a sequence is called wonderful if the following conditions are met:
  
    1. each element of the sequence is either painted in one of k colors or isn't painted; 
    2. each two elements which are painted in the same color are different (i. e. there's no two equal values painted in the same color); 
    3. let's calculate for each of k colors the number of elements painted in the color — all calculated numbers must be equal; 
    4. the total number of painted elements of the sequence is the maximum among all colorings of the sequence which meet the first three conditions. 
  
  
  
  E. g. consider a sequence a=[3, 1, 1, 1, 1, 10, 3, 10, 10, 2] and k=3. One of the wonderful colorings of the sequence is shown in the figure.
  
  <image> The example of a wonderful coloring of the sequence a=[3, 1, 1, 1, 1, 10, 3, 10, 10, 2] and k=3. Note that one of the elements isn't painted.
  
  Help Paul and Mary to find a wonderful coloring of a given sequence a.
  
  Input
  
  The first line contains one integer t (1 ≤ t ≤ 10000) — the number of test cases. Then t test cases follow.
  
  Each test case consists of two lines. The first one contains two integers n and k (1 ≤ n ≤ 2⋅10^5, 1 ≤ k ≤ n) — the length of a given sequence and the number of colors, respectively. The second one contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ n).
  
  It is guaranteed that the sum of n over all test cases doesn't exceed 2 ⋅ 10^5.
  
  Output
  
  Output t lines, each of them must contain a description of a wonderful coloring for the corresponding test case.
  
  Each wonderful coloring must be printed as a sequence of n integers c_1, c_2, ..., c_n (0 ≤ c_i ≤ k) separated by spaces where
  
    * c_i=0, if i-th element isn't painted; 
    * c_i>0, if i-th element is painted in the c_i-th color. 
  
  
  
  Remember that you need to maximize the total count of painted elements for the wonderful coloring. If there are multiple solutions, print any one.
  
  Example
  
  Input
  
  
  6
  10 3
  3 1 1 1 1 10 3 10 10 2
  4 4
  1 1 1 1
  1 1
  1
  13 1
  3 1 4 1 5 9 2 6 5 3 5 8 9
  13 2
  3 1 4 1 5 9 2 6 5 3 5 8 9
  13 3
  3 1 4 1 5 9 2 6 5 3 5 8 9
  
  
  Output
  
  
  1 1 0 2 3 2 2 1 3 3
  4 2 1 3
  1
  0 0 1 1 0 1 1 1 0 1 1 1 0
  2 1 2 2 1 1 1 1 2 1 0 2 2
  1 1 3 2 1 3 3 1 2 2 3 2 0
  
  Note
  
  In the first test case, the answer is shown in the figure in the statement. The red color has number 1, the blue color — 2, the green — 3.
solution: import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Random;
  import java.util.StringTokenizer;
  
  public class B{
  // author: Tarun Verma
  static FastScanner sc = new FastScanner();
  static int inf = Integer.MAX_VALUE;
  static long mod = 1000000007;
  
  static boolean isPalindrom(char[] arr, int i, int j) {
  	boolean ok = true;
  	while (i <= j) {
  		if (arr[i] != arr[j]) {
  			ok = false;
  			break;
  		}
  		i++;
  		j--;
  	}
  	return ok;
  }
  
  static int max(int a, int b) {
  	return Math.max(a, b);
  }
  
  static int min(int a, int b) {
  	return Math.min(a, b);
  }
  
  static long max(long a, long b) {
  	return Math.max(a, b);
  }
  
  static long min(long a, long b) {
  	return Math.min(a, b);
  }
  
  static int abs(int a) {
  	return Math.abs(a);
  }
  
  static long abs(long a) {
  	return Math.abs(a);
  }
  
  static void swap(long arr[], int i, int j) {
  	long temp = arr[i];
  	arr[i] = arr[j];
  	arr[j] = temp;
  }
  
  static void swap(int arr[], int i, int j) {
  	int temp = arr[i];
  	arr[i] = arr[j];
  	arr[j] = temp;
  }
  
  static int maxArr(int arr[]) {
  	int maxi = Integer.MIN_VALUE;
  	for (int x : arr)
  		maxi = max(maxi, x);
  	return maxi;
  }
  
  static int minArr(int arr[]) {
  	int mini = Integer.MAX_VALUE;
  	for (int x : arr)
  		mini = min(mini, x);
  	return mini;
  }
  
  static long maxArr(long arr[]) {
  	long maxi = Long.MIN_VALUE;
  	for (long x : arr)
  		maxi = max(maxi, x);
  	return maxi;
  }
  
  static long minArr(long arr[]) {
  	long mini = Long.MAX_VALUE;
  	for (long x : arr)
  		mini = min(mini, x);
  	return mini;
  }
  
  static int gcd(int a, int b) {
  	if (b == 0)
  		return a;
  	return gcd(b, a % b);
  }
  
  static long gcd(long a, long b) {
  	if (b == 0)
  		return a;
  	return gcd(b, a % b);
  }
  
  static void ruffleSort(int[] a) {
  	int n = a.length;
  	Random r = new Random();
  	for (int i = 0; i < a.length; i++) {
  		int oi = r.nextInt(n);
  		int temp = a[i];
  		a[i] = a[oi];
  		a[oi] = temp;
  	}
  	Arrays.sort(a);
  }
  
  public static int binarySearch(int a[], int target) {
  	int left = 0;
  	int right = a.length - 1;
  	int mid = (left + right) / 2;
  	int i = 0;
  	while (left <= right) {
  		if (a[mid] <= target) {
  			i = mid + 1;
  			left = mid + 1;
  		} else {
  			right = mid - 1;
  		}
  		mid = (left + right) / 2;
  	}
  	return i;
  }
  
  static class FastScanner {
  	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  	StringTokenizer st = new StringTokenizer("");
  
  	String next() {
  		while (!st.hasMoreTokens())
  			try {
  				st = new StringTokenizer(br.readLine());
  			} catch (IOException e) {
  				e.printStackTrace();
  			}
  		return st.nextToken();
  	}
  
  	int nextInt() {
  		return Integer.parseInt(next());
  	}
  
  	int[] readArray(int n) {
  		int[] a = new int[n];
  		for (int i = 0; i < n; i++)
  			a[i] = nextInt();
  		return a;
  	}
  
  	int[][] read2dArray(int n, int m) {
  		int arr[][] = new int[n][m];
  		for (int i = 0; i < n; i++) {
  			for (int j = 0; j < m; j++) {
  				arr[i][j] = nextInt();
  			}
  		}
  		return arr;
  	}
  
  	ArrayList<Integer> readArrayList(int n) {
  		ArrayList<Integer> arr = new ArrayList<Integer>();
  		for (int i = 0; i < n; i++) {
  			int a = nextInt();
  			arr.add(a);
  		}
  		return arr;
  	}
  
  	long nextLong() {
  		return Long.parseLong(next());
  	}
  }
  
  static class pair {
  	int fr, sc;
  
  	pair(int fr, int sc) {
  		this.fr = fr;
  		this.sc = sc;
  	}
  }
  
  ////////////////////////////////////////////////////////////////////////////////////
  ////////////////////DO NOT TOUCH BEFORE THIS LINE //////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////
  public static void solve() {
  	int n = sc.nextInt();
  	int k = sc.nextInt();
  	int arr[] = sc.readArray(n);
  	int ans [] =new int[n];
  //	List<Integer> res [] = new List [1_000_07];
  //	for(int i =0;i<1_000_07;i++) {
  //		res[i] = new ArrayList<Integer>();
  //	}
  	HashMap<Integer, ArrayList<Integer>> mpp = new HashMap<Integer, ArrayList<Integer>>();
  	for(int i =0;i<n;i++) {
  		if(!mpp.containsKey(arr[i])) {
  			mpp.put(arr[i], new ArrayList<Integer>());
  		}
  		mpp.get(arr[i]).add(i);
  	}
  	int sum = 0;
  //	for(int i =0;i<10;i++) {
  //		if(res[i].size() < k) {
  //			sum+= res[i].size();
  //		}
  //	}
  	for(Map.Entry<Integer, ArrayList<Integer>> i: mpp.entrySet()) {
  		if(i.getValue().size() < k) {
  			sum+=i.getValue().size();
  		}
  	}
  	int tmp = 1;
  	int sum2 = (sum / k);
  	boolean ok = true;
  	for(Map.Entry<Integer, ArrayList<Integer>> i: mpp.entrySet()) {
  		if(i.getValue().size() >= k) {
  			for(int j = 0;j<k;j++) {
  				ans[i.getValue().get(j)] = j+1;
  			}
  		} else {
  			for(int j : i.getValue()) {
  				if(sum2 == 0) break;
  				ans[j] = tmp;
  				tmp++;
  				if(tmp > k) {
  					tmp = 1;
  					sum2--;
  				}
  				
  			}
  		}
  	}
  	for(int i: ans) {
  		System.out.print(i+  " ");
  	}System.out.println();
  	
  }
  
  public static void main(String[] args) {
  	int t = 1;
  	t = sc.nextInt();
  	outer: for (int tt = 0; tt < t; tt++) {
  		solve();
  	}
  }
  /* Common Mistakes By Me
   * make sure to read the bottom part of question
   * special cases (n=1?)
   * In Game Theory Check your solution and consider all the solutions
   * Always initialise value to the declare array in local scope
   * don't use debugs in interactive problems
   * Always Reset vis,adj array upto n+1 otherwise can cause TLE
  */
  ////////////////////////////////////////////////////////////////////////////////////	
  
  
  }