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: # Problem: B2. Wonderful Coloring - 2
  # Contest: Codeforces - Codeforces Round #734 (Div. 3)
  # URL: https://codeforces.com/contest/1551/problem/B2
  # Memory Limit: 256 MB
  # Time Limit: 2000 ms
  # 
  # Powered by CP Editor (https://cpeditor.org)
  
  # ____           ____   ___         # skeon19
  #|      | /     |      |   | |\   | # 
  #|____  |/      |___   |   | | \  | # EON_KID
  #     |	|\      |      |   | |  \ | #
  # ____|	| \ ___ |____  |___| |   \| # Soul_Silver
  
  from collections import defaultdict
  import sys,io,os
  INP=sys.stdin.readline
  inp=lambda:[*map(int,INP().encode().split())]
  sinp=lambda:[*map(str,INP().split())]
  out=sys.stdout.write
  #from functools import reduce
  #from bisect import bisect_right,bisect_left
  #from sortedcontainers import SortedList, SortedSet, SortedDict
  #import sympy #Prime number library
  #import heapq
  #Maxint=9223372036854775807
  
  def main():
      for _ in range(inp()[0]):
          n,k=inp()
          d=defaultdict(int)
          check=defaultdict(list)
          l=inp()
          for i in range(n):
          	if len(check[l[i]])<k:
          		check[l[i]].append(i)
          	
          c=0
          ans=[0]*n
          for i in check:
          	c+=len(check[i])
          r=c//k
          res=[]
          m=k
          for i in range(r*k):
          	res.append(m)
          	m-=1
          	if m==0:
          		m=k
          coz=[]
          
          for i in check:
          	coz+=check[i]
          for i in range(r*k):
          	ans[coz[i]]=res[i]
          print(" ".join(map(str,ans)))
  
  
          	 
          
          
          
          
  ###############################################################       
  def SumOfExpOfFactors(a):
  	fac = 0
  	lis=SortedList()
  	if not a&1: 
  		lis.add(2)
  	while not a&1:
  		a >>= 1
  		fac += 1
  	for i in range(3,int(a**0.5)+1,2):
  		if not a%i:
  			lis.add(i)
  		while not a%i:
  			a //= i
  			fac += 1
  	if a != 1:
  		lis.add(a)
  		fac += 1
  	return fac,lis
  ###############################################################
  div=[0]*(1000001)
  def NumOfDivisors(n): #O(nlog(n))
  	for i in range(1,n+1):
  		for j in range(i,n+1,i):
  			div[j]+=1
  ###############################################################
  def primes1(n): #return a list having prime numbers from 2 to n
      """ Returns  a list of primes < n """
      sieve = [True] * (n//2)
      for i in range(3,int(n**0.5)+1,2):
          if sieve[i//2]:
              sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1)
      return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]
  ##############################################################    
  def GCD(a,b):
      if(b==0):
          return a
      else:
          return GCD(b,a%b)
  ##############################################################
  #
  #     1
  #   /   \
  #  2     3
  # /\   / \ \ \
  #4  5  6 7 8 9
  #      \
  #      10
  
  class Graph:
      def __init__(self):
          self.Graph = defaultdict(list)
          
      def addEdge(self, u, v):
          self.Graph[u].append(v)
          self.Graph[v].append(u)
      #DFS Graph / tree    
      def DFSUtil(self, v, visited):
          visited.add(v)
          #print(v, end=' ')
          for neighbour in self.Graph[v]:
              if neighbour not in visited: #not needed if its a tree
                  self.DFSUtil(neighbour, visited)
      def DFS(self, v):
   
          visited = set() #not needed if its a tree
          self.DFSUtil(v, visited) #Visited not needed if its a tree
      #BFS Graph / tree
      def BFS(self, s):
          # Mark all the vertices as not visited
          
          visited = set()
          # Create a queue for BFS
          queue = []
          queue.append(s)
          visited.add(s)
          while queue:
              s = queue.pop(0)
              #print (s, end = " ")
              for i in self.Graph[s]:
                  if i not in visited:
                      queue.append(i)
                      visited.add(i)
  '''
  g = Graph()
  g.addEdge(1, 2)
  g.addEdge(1, 3)
  g.addEdge(2, 4)
  g.addEdge(2, 5)
  g.addEdge(3, 6)
  g.addEdge(3, 7)
  g.addEdge(3, 8)
  g.addEdge(3, 9)
  g.addEdge(6,10)
  g.DFS(1)  
  g.BFS(1)  '''   
  ##############################################################
  class SortedList:
      def __init__(self, iterable=[], _load=200):
          """Initialize sorted list instance."""
          values = sorted(iterable)
          self._len = _len = len(values)
          self._load = _load
          self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
          self._list_lens = [len(_list) for _list in _lists]
          self._mins = [_list[0] for _list in _lists]
          self._fen_tree = []
          self._rebuild = True
  
      def _fen_build(self):
          """Build a fenwick tree instance."""
          self._fen_tree[:] = self._list_lens
          _fen_tree = self._fen_tree
          for i in range(len(_fen_tree)):
              if i | i + 1 < len(_fen_tree):
                  _fen_tree[i | i + 1] += _fen_tree[i]
          self._rebuild = False
  
      def _fen_update(self, index, value):
          """Update `fen_tree[index] += value`."""
          if not self._rebuild:
              _fen_tree = self._fen_tree
              while index < len(_fen_tree):
                  _fen_tree[index] += value
                  index |= index + 1
  
      def _fen_query(self, end):
          """Return `sum(_fen_tree[:end])`."""
          if self._rebuild:
              self._fen_build()
  
          _fen_tree = self._fen_tree
          x = 0
          while end:
              x += _fen_tree[end - 1]
              end &= end - 1
          return x
  
      def _fen_findkth(self, k):
          """Return a pair of (the largest `idx` such that `sum(_fen_tree[:idx]) <= k`, `k - sum(_fen_tree[:idx])`)."""
          _list_lens = self._list_lens
          if k < _list_lens[0]:
              return 0, k
          if k >= self._len - _list_lens[-1]:
              return len(_list_lens) - 1, k + _list_lens[-1] - self._len
          if self._rebuild:
              self._fen_build()
  
          _fen_tree = self._fen_tree
          idx = -1
          for d in reversed(range(len(_fen_tree).bit_length())):
              right_idx = idx + (1 << d)
              if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
                  idx = right_idx
                  k -= _fen_tree[idx]
          return idx + 1, k
  
      def _delete(self, pos, idx):
          """Delete value at the given `(pos, idx)`."""
          _lists = self._lists
          _mins = self._mins
          _list_lens = self._list_lens
  
          self._len -= 1
          self._fen_update(pos, -1)
          del _lists[pos][idx]
          _list_lens[pos] -= 1
  
          if _list_lens[pos]:
              _mins[pos] = _lists[pos][0]
          else:
              del _lists[pos]
              del _list_lens[pos]
              del _mins[pos]
              self._rebuild = True
  
      def _loc_left(self, value):
          """Return an index pair that corresponds to the first position of `value` in the sorted list."""
          if not self._len:
              return 0, 0
  
          _lists = self._lists
          _mins = self._mins
  
          lo, pos = -1, len(_lists) - 1
          while lo + 1 < pos:
              mi = (lo + pos) >> 1
              if value <= _mins[mi]:
                  pos = mi
              else:
                  lo = mi
  
          if pos and value <= _lists[pos - 1][-1]:
              pos -= 1
  
          _list = _lists[pos]
          lo, idx = -1, len(_list)
          while lo + 1 < idx:
              mi = (lo + idx) >> 1
              if value <= _list[mi]:
                  idx = mi
              else:
                  lo = mi
  
          return pos, idx
  
      def _loc_right(self, value):
          """Return an index pair that corresponds to the last position of `value` in the sorted list."""
          if not self._len:
              return 0, 0
  
          _lists = self._lists
          _mins = self._mins
  
          pos, hi = 0, len(_lists)
          while pos + 1 < hi:
              mi = (pos + hi) >> 1
              if value < _mins[mi]:
                  hi = mi
              else:
                  pos = mi
  
          _list = _lists[pos]
          lo, idx = -1, len(_list)
          while lo + 1 < idx:
              mi = (lo + idx) >> 1
              if value < _list[mi]:
                  idx = mi
              else:
                  lo = mi
  
          return pos, idx
  
      def add(self, value):
          """Add `value` to sorted list."""
          _load = self._load
          _lists = self._lists
          _mins = self._mins
          _list_lens = self._list_lens
  
          self._len += 1
          if _lists:
              pos, idx = self._loc_right(value)
              self._fen_update(pos, 1)
              _list = _lists[pos]
              _list.insert(idx, value)
              _list_lens[pos] += 1
              _mins[pos] = _list[0]
              if _load + _load < len(_list):
                  _lists.insert(pos + 1, _list[_load:])
                  _list_lens.insert(pos + 1, len(_list) - _load)
                  _mins.insert(pos + 1, _list[_load])
                  _list_lens[pos] = _load
                  del _list[_load:]
                  self._rebuild = True
          else:
              _lists.append([value])
              _mins.append(value)
              _list_lens.append(1)
              self._rebuild = True
  
      def discard(self, value):
          """Remove `value` from sorted list if it is a member."""
          _lists = self._lists
          if _lists:
              pos, idx = self._loc_right(value)
              if idx and _lists[pos][idx - 1] == value:
                  self._delete(pos, idx - 1)
  
      def remove(self, value):
          """Remove `value` from sorted list; `value` must be a member."""
          _len = self._len
          self.discard(value)
          if _len == self._len:
              raise ValueError('{0!r} not in list'.format(value))
  
      def pop(self, index=-1):
          """Remove and return value at `index` in sorted list."""
          pos, idx = self._fen_findkth(self._len + index if index < 0 else index)
          value = self._lists[pos][idx]
          self._delete(pos, idx)
          return value
  
      def bisect_left(self, value):
          """Return the first index to insert `value` in the sorted list."""
          pos, idx = self._loc_left(value)
          return self._fen_query(pos) + idx
  
      def bisect_right(self, value):
          """Return the last index to insert `value` in the sorted list."""
          pos, idx = self._loc_right(value)
          return self._fen_query(pos) + idx
  
      def count(self, value):
          """Return number of occurrences of `value` in the sorted list."""
          return self.bisect_right(value) - self.bisect_left(value)
  
      def __len__(self):
          """Return the size of the sorted list."""
          return self._len
  
      def __getitem__(self, index):
          """Lookup value at `index` in sorted list."""
          pos, idx = self._fen_findkth(self._len + index if index < 0 else index)
          return self._lists[pos][idx]
  
      def __delitem__(self, index):
          """Remove value at `index` from sorted list."""
          pos, idx = self._fen_findkth(self._len + index if index < 0 else index)
          self._delete(pos, idx)
  
      def __contains__(self, value):
          """Return true if `value` is an element of the sorted list."""
          _lists = self._lists
          if _lists:
              pos, idx = self._loc_left(value)
              return idx < len(_lists[pos]) and _lists[pos][idx] == value
          return False
  
      def __iter__(self):
          """Return an iterator over the sorted list."""
          return (value for _list in self._lists for value in _list)
  
      def __reversed__(self):
          """Return a reverse iterator over the sorted list."""
          return (value for _list in reversed(self._lists) for value in reversed(_list))
  
      def __repr__(self):
          """Return string representation of sorted list."""
          return 'SortedList({0})'.format(list(self))
      # https://github.com/cheran-senthil/PyRival/blob/master/pyrival/data_structures/SortedList.py
  ###################################################################################################
  
  if __name__ == '__main__':
      main()