import Foundation

//素数判定する関数 ex:) primeJudge(32) -> true
func primeJudge(_ num: Int) -> Bool {
    var i = 2
    if num == 1 {
        return false
    }
    if num == 2 || num == 3{
        return true
    }

    for i in 2 ... Int(sqrt(Double(num))) {
        if num%i == 0 {
            return false
        }
    }
    return true
}

//約数列挙する関数 ex:) multiple(32) -> [1,2,4,8,16,32]
func factors(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    for i in 1 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            factorsArr.append(i)
            if num/i != i {
            factorsArr.append(num/i)
            }
        }
    }

    return factorsArr.sorted()
}
//指数を求める ex:) exponents(32,2) -> 5
func exponents(_ num1: Int, _ num2: Int) -> Int {
    if num2 == 1 {
        return 1
    }
    var count = 0
    var num1 = num1
    while num1.isMultiple(of: num2) {
        num1 /= num2
        count += 1
    }
    return count
}

//素因数分解1 役数と指数を連続で格納
func primeFactorization1(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
            factorsArr.append(i)
            factorsArr.append(exponents(num, i))
            }
        }
    }
    print(factorsArr)
    return factorsArr.sorted()
}

//素因数分解2 役数と指数を別の配列に格納
func primeFactorization2(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    var exponentsArr = [Int]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
            factorsArr.append(i)
            exponentsArr.append(exponents(num, i))
            }
        }
    }
    print(factorsArr)
    print(exponentsArr)
    return factorsArr.sorted()
}
//素因数分解3 役数と指数を二次元配列に格納
func primeFactorization3(_ num: Int) -> [[Int]] {
    var primeFactArr = [[Int]]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
                primeFactArr.append([i,exponents(num, i)])
            }
        }
    }
    return primeFactArr
}
primeFactorization3(150)
//桁数を返す関数
func numberOfDigits(_ num: Int) -> Int {
    var digits = 1
    var num = num
    while num >= 10 {
        num /= 10
        digits += 1
    }
    return digits
}

let rdInt = Int(readLine()!)!

func factors1(_ num: Int) -> Int {
    var factorsArr = [Int]()
    for i in 1 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            factorsArr.append(max(numberOfDigits(i),numberOfDigits(num/i)))
        }
    }

    return factorsArr.min()!
}

print(factors1(rdInt))


import Foundation

//素数判定する関数 ex:) primeJudge(32) -> true
func primeJudge(_ num: Int) -> Bool {
    var i = 2
    if num == 1 {
        return false
    }
    if num == 2 || num == 3{
        return true
    }

    for i in 2 ... Int(sqrt(Double(num))) {
        if num%i == 0 {
            return false
        }
    }
    return true
}

//約数列挙する関数 ex:) multiple(32) -> [1,2,4,8,16,32]
func factors(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    for i in 1 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            factorsArr.append(i)
            if num/i != i {
            factorsArr.append(num/i)
            }
        }
    }

    return factorsArr.sorted()
}
//指数を求める ex:) exponents(32,2) -> 5
func exponents(_ num1: Int, _ num2: Int) -> Int {
    if num2 == 1 {
        return 1
    }
    var count = 0
    var num1 = num1
    while num1.isMultiple(of: num2) {
        num1 /= num2
        count += 1
    }
    return count
}

//素因数分解1 役数と指数を連続で格納
func primeFactorization1(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
            factorsArr.append(i)
            factorsArr.append(exponents(num, i))
            }
        }
    }
    print(factorsArr)
    return factorsArr.sorted()
}

//素因数分解2 役数と指数を別の配列に格納
func primeFactorization2(_ num: Int) -> [Int] {
    var factorsArr = [Int]()
    var exponentsArr = [Int]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
            factorsArr.append(i)
            exponentsArr.append(exponents(num, i))
            }
        }
    }
    print(factorsArr)
    print(exponentsArr)
    return factorsArr.sorted()
}
//素因数分解3 役数と指数を二次元配列に格納
func primeFactorization3(_ num: Int) -> [[Int]] {
    var primeFactArr = [[Int]]()
    for i in 2 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            if primeJudge(i) {
                primeFactArr.append([i,exponents(num, i)])
            }
        }
    }
    return primeFactArr
}
primeFactorization3(150)
//桁数を返す関数
func numberOfDigits(_ num: Int) -> Int {
    var digits = 1
    var num = num
    while num >= 10 {
        num /= 10
        digits += 1
    }
    return digits
}

let rdInt = Int(readLine()!)!

func factors1(_ num: Int) -> Int {
    var factorsArr = [Int]()
    for i in 1 ... Int(sqrt(Double(num))) {
        if num.isMultiple(of: i) {
            print(i,num/i)
            print(numberOfDigits(i),numberOfDigits(num/i))
            factorsArr.append(max(numberOfDigits(i),numberOfDigits(num/i)))
        }
    }
    print(factorsArr)

    return factorsArr.min()!
}

print(factors1(rdInt))


import CoreFoundation
let N = Int(readLine()!)!
let divisors = (1...Int(sqrt(Double(N)))).filter{N % $0 == 0}
print(String(divisors[divisors.count-1]).characters.count)


import CoreFoundation
let N = Int(readLine()!)!
let divisors = (1...Int(sqrt(Double(N)))!).filter{N % $0 == 0}
print(String(divisors[divisors.count-1]).characters.count)


"use strict";

const Main = args => {
  const input = args.trim() - 0;
  const max = Math.floor(Math.sqrt(input));

  let result = input.toString().length

  for (let a = 1; a <= max; a++) {
    if (input % a === 0) {
      let b = input / a;
      let tmp = Math.max(a.toString().length, b.toString().length);

      if (tmp < result) {
        result = tmp;
      }
    }
  }

  console.log(result);

}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


"use strict";

const Main = args => {
  const input = args.trim() - 0;
  const max = Math.floor(Math.sqrt(input));

  let result = input.toString().length

  for (let a = 1; a < max; a++) {
    if (input % a === 0) {
      let b = input / a;
      let tmp = Math.max(a.toString().length, b.toString().length);

      if (tmp < result) {
        result = tmp;
      }
    }
  }

  console.log(result);

}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


# ABC081C - Not so Diverse (ARC086C)
from collections import Counter

def main():
    n, k = map(int, input().rstrip().split())
    A = sorted(Counter(input().split()).values(), reverse=True)
    print(sum(A[k:]))

if __name__ == "__main__":
    main()


from collections import Counter
n, k = map(int, input().split())
al = sorted(Counter(input().split()).values(), reverse=True)
print(sum(al[k:]))


# ARC086C - Not so Diverse (ABC081C)
from collections import Counter

def main():
    _, k, *a = map(int, open(0).read().split())
    print(sum(sorted(Counter(a).values(), reverse=True)[k:]))

if __name__ == "__main__":
    main()


import collections as c
N,K,*A= map(int,open(0).read().split())
ans=0
C=c.Counter(A)
C=sorted(C.values())

colors = len(C)

for i in range(colors):
  if len(C)<=K:
    break
  _c = C.pop(0)
  ans+=_c
print(ans)


import collections as c
N,K,*A= map(int,open(0).read().split())
ans=0
C=c.Counter(A)
C=sorted(C.values())

for i in range(N):
  if len(C)<=K:
    break
  ans+=C[i]
print(ans)


import collections as c
N,K,*A= map(int,open(0).read().split())
ans=0
C=c.Counter(A)
C=sorted(C.values(),key=lambda x:x)

for i in C:
  if len(C)<=K:
    break
  _c = C.pop(0)
  ans+=_c
print(ans)


import java.io.*;
import java.util.*;
import java.math.*;
// import java.awt.Point;

public class Main {
    InputStream is;
    PrintWriter out;
    String INPUT = "";

    long MOD = 1_000_000_007;
    int inf = Integer.MAX_VALUE;

    void solve(){
        int n = ni();
        int k  = ni();
        int[] a = new int[n];
        int[] c = new int[n+1];
        for(int i = 0; i < n; i++){
            a[i] = ni();
            c[a[i]]++;
        }
        Arrays.sort(c);
        long ans = 0;
        for(int i = n; i >= n-k+1; i--){
            ans += c[i];
        }
        out.println(n-ans);
    }

    void run() throws Exception
    {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        solve();
        out.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new Main().run(); }

    private byte[] inbuf = new byte[1024];
    private int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b) && b != ' ')){
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }

}


import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws IOException {
        Scan sc = new Scan();
        int n = sc.scanInt();
        int k = sc.scanInt();
        int[] arr = new int[n+1];
        int cmp = 0;
        for(int i= 0; i < n; ++i){
            int id = sc.scanInt();
            arr[id]++;
            if(arr[id] == 1)
                ++cmp;
        }
        if(cmp <= k){
            System.out.println("0");
            return;
        }

        Arrays.sort(arr);
        int res = 0;
        for(int i= 0; cmp > k && i <= n; ++i){
            if(arr[i] == 0)
                continue;
            cmp--;
            res += arr[i];
        }
        System.out.println(res);
    }
}

class Scan
{
    private byte[] buf=new byte[1024];
    private int index;
    private InputStream in;
    private int total;
    public Scan()
    {
        in=System.in;
    }
    public int scan()throws IOException
    {
        if(total<0)
        throw new InputMismatchException();
        if(index>=total)
        {
            index=0;
            total=in.read(buf);
            if(total<=0)
            return -1;
        }
        return buf[index++];
    }
    public int scanInt()throws IOException
    {
        int integer=0;
        int n=scan();
        while(isWhiteSpace(n))
        n=scan();
        int neg=1;
        if(n=='-')
        {
            neg=-1;
            n=scan();
        }
        while(!isWhiteSpace(n))
        {
            if(n>='0'&&n<='9')
            {
                integer*=10;
                integer+=n-'0';
                n=scan();
            }
            else throw new InputMismatchException();
        }
        return neg*integer;
    }
    public long scanLong() throws IOException {
        long integer=0;
        int n=scan();
        while(isWhiteSpace(n))
        n=scan();
        int neg=1;
        if(n=='-')
        {
            neg=-1;
            n=scan();
        }
        while(!isWhiteSpace(n))
        {
            if(n>='0'&&n<='9')
            {
                integer*=10;
                integer+=n-'0';
                n=scan();
            }
            else throw new InputMismatchException();
        }
        return neg*integer;
    }
    public double scanDouble()throws IOException
    {
        double doub=0;
        int n=scan();
        while(isWhiteSpace(n))
        n=scan();
        int neg=1;
        if(n=='-')
        {
            neg=-1;
            n=scan();
        }
        while(!isWhiteSpace(n)&&n!='.')
        {
            if(n>='0'&&n<='9')
            {
                doub*=10;
                doub+=n-'0';
                n=scan();
            }
            else throw new InputMismatchException();
        }
        if(n=='.')
        {
            n=scan();
            double temp=1;
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    temp/=10;
                    doub+=(n-'0')*temp;
                    n=scan();
                }
                else throw new InputMismatchException();
            }
        }
        return doub*neg;
    }
    public String scanString()throws IOException
    {
        StringBuilder sb=new StringBuilder();
        int n=scan();
        while(isWhiteSpace(n))
        n=scan();
        while(!isWhiteSpace(n))
        {
            sb.append((char)n);
            n=scan();
        }
        return sb.toString();
    }
    private boolean isWhiteSpace(int n)
    {
        if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
        return true;
        return false;
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
	static InputStream is;
	static PrintWriter out;
	static String INPUT = "";

	static void solve()
	{
		int n = ni(), K = ni();
		int[] a = na(n);
		int[] f = new int[200005];
		for(int v : a)f[v]++;
		Arrays.sort(f);
		int fix = 0;
		for(int i = 1;i <= K;i++){
			fix += f[200005-i];
		}
		out.println(n-fix);

	}

	public static void main(String[] args) throws Exception
	{
		long S = System.currentTimeMillis();
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		solve();
		out.flush();
		long G = System.currentTimeMillis();
		tr(G-S+"ms");
	}

	private static boolean eof()
	{
		if(lenbuf == -1)return true;
		int lptr = ptrbuf;
		while(lptr < lenbuf)if(!isSpaceChar(inbuf[lptr++]))return false;

		try {
			is.mark(1000);
			while(true){
				int b = is.read();
				if(b == -1){
					is.reset();
					return true;
				}else if(!isSpaceChar(b)){
					is.reset();
					return false;
				}
			}
		} catch (IOException e) {
			return true;
		}
	}

	private static byte[] inbuf = new byte[1024];
	static int lenbuf = 0, ptrbuf = 0;

	private static int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private static boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
//	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
	private static int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private static double nd() { return Double.parseDouble(ns()); }
	private static char nc() { return (char)skip(); }

	private static String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private static char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private static char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private static int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private static int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) { if(INPUT.length() != 0)System.out.println(Arrays.deepToString(o)); }
}


import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int k  = sc.nextInt();
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int a = sc.nextInt();
            int count = map.getOrDefault(a,0);
            map.put(a, ++count);
        }

        if (map.size() <= k) {
            System.out.println(0);
        }

        int diff = map.size() - k ;
        List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
        list.sort((e1, e2) -> (e1.getValue() - e2.getValue()));
        int count = 0;
        for (int i = 0; i < diff; i++) {
            count += list.get(i).getValue();
        }

        System.out.println(count);
    }
}


import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.next());
        int k = Integer.parseInt(sc.next());
        HashMap<Long, Long> h = new HashMap<>();
        for (int i = 0; i < n; i++) {
            long a = Long.parseLong(sc.next());
            if (h.containsKey(a)) {
                h.put(a, h.get(a) + 1);
            } else {
                h.put(a, 1L);
            }
        }
        sc.close();
        h.entrySet().stream().sorted(Map.Entry.comparingByValue());
        long ans = 0, i = 0;
        for (long v : h.values()) {
            i++;
            if (i > k) {
                ans += v;
            }
        }
        System.out.println(ans);
    }
}


import java.util.*;
import java.util.stream.Collectors;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.next());
        int k = Integer.parseInt(sc.next());
        HashMap<Long, Long> h = new HashMap<>();
        for (int i = 0; i < n; i++) {
            long a = Long.parseLong(sc.next());
            if (h.containsKey(a)) {
                h.put(a, h.get(a) + 1);
            } else {
                h.put(a, 1L);
            }
        }
        sc.close();
        List<Long> s = h.keySet().stream().collect(Collectors.toList());
        s.sort(Comparator.reverseOrder());
        long ans = 0, i = 0;
        for (long v : s) {
            i++;
            if (i > k) {
                ans += v;
            }
        }
        System.out.println(ans);
    }
}


//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	int N = getint(), K = getint();

	int A[200001] = {};
	rep(i, N) {
		A[getint()]++;
	}
	int n[200001] = {};
	rep(i, 200001) {
		n[A[i]]++;
	}
	int kotae = N;
	for (int i = 200000; i >= 1; i--) {
		int k = min(K, n[i]);
		kotae -= k * i;
		K -= k;
	}
	printf("%d", kotae);

	Would you please return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>

#include <cstdio>
#include <cstring>
#include <cstdint>
#include <cstdlib>
#include <cstddef>

#include <type_traits>

namespace FastIn {
  static constexpr size_t BUF_SIZE=1<<17, INT_LEN=24, FLT_LEN=400;
  static char buf[BUF_SIZE|1]={}, *pos=buf, *endbuf=nullptr;

  inline bool rebuffer() {
    size_t rest=endbuf-pos;
    if (static_cast<ptrdiff_t>(rest) > pos-buf) {
      // not disjoint
      return true;
    }

    // disjoint
    std::memcpy(buf, pos, rest);

    pos = buf;

    size_t len=std::fread(pos+rest, 1, BUF_SIZE-rest, stdin);
    *(endbuf = buf + (rest+len)) = 0;

    return *pos;
  }

  inline bool scan(char &in) {
    if ((in = *pos)) {
      ++pos;
      return true;
    }

    return rebuffer() && (in = *pos++);
  }

  inline bool scan(char *in) {
    if ((*in = *pos) == 0) {
      if (rebuffer() && (*in = *pos) == 0) {
        return false;
      }
    }
    ++in;
    while (true) {
      if ((*in = *pos++) == 0) {
        if (rebuffer() && (*in = *pos++) == 0) {
          return true;
        }
      }
      ++in;
    }
  }

  inline bool scan(double &in) {
    if (pos + FLT_LEN >= endbuf && !rebuffer()) {
      in = 0.0;
      return false;
    }

    char *tmp;
    in = std::strtod(pos, &tmp);
    pos = tmp;
    return true;
  }

  template <class Int>
  inline bool scan(
      Int &in,
      typename std::enable_if<std::is_signed<Int>::value>::type *un=nullptr
  ) {
    in = 0;

    // assume that no redundant whitespace appears
    if (pos + INT_LEN >= endbuf && !rebuffer()) {
      return false;
    }

    // assume that ' ' < '+' < '-' < '0' < '9'
    while (*pos < '-') {
      ++pos;
    }

    bool neg=false;
    if (*pos == '-') {
      ++pos;
      neg = true;
    }

    // assume that numbers are separated by the character whose value is
    // less than '0' (e.g. whitespaces, newlines)
    do {
      in = in*10 + (*pos)-'0';
    } while (*++pos >= '0');

    if (neg) {
      in = -in;
    }
    return true;
  }

  template <class Int>
  inline bool scan(
      Int &in,
      typename std::enable_if<!std::is_signed<Int>::value>::type *un=nullptr
  ) {
    in = 0;

    // assume that no redundant whitespace appears
    if (pos + INT_LEN >= endbuf && !rebuffer()) {
      return false;
    }

    // assume that ' ' < '0' < '9' and minus signs do not appear
    //while (*pos < '0') {
    //  ++pos;
    //}

    // assume that numbers are separated by the character whose value is
    // less than '0' (e.g. whitespaces, newlines)
    do {
      in = in*10 + (*pos)-'0';
    } while (*++pos >= '0');

    ++pos;
    return true;
  }

  inline bool eat() {
    if (*pos > ' ') {
      return true;
    }

    do {
      if (*pos == 0 && !rebuffer()) {
        return false;
      }
    } while (*++pos <= ' ');

    return true;
  }

  inline bool eat(char ch) {
    if (*pos == ch) {
      return true;
    }

    do {
      if (*pos == 0 && !rebuffer()) {
        return false;
      }
    } while (*++pos != ch);

    return true;
  }

  class Scanner {
    bool rebuffer() {
      return FastIn::rebuffer();
    }

  public:
    Scanner() {
      endbuf = pos + std::fread(buf, 1, BUF_SIZE, stdin);
    }

    template <class T>
    inline bool scan(T &in) {
      return FastIn::scan(in);
    }

    template <class First, class... Rest>
    inline bool scan(First &in, Rest &...ins) {
      return scan(in) && scan(ins...);
    }
  };
}

template <class RandomIt, class IntType>
void bsort(RandomIt first, RandomIt last, IntType bound) {
  std::vector<IntType> bucket(bound);
  for (RandomIt it=first; it<last; ++it) {
    ++bucket[*it];
  }

  for (IntType i=0; i<bound; ++i) {
    while (bucket[i]--) {
      *first = i;
      ++first;
    }
  }
}

FastIn::Scanner cin;

int main() {
  size_t N;
  unsigned K;
  cin.scan(N, K);

  if (N == K) {
    printf("0\n");
    return 0;
  }

  std::vector<unsigned> A(N+1);
  for (size_t i=0; i<N; ++i) {
    unsigned a;
    cin.scan(a);
    ++A[a];
  }

  bsort(A.begin(), A.end(), N+1);

  size_t nonzero=std::upper_bound(A.begin(), A.end(), 0)-A.begin();
  K += nonzero;

  int res=0;
  for (size_t i=nonzero; i<N; ++i) {
    if (N < K) break;

    if (A[i]) {
      res += A[i];
      ++K;
    }
  }

  printf("%d\n", res);
  return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>

#include <cstdio>
#include <cstring>
#include <cstdint>
#include <cstdlib>
#include <cstddef>

#include <type_traits>

namespace FastIn {
  static constexpr size_t BUF_SIZE=1<<17, INT_LEN=24, FLT_LEN=400;
  static char buf[BUF_SIZE|1]={}, *pos=buf, *endbuf=nullptr;

  inline bool rebuffer() {
    size_t rest=endbuf-pos;
    if (static_cast<ptrdiff_t>(rest) > pos-buf) {
      // not disjoint
      return true;
    }

    // disjoint
    std::memcpy(buf, pos, rest);

    pos = buf;

    size_t len=std::fread(pos+rest, 1, BUF_SIZE-rest, stdin);
    *(endbuf = buf + (rest+len)) = 0;

    return *pos;
  }

  inline bool scan(char &in) {
    if ((in = *pos)) {
      ++pos;
      return true;
    }

    return rebuffer() && (in = *pos++);
  }

  inline bool scan(char *in) {
    if ((*in = *pos) == 0) {
      if (rebuffer() && (*in = *pos) == 0) {
        return false;
      }
    }
    ++in;
    while (true) {
      if ((*in = *pos++) == 0) {
        if (rebuffer() && (*in = *pos++) == 0) {
          return true;
        }
      }
      ++in;
    }
  }

  inline bool scan(double &in) {
    if (pos + FLT_LEN >= endbuf && !rebuffer()) {
      in = 0.0;
      return false;
    }

    char *tmp;
    in = std::strtod(pos, &tmp);
    pos = tmp;
    return true;
  }

  template <class Int>
  inline bool scan(
      Int &in,
      typename std::enable_if<std::is_signed<Int>::value>::type *un=nullptr
  ) {
    in = 0;

    // assume that no redundant whitespace appears
    if (pos + INT_LEN >= endbuf && !rebuffer()) {
      return false;
    }

    // assume that ' ' < '+' < '-' < '0' < '9'
    while (*pos < '-') {
      ++pos;
    }

    bool neg=false;
    if (*pos == '-') {
      ++pos;
      neg = true;
    }

    // assume that numbers are separated by the character whose value is
    // less than '0' (e.g. whitespaces, newlines)
    do {
      in = in*10 + (*pos)-'0';
    } while (*++pos >= '0');

    if (neg) {
      in = -in;
    }
    return true;
  }

  template <class Int>
  inline bool scan(
      Int &in,
      typename std::enable_if<!std::is_signed<Int>::value>::type *un=nullptr
  ) {
    in = 0;

    // assume that no redundant whitespace appears
    if (pos + INT_LEN >= endbuf && !rebuffer()) {
      return false;
    }

    // assume that ' ' < '0' < '9' and minus signs do not appear
    //while (*pos < '0') {
    //  ++pos;
    //}

    // assume that numbers are separated by the character whose value is
    // less than '0' (e.g. whitespaces, newlines)
    do {
      in = in*10 + (*pos)-'0';
    } while (*++pos >= '0');

    ++pos;
    return true;
  }

  inline bool eat() {
    if (*pos > ' ') {
      return true;
    }

    do {
      if (*pos == 0 && !rebuffer()) {
        return false;
      }
    } while (*++pos <= ' ');

    return true;
  }

  inline bool eat(char ch) {
    if (*pos == ch) {
      return true;
    }

    do {
      if (*pos == 0 && !rebuffer()) {
        return false;
      }
    } while (*++pos != ch);

    return true;
  }

  class Scanner {
    bool rebuffer() {
      return FastIn::rebuffer();
    }

  public:
    Scanner() {
      endbuf = pos + std::fread(buf, 1, BUF_SIZE, stdin);
    }

    template <class T>
    inline bool scan(T &in) {
      return FastIn::scan(in);
    }

    template <class First, class... Rest>
    inline bool scan(First &in, Rest &...ins) {
      return scan(in) && scan(ins...);
    }
  };
}

template <class RandomIt, class IntType>
void bsort(RandomIt first, RandomIt last, IntType bound) {
  std::vector<IntType> bucket(bound);
  for (RandomIt it=first; it<last; ++it) {
    ++bucket[*it];
  }

  for (IntType i=0; i<bound; ++i) {
    while (bucket[i]--) {
      *first = i;
      ++first;
    }
  }
}

FastIn::Scanner cin;

int main() {
  size_t N;
  unsigned K;
  cin.scan(N, K);

  if (N == K) {
    printf("0\n");
    return 0;
  }

  std::vector<unsigned> A(N+1);
  for (size_t i=0; i<N; ++i) {
    unsigned a;
    cin.scan(a);
    ++A[a];
  }

  bsort(A.begin(), A.end(), N+1);

  size_t i=0;

  while (A[i] == 0) {
    ++i;
  }

  K += i;
  int res=0;
  for (; i<N; ++i) {
    if (N < K) break;

    if (A[i]) {
      res += A[i];
      ++K;
    }
  }

  printf("%d\n", res);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
void Main();

using i8  = int8_t;   /* -128 ~ 127 */
using u8  = uint8_t;  /* 0 ~ 255 */
using i16 = int16_t;  /* -32,768 ~ 32,767 */
using u16 = uint16_t; /* 0 ~ 65,535 */
using i32 = int32_t;  /* -2,147,483,648 ~ 2,147,483,647 */
using u32 = uint32_t; /* 0 ~ 4,294,967,295 */
using i64 = int64_t;  /* -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 */
using u64 = uint64_t; /* 0 ~ 18,446,744,073,709,551,615 */
using f32 = float;    /* (-3.4 * 10^38) ~ (3.4 * 10^38) */
using f64 = double;   /* (-1.7 * 10^308) ~ (1.7 * 10^308) */
using f80 = __float80;
template <class T> using Vec = vector<T>;
constexpr i64 INF = 1010000000000000017;
constexpr i64 MOD = 1e9 + 7;
constexpr f64 EPS = 1e-12;
constexpr f64 PI = 3.14159265358979323846;
#define ALL(v) v.begin(), v.end()
#define YN(a, b, c) ((c)? a : b)
#define GCD(a, b) __gcd(a, b) /* 最大公約数 */
#define LCM(a, b) (i64)(a / (f64)__gcd(a, b) * b) /* 最小公倍数 */

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
    Main();
    return 0;
}

void Main() {
    i32 N, K;
    cin >> N >> K;
    Vec<i32> M(N + 1, 0);
    for (i32 i = 0; i < N; i++) {
        i32 A;
        cin >> A;
        M[A]++;
    }
    sort(ALL(M));
    i32 total = 0;
    for (i32 i = 0; i <= N; i++) {
        if (M[i] != 0) total++;
    }
    i32 index = 0;
    while (M[index] != 0) index++;
    i64 sum = 0;
    while (total > K) {
        sum += M[index];
        total -= M[index];
        index++;
    }
    cout << sum << endl;

}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const long long INF = 1e18;
# define len(x) ((int)(x).size())
# define rep(i, n) for(int i=0, i##_len=(n); i<i##_len; ++i)
# define reps(i, n) for(int i=1, i##_len=(n); i<=i##_len; ++i)
# define rrep(i, n) for(int i=((int)(n)-1); i>=0; --i)
# define rreps(i, n) for(int i=((int)(n)); i>0; --i)
# define foreps(i, m, n) for(int i = m;i < n;i++)
# define ALL(x) (x).begin(), (x).end()
# define rall(x) (x).rbegin(), (x).rend()
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

int main() {
   ll N, K; cin >> N >> K;
   vector<ll> A(N);
   map<ll, ll> mp;
   rep(i, N) {
       cin >> A[i]; mp[A[i]]++;
   }

   vector<ll> B(N);
   rep(i, N) B[i] = mp[A[i]];
   sort(ALL(B));

   ll ans = 0;
   rep(i, len(mp) - K) ans += B[i];
   cout << ans << endl;
}


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

int main() {

  int N,K;
  cin >> N >> K;
  vector<int> A(N);

  //種類を数えるsetを作る=>それぞれの数を数える=>ソートする=>低い順番に減らしていく

  for (int i = 0; i < N; i++) {
      cin >> A.at(i);
  }

  set<int> S;
  for (int i = 0; i < N; i++) {
      S.insert(A.at(i));
  }

  vector<int> num(S.size());

  auto itr = S.begin();
  //numにそれぞれの数字の個数を格納
  for (int j = 0; j < S.size(); j++) {
    num.at(j) = 0;
    for (int i = 0; i < N; i++) {
      if(A.at(i) == *itr)
        num.at(j) += 1;
    }
    ++itr;
  }

  sort(num.rbegin(),num.rend());
  int count = 0;

  for (int i = K; i < S.size(); i++) {
    count += num.at(i);
  }

  cout << count << endl;

}


#include<stdio.h>
int R=1,C=1,H[2000010],N[2000010];
//評価関数（いまはMIN）
int hyouka(int a,int b){
  if(C<b)return 1;
  if(C<a||b==0)return 0;
  return N[H[a]]>N[H[b]]?1:0;
}
//挿入関数
void hin(int a){
  int i=C++;
  for(N[H[0]=R]=a;hyouka(0,i/2);i/=2)H[i]=H[i/2];
  H[i]=R++;
}
//取り出す関数
int hout(){
  int rt=H[1],i,j=2,k=H[--C];
  for(i=1;hyouka(i,C);i=j)H[i]=H[j=i*2+1-hyouka(i*2,i*2+1)];
  H[j/2]=k;
  return rt;
}
int main(){
  int n,m,i,s=0,a,b[200010]={};
  scanf("%d %d",&n,&m);
  //m=n-m;
  for(i=0;i<n;i++){
    scanf("%d",&a);
    b[a]++;
  }
  for(i=0;i<200010;i++){
    if(b[i])hin(b[i]);
  }
  for(i=0;i<m&&C-1;i++)s+=N[hout()];
  printf("%d\n",n-s);
  return 0;
}


#include <stdio.h>
#include <stdlib.h>
int count(int *a,int N);
int med3(int x, int y,int z);
void quicksort(int a[], int left, int right);
int main()
{
	int N,K,*a,i,j,var,sum=0;
	scanf("%d %d",&N,&K);
	a=(int *)malloc(sizeof(int)*N);
	if(a==NULL) {
		fprintf(stderr,"Cannot allocation\n");
		return 1;
	}
	for(i=0;i<N;i++) a[i]=0;
	for(i=0;i<N;i++) {
		scanf("%d",&j);
		a[j-1]++;
	}
	if((var=count(a,N))<=K) {
		printf("0\n");
		return 0;
	} else {
		quicksort(a,0,N-1);
 		for(i=N-1,j=0;j<K;i--,j++) {
			sum+=a[i];
		}
		printf("%d\n",N-sum);
	}
	free(a);
	return 0;
}
int count(int *a,int N)
{
	int i,j=0;
	for(i=0;i<N;i++) {
		if(a[i]!=0) j++;
	}
	return j;
}

int med3(int x, int y,int z) {
    if (x < y) {
        if (y < z) return y; else if (z < x) return x; else return z;
    } else {
        if (z < y) return y; else if (x < z) return x; else return z;
    }
}

void quicksort(int a[], int left, int right) {
    if (left<right) {
        int i=left,j=right;
        int tmp,pivot=med3(a[i], a[i + (j - i) / 2], a[j]);
        while(1) {
            while (a[i]<pivot) i++;
            while (pivot<a[j]) j--;
            if (i>=j) break;
            tmp=a[i];a[i]=a[j];a[j]=tmp;
            i++;j--;
        }
        quicksort(a, left, i - 1);
        quicksort(a, j + 1, right);
    }
}


//set many funcs template
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#define inf 1072114514
#define llinf 4154118101919364364
#define mod 1000000007
#define pi 3.1415926535897932384

int max(int a,int b){if(a>b){return a;}return b;}
int min(int a,int b){if(a<b){return a;}return b;}
int zt(int a,int b){return max(a,b)-min(a,b);}
int round(int a,int b){if((a%b)*2 >= b){return (a/b)+1;}return a/b;}
int ceil(int a,int b){if(a%b==0){return a/b;}return (a/b)+1;}
int gcd(int a,int b){int c;while(b!=0){c=a%b;a=b;b=c;}return a;}
int lcm(int a,int b){int c=gcd(a,b);a/=c;return a*b;}
int nCr(int a,int b){int i,r=1;for(i=1;i<=b;i++){r*=(a+1-i);r/=i;}return r;}
int fact(int a){int i,r=1;for(i=1;i<=a;i++){r*=i;}return r;}
int pow(int a,int b){int i,r=1;for(i=1;i<=b;i++){r*=a;}return r;}
long long llmax(long long a,long long b){if(a>b){return a;}return b;}
long long llmin(long long a,long long b){if(a<b){return a;}return b;}
long long llzt(long long a,long long b){return llmax(a,b)-llmin(a,b);}
long long llround(long long a,long long b){if((a%b)*2 >= b){return (a/b)+1;}return a/b;}
long long llceil(long long a,long long b){if(a%b==0){return a/b;}return (a/b)+1;}
long long llgcd(long long a,long long b){long long c;while(b!=0){c=a%b;a=b;b=c;}return a;}
long long lllcm(long long a,long long b){long long c=llgcd(a,b);a/=c;return a*b;}
long long llnCr(long long a,long long b){long long i,r=1;for(i=1;i<=b;i++){r*=(a+1-i);r/=i;}return r;}
long long llfact(long long a){long long i,r=1;for(i=1;i<=a;i++){r*=i;}return r;}
long long llpow(long long a,long long b){long long i,r=1;for(i=1;i<=b;i++){r*=a;}return r;}
double dbmax(double a,double b){if(a>b){return a;}return b;}
double dbmin(double a,double b){if(a<b){return a;}return b;}
double dbzt(double a,double b){return dbmax(a,b)-dbmin(a,b);}
int sortfncsj(const void *a,const void *b){if(*(int *)a>*(int *)b){return 1;}if(*(int *)a==*(int *)b){return 0;}return -1;}
int sortfnckj(const void *a,const void *b){if(*(int *)a<*(int *)b){return 1;}if(*(int *)a==*(int *)b){return 0;}return -1;}
int llsortfncsj(const void *a,const void *b){if(*(long long *)a>*(long long *)b){return 1;}if(*(long long *)a==*(long long *)b){return 0;}return -1;}
int llsortfnckj(const void *a,const void *b){if(*(long long *)a<*(long long *)b){return 1;}if(*(long long *)a==*(long long *)b){return 0;}return -1;}
int dbsortfncsj(const void *a,const void *b){if(*(double *)a>*(double *)b){return 1;}if(*(double *)a==*(double *)b){return 0;}return -1;}
int dbsortfnckj(const void *a,const void *b){if(*(double *)a<*(double *)b){return 1;}if(*(double *)a==*(double *)b){return 0;}return -1;}

int main(void){
    int i,j,n,k,a,b[262144]={0},p,x[262144],r=0;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++){scanf("%d",&a);
        //if(b[a]==0){kind++;}
        b[a]++;
    }
    p=0;
    for(i=1;i<=n;i++){
        if(b[i]!=0){x[p]=b[i];p++;}
    }
    qsort(x,p,sizeof(int),sortfncsj);
    for(i=0;i<(p-k);i++){r+=x[i];}
    printf("%d\n",r);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
int compare_int(const void *a, const void *b){
    return *(int*)a - *(int*)b;
}
int main(){
    int n,m,k,a[10]={0},kind=0,cnt=0;
    scanf("%d%d",&n,&k);
    for(int i=0; i<n; i++){
        scanf("%d",&m);
        if(!a[m]){ kind++; }
        a[m]++;
    }
    if( kind <= k ){ printf("0\n"); return 0; }

    qsort( a, 10, sizeof(int), compare_int );
    for(int i=0; i<200000; i++){
        if( a[i] ){ cnt+=a[i]; kind--; }
        if( kind <= k ){ break; }
    }
    printf("%d\n",cnt);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<math.h>

void swap(int* x, int* y) {
	int tmp;

	tmp = *x;
	*x = *y;
	*y = tmp;
}

void sort(int array[], int n) {
	int i, j;
	for (i = 0; i < n - 1; i++) {
		for (j = n - 1; j >= i + 1; j--) {
			if (array[j] < array[j - 1]) {
				swap(&array[j], &array[j - 1]);
			}
		}
	}
}

int main(){

	long long int n, k, i, a[200000], x = 0, b, sum;

    scanf("%lld %lld", &n, &k);

    for (i = 0; i < n; i++) {
        scanf("%lld", &b);
		a[b]++;
	}

	sort(a, n);

	for (i = k; i < n; i++) {
		sum += a[b];
	}
	printf("%lld", sum);
}


#include <stdio.h>
#include <stdlib.h>

int input(int*, int*,int );
void sort(int *,int );
void reset(int*, int*, int);

int main()
{
	int sum = 0;
	int n, k;
	int *data;
	int *m;

	scanf("%d %d", &n, &k);

	data = (int*)malloc(n * sizeof(int));
	m = (int*)malloc(n * sizeof(int));

	reset(data, m, n);
	n = input(data, m, n);

	for (int i = k; i < n; i++)
		sum += m[i];

	printf("%d\n", sum);

	free(data);
	free(m);

	return 0;
}

void reset(int* data, int* m, int n)
{
	for (int i = 0; i < n; i++)
		data[i] = m[i] = 0;
}

int input(int *data, int *m,int n)
{
	int a;

	for (int i = 0; i < n; i++) {
		scanf("%d", &a);
		data[a - 1]++;
	}

	a = 0;
	for (int i = 0; i < n; i++) {
		if (data[i] != 0) {
			m[a] = data[i];
			a++;
		}
	}

	sort(m, n);

	return a;
}

void sort(int* m, int n)
{
	int i, j;
	int temp;

	for (i = 0; i < n - 1; i++) {
		for (j = i + 1; j < n; j++) {
			if (m[i] < m[j]) {
				temp = m[i];
				m[i] = m[j];
				m[j] = temp;
			}
		}
	}
}


function Main(input) {
	var N = parseInt(input.split("\n")[0].split(" ")[0]);
  var K = parseInt(input.split("\n")[0].split(" ")[1]);
  var list = input.split("\n")[1].split(" ");
  var hindo = {};
  var youso = [];
  for(var i = 0; i < list.length; i++){
    if(hindo[list[i]] == null){
       hindo[list[i]] = 1;
      youso.push(list[i]);
       }else{
        hindo[list[i]]++;
       }
  }
  youso.sort(function(a,b){
  	return hindo[a] - hindo[b];
  });
  if(youso.length < K){
     console.log("0");
    return;
     }
  var count = 0;
  var output = 0;
  while(count != youso.length - K){
        output += hindo[youso[count]];
    	count++;
  }
  console.log(output);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


"use strict";

const main = arg => {
    arg = arg.trim().split("\n");
    const N = parseInt(arg[0].split(" ")[0]);
    const K = parseInt(arg[0].split(" ")[1]);

    const A = arg[1].split(" ").map(n=>parseInt(n));

    const ball = [...Array(N)].fill(0);

    for(let i=0; i<N; i++) {
        ball[A[i]-1]++;
    }

    ball.sort((a,b)=>b-a);

    const temp = ball.filter(n=>n!==0);

    // console.log(ball)

    if(temp.length <= K) {
        console.log(0);
    } else {
        console.log(temp.slice(K).reduce((m,n)=>m+n));
    }
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


inp = require('fs').readFileSync('/dev/stdin', 'utf8').split('\n')
l = inp.shift().split(' ')
N = l[0]
K = l[1]
A = inp.shift().split(' ')
o = {}
a = []
for (i=0; i<N; i++) {
    a[A[i]] = (a[A[i]] || 0) + 1
    o[A[i]] = 1
}
keys = Object.keys(o)
c = keys.length - K
if (c > 0) {
    a.sort((b,c) => b - c)
    cnt = 0
    for (k of a) {
        cnt += k
        c--
        if (c===0) {
            break;
        }
    }
    console.log(cnt)
} else {
    console.log(0)
}


/*
-------関数一覧--------
arr1dto2d(Array) 一次元配列を二次元配列にします
pf(N)素因数分解した結果をオブジェクトで返します
gcd(a,b)最大公約数を返します
lcm(a,b)最小公倍数を返します
num(a,b)a-bを返します。ソート用です
isPrime(n)素数かどうか真偽値で返します
isNumber(n)数かどうか真偽値で返します
arrsum(arr)配列の合計値を返します
nibu(arr,n)n以下で最も大きい数の添字を返します(nを含みます)
br(input)入力を改行で区切ります
*/
const debugMode = false;
const inf = Number.MAX_SAFE_INTEGER;
const mod = 1000000007;
function Main(input) {
    input = input.split("\n");
    var mem = input[0].split(" ").map(Number);
    var arr = input[1].split(" ").map(String);
    var n = {}
    arr.forEach(function (val) {
        if (n[val]) n[val]++;
        else n[val] = 1;
    });
    var p = [];
    Object.keys(n).forEach(function(val){
        p.push(n[val]);
    })
    p = p.sort(function(a,b){retun a-b;});
    if (p.length <= mem[1]) {
        console.log(0)
    } else {
        var sum = 0;
        for (var i = 0; i < p.length - mem[1]; i++) {
            sum += p[i]
        }
        console.log(sum);
    }
} Main(require("fs").readFileSync("/dev/stdin", "utf8").trim());
function zisyozyunn(a) {
    var arr = [];
    for (var i = 0; i < input[0]; i++) {
        arr.push(i + 1);
    }
    var sum = 0;
    for (var i = 0; i < a.length; i++) {
        var f = arr.findIndex(val => val == a[i]);
        sum += factorialize(a.length - 1 - i) * f;
        arr.splice(f, 1);
    }
    return sum;
}
function arrsum(arr) {
    var sum = 0;
    for (var i = 0, len = arr.length; i < len; ++i) {
        sum += arr[i] - 0;
    };
    return sum;
}
function debug(val) {
    if (debugMode == true) {
        console.log(val)
    }
}
function arrMaxPoint(arr) {
    var max = Number.MIN_SAFE_INTEGER;
    var point = -1;
    for (var i = 0; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
            point = i;
        }
    }
    return point;
}
function arrMinPoint(arr) {
    var min = Number.MAX_SAFE_INTEGER;
    var point = -1;
    for (var i = 0; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i];
            point = i;
        }
    }
    return point;
}
function arr1dto2d(arr) {
    for (var i = 0; i < arr.length; i++) {
        arr[i] = arr[i].split("");
    }
    return arr;
}
function isPrime(n) {
    if (false === Number.isInteger(n)) {
        return false;
    }
    if (n <= 1) {
        return false;
    }
    if (2 === n) {
        return true;
    }
    if (0 === n % 2) {
        return false;
    }
    var square_root = Math.floor(Math.sqrt(n));
    for (var i = 3; i <= square_root; i += 2) {
        if (0 === n % i) {
            return false;
        }
    }
    return true;
}
function isNumber(val) {
    const pat = /^([1-9]\d*|0)$/;
    return pat.test(val);
}
function factorialize(num) {
    if (num === 0) { return 1; }
    return num * factorialize(num - 1);
}
function rotate(array) {
    const ROW = array.length;
    const COL = array[0].length;
    const row = ROW - 1;
    var a = new Array(COL);
    for (var c = 0; c < COL; c++) {
        a[c] = new Array(ROW);
        for (var r = 0; r < ROW; r++) {
            a[c][r] = array[row - r][c];
        }
    }
    return a;
}
function part_in(base, push, st) {
    for (var i = st, p = 0; p < push.length; i++, p++) {
        base[i] = push[p];
    }
    return base;
}
function part_reverse(arr, s, g) {
    var push = arr.slice(s - 1, g);
    push.reverse();
    arr = part_in(arr, push, s - 1);
    return arr;
}
function zeroPadding(num, length) {
    return (num + '000000000000000000000000000000000').slice(0, length);
}
function arrsum(arr) {
    var sum = 0;
    for (var i = 0, len = arr.length; i < len; ++i) {
        sum += arr[i] - 0;
    };
    return sum;
}
function pf(n) {
    var result = {};

    if (n === 1) {
        return { "1": 1 }
    }

    var init = 2;

    while (n !== 1) {
        var i = init;
        while (i < Number.MAX_SAFE_INTEGER) {
            if (n % i === 0) {
                n /= i;
                if (!(result[i] > 0)) {
                    result[i] = 0;
                }
                result[i]++;
                break;
            }
            i++;
        }
        init = i;
    }
    return result;
}
function gcd(a, b) {
    if (b === 0) {
        return a
    }
    return gcd(b, a % b)
}
function lcm(a, b) {
    var g = (n, m) => m ? g(m, n % m) : n
    return a * b / g(a, b)
}
function num(a, b) {
    return a - b;
}
function nibu(a, searchValue) {
    var index = -1;

    //調べる左端を表す添字(index)
    var left = 0;

    //調べる右端を表す添字(index)
    var right = a.length - 1;

    //左端と右端にデータがある間は処理を繰り返す
    while (left <= right) {

        //左右の真ん中を表す添字(index)
        middle = Math.floor((left + right) / 2);

        //真ん中の値と探す値を比較する
        if (a[middle] == searchValue) {
            //一致した場合、変数に入れて処理終了
            index = middle;
            break;
        } else if (a[middle] < searchValue) {
            //探す値より小さい場合、左側にはもっと小さい値しかないので左端の値を真ん中の値の右に移動する
            left = middle + 1;
        } else {
            //探す値より大きい場合、右側にはもっと大きい値しかないので右端の値を真ん中の値の左に移動する
            right = middle - 1;
        }
    }
    if (index != -1) return index;
    else return left;
}
function br(input) {
    return input.split("\n");
}
function is_sortred(arr) {
    var flag = true;
    for (var i = 1; i < arr.length; i++) {
        if (arr[i - 1] > arr[i]) {
            flag = false;
            break;
        }
    }
    return flag;
}
function primeFactorization(n) {

    // 平方根を保存
    var s = Math.floor(Math.sqrt(n));

    var r = 0;

    var result = {};

    // 2から平方根までの素因数を求める
    for (var i = 2; i <= s; i++) {

        if ((n % i) == 0) {

            r = 0; // 指数カウンタクリア

            do {

                r++; // 指数カウンタプラス

                n = n / i;

            } while ((n % i) == 0);

            // 素因数iを指数とともに保存
            result[i] = r;

        }

    }

    // 残った素数を追加
    if (n > s) {
        result[n] = 1;
    }

    return result;

}


/*
-------関数一覧--------
arr1dto2d(Array) 一次元配列を二次元配列にします
pf(N)素因数分解した結果をオブジェクトで返します
gcd(a,b)最大公約数を返します
lcm(a,b)最小公倍数を返します
num(a,b)a-bを返します。ソート用です
isPrime(n)素数かどうか真偽値で返します
isNumber(n)数かどうか真偽値で返します
arrsum(arr)配列の合計値を返します
nibu(arr,n)n以下で最も大きい数の添字を返します(nを含みます)
br(input)入力を改行で区切ります
*/
const debugMode = false;
const inf = Number.MAX_SAFE_INTEGER;
const mod = 1000000007;
function Main(input) {
    input = input.split("\n");
    var mem = input[0].split(" ").map(Number);
    var arr = input[1].split(" ").map(String);
    var n = {}
    arr.forEach(function (val) {
        if (n[val]) n[val]++;
        else n[val] = 1;
    });
    var p = [];
    Object.keys(n).forEach(function(val){
        p.push(n[val]);
    })
    p = p.sort();
    if (p.length <= mem[1]) {
        console.log(0)
    } else {
        var sum = 0;
        for (var i = 0; i < p.length - mem[1]; i++) {
            sum += p[i]
        }
        console.log(sum);
    }
} Main(require("fs").readFileSync("/dev/stdin", "utf8").trim());
function zisyozyunn(a) {
    var arr = [];
    for (var i = 0; i < input[0]; i++) {
        arr.push(i + 1);
    }
    var sum = 0;
    for (var i = 0; i < a.length; i++) {
        var f = arr.findIndex(val => val == a[i]);
        sum += factorialize(a.length - 1 - i) * f;
        arr.splice(f, 1);
    }
    return sum;
}
function arrsum(arr) {
    var sum = 0;
    for (var i = 0, len = arr.length; i < len; ++i) {
        sum += arr[i] - 0;
    };
    return sum;
}
function debug(val) {
    if (debugMode == true) {
        console.log(val)
    }
}
function arrMaxPoint(arr) {
    var max = Number.MIN_SAFE_INTEGER;
    var point = -1;
    for (var i = 0; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
            point = i;
        }
    }
    return point;
}
function arrMinPoint(arr) {
    var min = Number.MAX_SAFE_INTEGER;
    var point = -1;
    for (var i = 0; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i];
            point = i;
        }
    }
    return point;
}
function arr1dto2d(arr) {
    for (var i = 0; i < arr.length; i++) {
        arr[i] = arr[i].split("");
    }
    return arr;
}
function isPrime(n) {
    if (false === Number.isInteger(n)) {
        return false;
    }
    if (n <= 1) {
        return false;
    }
    if (2 === n) {
        return true;
    }
    if (0 === n % 2) {
        return false;
    }
    var square_root = Math.floor(Math.sqrt(n));
    for (var i = 3; i <= square_root; i += 2) {
        if (0 === n % i) {
            return false;
        }
    }
    return true;
}
function isNumber(val) {
    const pat = /^([1-9]\d*|0)$/;
    return pat.test(val);
}
function factorialize(num) {
    if (num === 0) { return 1; }
    return num * factorialize(num - 1);
}
function rotate(array) {
    const ROW = array.length;
    const COL = array[0].length;
    const row = ROW - 1;
    var a = new Array(COL);
    for (var c = 0; c < COL; c++) {
        a[c] = new Array(ROW);
        for (var r = 0; r < ROW; r++) {
            a[c][r] = array[row - r][c];
        }
    }
    return a;
}
function part_in(base, push, st) {
    for (var i = st, p = 0; p < push.length; i++, p++) {
        base[i] = push[p];
    }
    return base;
}
function part_reverse(arr, s, g) {
    var push = arr.slice(s - 1, g);
    push.reverse();
    arr = part_in(arr, push, s - 1);
    return arr;
}
function zeroPadding(num, length) {
    return (num + '000000000000000000000000000000000').slice(0, length);
}
function arrsum(arr) {
    var sum = 0;
    for (var i = 0, len = arr.length; i < len; ++i) {
        sum += arr[i] - 0;
    };
    return sum;
}
function pf(n) {
    var result = {};

    if (n === 1) {
        return { "1": 1 }
    }

    var init = 2;

    while (n !== 1) {
        var i = init;
        while (i < Number.MAX_SAFE_INTEGER) {
            if (n % i === 0) {
                n /= i;
                if (!(result[i] > 0)) {
                    result[i] = 0;
                }
                result[i]++;
                break;
            }
            i++;
        }
        init = i;
    }
    return result;
}
function gcd(a, b) {
    if (b === 0) {
        return a
    }
    return gcd(b, a % b)
}
function lcm(a, b) {
    var g = (n, m) => m ? g(m, n % m) : n
    return a * b / g(a, b)
}
function num(a, b) {
    return a - b;
}
function nibu(a, searchValue) {
    var index = -1;

    //調べる左端を表す添字(index)
    var left = 0;

    //調べる右端を表す添字(index)
    var right = a.length - 1;

    //左端と右端にデータがある間は処理を繰り返す
    while (left <= right) {

        //左右の真ん中を表す添字(index)
        middle = Math.floor((left + right) / 2);

        //真ん中の値と探す値を比較する
        if (a[middle] == searchValue) {
            //一致した場合、変数に入れて処理終了
            index = middle;
            break;
        } else if (a[middle] < searchValue) {
            //探す値より小さい場合、左側にはもっと小さい値しかないので左端の値を真ん中の値の右に移動する
            left = middle + 1;
        } else {
            //探す値より大きい場合、右側にはもっと大きい値しかないので右端の値を真ん中の値の左に移動する
            right = middle - 1;
        }
    }
    if (index != -1) return index;
    else return left;
}
function br(input) {
    return input.split("\n");
}
function is_sortred(arr) {
    var flag = true;
    for (var i = 1; i < arr.length; i++) {
        if (arr[i - 1] > arr[i]) {
            flag = false;
            break;
        }
    }
    return flag;
}
function primeFactorization(n) {

    // 平方根を保存
    var s = Math.floor(Math.sqrt(n));

    var r = 0;

    var result = {};

    // 2から平方根までの素因数を求める
    for (var i = 2; i <= s; i++) {

        if ((n % i) == 0) {

            r = 0; // 指数カウンタクリア

            do {

                r++; // 指数カウンタプラス

                n = n / i;

            } while ((n % i) == 0);

            // 素因数iを指数とともに保存
            result[i] = r;

        }

    }

    // 残った素数を追加
    if (n > s) {
        result[n] = 1;
    }

    return result;

}


"use strict";

const main = arg => {
    arg = arg.trim().split("\n");
    const N = parseInt(arg[0].split(" ")[0]);
    const K = parseInt(arg[0].split(" ")[1]);

    const A = arg[1].split(" ").map(n=>parseInt(n));

    const ball = [...Array(N)].fill(0);

    for(let i=0; i<N; i++) {
        ball[A[i]-1]++;
    }

    ball.sort((a,b)=>b-a);

    const temp = ball.filter(n=>n!==0);

    if(temp.length <= K) {
        console.log(0);
    } else {
        console.log(temp.slice(-(K-1)).reduce((m,n)=>m+n));
    }
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


package main

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

//Util
func nextStr() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a > b {
		return b
	} else {
		return a
	}
}

func absInt(a int) int {
	if a >= 0 {
		return a
	} else {
		return -a
	}
}

func absFloat64(a float64) float64 {
	if a >= 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a > b {
		return b
	} else {
		return a
	}
}

func str2Int(s string) int {
	n, _ := strconv.Atoi(s)
	return n
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func powInt(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func isPrime(x int) bool {
	if x == 1 {
		return false
	}
	if x == 2 {
		return true
	}
	if x%2 == 0 {
		return false
	}

	b := true
	rootx := int(math.Sqrt(float64(x)))
	i := 3
	for i <= rootx {
		if x%i == 0 {
			b = false
			break
		}
		i += 2
	}
	return b
}

func PrimeFactors(n int) (pfs []int) {
	// Get the number of 2s that divide n
	for n%2 == 0 {
		pfs = append(pfs, 2)
		n = n / 2
	}

	// n must be odd at this point. so we can skip one element
	// (note i = i + 2)
	for i := 3; i*i <= n; i = i + 2 {
		// while i divides n, append i and divide n
		for n%i == 0 {
			pfs = append(pfs, i)
			n = n / i
		}
	}

	// This condition is to handle the case when n is a prime number
	// greater than 2
	if n > 2 {
		pfs = append(pfs, n)
	}

	return
}

func sumInts(x []int) int {

	total := 0
	for _, v := range x {
		total += v
	}

	return total
}

//Main
const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		return sc
	}()
)

var N, K int

func main() {
	sc.Split(bufio.ScanWords)

	N, K = nextInt(), nextInt()
	kind := 0
	m := make([]int, N)
	for i := 0; i < N; i++ {
		a := nextInt() - 1
		if m[a] == 0 {
			kind++
		}
		m[a]++
	}

	sort.Ints(m)
	ans := 0
	if K >= kind {
		fmt.Println(ans)
		return
	}
	for i := N - kind; i < N; i++ {
		kind--
		ans += m[i]
		if K >= kind {
			fmt.Println(ans)
			return
		}

	}
}


package main

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

var sc = bufio.NewScanner(os.Stdin)

func next() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}

func nextInts(n int) []int {
	slice := make([]int, n)
	for i := 0; i < n; i++ {
		slice[i] = nextInt()
	}
	return slice
}

type Count []int

func (c Count) Len() int {
	return len(c)
}

func (c Count) Less(i, j int) bool {
	return c[i] < c[j]
}

func (c Count) Swap(i, j int) {
	c[i], c[j] = c[j], c[i]
}

func main() {
	sc.Split(bufio.ScanWords)
	n, k := nextInt(), nextInt()
	// balls[i] = i+1が書かれたボールの個数
	balls := make(Count, n)
	kind := 0
	for i := 0; i < n; i++ {
		a := nextInt()
		if balls[a-1] == 0 {
			kind++
		}
		balls[a-1]++
	}
	sort.Sort(balls)

	ans := 0
	for i := 0; kind > k; i++ {
		if balls[i] > 0 {
			ans += balls[i]
			kind--
		}
	}
	fmt.Println(ans)
}


package main

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

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func main() {
	sc.Split(bufio.ScanWords)
	N, K := getInt(), getInt()
	a := make(map[int]int)
	for i := 0; i < N; i++ {
		x := getInt()
		a[x]++
	}
	b := make([]int, len(a))
	idx := 0
	for _, v := range a {
		b[idx] = v
		idx++
	}
	sort.Ints(b)
	// out(b)
	sum := 0
	for i := len(b) - 1; i >= 0; i-- {
		// out(i, sum, K)
		if sum >= K {
			break
		}
		sum++
	}
	ans := 0
	for i := 0; i < len(b)-sum; i++ {
		ans += b[i]
	}
	out(ans)
}


package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	var n, k, tmp int
	scanner.Scan()
	fmt.Sscan(scanner.Text(), &n, &k)

	a := make(map[int]int, n)
	scanner.Scan()
	for _, v := range strings.Split(scanner.Text(), " ") {
		tmp, _ = strconv.Atoi(v)
		a[tmp]++
	}

	values := make([]int, k)
	for _, v := range a {
		for i := 0; i < k; i++ {
			if v > values[i] {
				values[i] = v
				break
			}
		}
	}

	for i := 0; i < k; i++ {
		n -= values[i]
	}
	fmt.Println(n)
}


package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	var n, k, ans, tmp int
	scanner.Scan()
	fmt.Sscan(scanner.Text(), &n, &k)

	a := make(map[int]int, n)
	scanner.Scan()
	for _, v := range strings.Split(scanner.Text(), " ") {
		tmp, _ = strconv.Atoi(v)
		a[tmp]++
	}

	values := make([]int, 0)
	for _, v := range a {
		values = append(values, v)
	}
	sort.Ints(values)

	for i := 0; i < len(values)-k; i++ {
		ans += values[i]
	}
	fmt.Println(ans)
}


package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	var n, k, ans int
	scanner.Scan()
	fmt.Sscan(scanner.Text(), &n, &k)

	a := make(map[string]int, n)
	scanner.Scan()
	for _, v := range strings.Split(scanner.Text(), " ") {
		a[v]++
	}

	values := make([]int, 0)
	for _, v := range a {
		values = append(values, v)
	}
	sort.Ints(values)

	for i := 0; i < len(values)-k; i++ {
		ans += values[i]
	}
	fmt.Println(ans)
}


n, k = gets.split.map(&:to_i)
as = gets.split.map(&:to_i)

counts = as.each.with_object(Array.new(n + 1, 0)) do |a, h|
  h[a] += 1
end.sort!

ans = 0
until counts.size <= k
  ans += counts.shift
end

puts ans


n, k = gets.split.map(&:to_i)
as = gets.split.map(&:to_i)

counts = as.each.with_object(Array.new(n + 1, 0)) do |a, arr|
  arr[a] += 1
end.sort!

ans = 0
until counts.size == k
  ans += counts.shift
end

puts ans


n, k = gets.split.map(&:to_i)
as = gets.split.map(&:to_i)

counts = as.each.with_object(Array.new(n + 1, 0)) do |a, h|
  h[a] += 1
end.sort!

ans = 0
while counts.size > k
  ans += counts.shift
end

puts ans


n, k = gets.split.map(&:to_i)
as = gets.split.map(&:to_i)

counts = as.each.with_object(Hash.new(0)) do |a, h|
  h[a] += 1
end.values.sort

ans = 0
until counts.size == k
  ans += counts.shift
end

puts ans


n, k = gets.split.map(&:to_i)
as = gets.split.map(&:to_i)

counts = as.each.with_object(Array.new(n + 1, 0)) do |a, arr|
  arr[a] += 1
end.select { |n| n > 0 }.sort!

ans = 0
until counts.size == k
  ans += counts.shift
end

puts ans


kinds = Hash.new(0)

n, k = gets.split.map(&:to_i)
gets.split.each {|a| kinds[a.to_i] += 1}

tmp = kinds.values.sort.reverse[0, k]

puts tmp.empty? ? 0 : tmp.inject(&:+)


#![allow(non_snake_case)]
#![allow(unused_variables)]

fn main() {
    let (N, K): (usize, usize) = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    };
    let A: Vec<i64> = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|x| x.parse().unwrap())
            .collect()
    };

    let mut c = vec![0; N + 1];
    for a in A {
        c[a as usize] += 1;
    }
    let mut b: Vec<_> = c.iter().filter(|&&z| z > 0).map(|&z| z).collect();
    b.sort();
    let m = b.len();
    let ans = if m <= K {
        0
    } else {
        let mut res = 0;
        for i in 0..(m - K) {
            res += b[i];
        }
        res
    };

    println!("{}", ans);
}


#![allow(non_snake_case)]
#![allow(unused_variables)]

fn main() {
    let (N, K): (usize, usize) = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    };
    let A: Vec<i64> = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|x| x.parse().unwrap())
            .collect()
    };

    let mut c = vec![0; N + 1];
    for a in A {
        c[a as usize] += 1;
    }
    let mut b: Vec<_> = c.iter().filter(|&&z| z > 0).collect();
    b.sort();
    let m = b.len();
    let ans: i64 = if m <= K {
        0
    } else {
        let mut res: i64 = 0;
        for i in 0..(m - K) {
            res = res + b[i];
        }
        res
    };

    println!("{}", ans);
}