#pragma GCC optimize( O3 , Ofast , unroll-loops , omit-frame-pointer , inline ) //Optimization flags   #pragma GCC option( arch=native , tune=native , no-zero-upper ) //Enable AVX   // #pragma GCC target( avx2 ) //Enable AVX      #include <bits/stdc++.h>      #define int long long      using namespace std;      #ifdef LOCAL    #include  /media/brayand/BrayanD/debugger.h    #else   #define db(...) false   #define dbl(...) false   #define dbg(...) false   #define dbm(...) false   #define dbs(...) false   #define dbas(...) false   #endif      const int oo = 1e18;      const int MAXN = 4e4+100;      int ST[MAXN*4];   int lazy[MAXN*4];      int dp[MAXN][120];      void prop(int nodo)   {    if(lazy[nodo] != 0)    {     ST[nodo] += lazy[nodo];     if(nodo*2 < MAXN*4)     {      lazy[nodo*2] += lazy[nodo];     }     if(nodo*2+1 < MAXN*4)     {      lazy[nodo*2+1] += lazy[nodo];     }     lazy[nodo] = 0;    }   }      void build(int nodo, int l, int r, int k)   {    lazy[nodo] = 0;    if(l == r)    {     ST[nodo] = dp[l][k];     return;    }    int mid = (l+r)/2;    build(nodo*2,l,mid,k);    build(nodo*2+1,mid+1,r,k);    ST[nodo] = max(ST[nodo*2], ST[nodo*2+1]);   }      void update(int nodo, int l, int r, int a, int b, int x)   {    prop(nodo);    if(r < a || l > b)return;    if(a <= l && r <= b)    {     lazy[nodo] += x;     prop(nodo);     return;    }    int mid = (l+r)/2;    update(nodo*2,l,mid,a,b,x);    update(nodo*2+1,mid+1,r,a,b,x);    ST[nodo] = max(ST[nodo*2], ST[nodo*2+1]);   }      int query(int nodo, int l, int r, int a, int b)   {    prop(nodo);    if(r < a || l > b)return -oo;    if(a <= l && r <= b)    {     return ST[nodo];    }    int mid = (l+r)/2;    return max(query(nodo*2,l,mid,a,b), query(nodo*2+1,mid+1,r,a,b));   }      int A[MAXN];      vector<int> arr[MAXN];      int T[MAXN];      vector<int> ins[MAXN];   vector<int> del[MAXN];      int32_t main()   {       ios_base::sync_with_stdio(0);       cin.tie(0);          int N, K;       cin >> N >> K;       K--;          for(int i = 1 ; i <= N ; i++)       {        cin >> A[i];        arr[A[i]].push_back(i);       }          if(N == 1)       {        cout << 0 <<   n ;        return 0;       }          vector<pair<int,int>> vect;          int sum = 0;          for(int i = 1 ; i <= N ; i++)       {        for(int j = 1 ; j < arr[i].size() ; j++)        {         vect.push_back({arr[i][j-1],arr[i][j]-1});        }        if(arr[i].size())        {         sum += arr[i].back()-arr[i][0];        }       }          for(auto x : vect)       {        int d = x.second-x.first+1;        T[x.first] += d;        T[x.second+1] -= d;       }          for(int i = 1 ; i <= N ; i++)       {        T[i] += T[i-1];       }          for(int i = 0 ; i < MAXN ; i++)       {        for(int j = 0 ; j < 120 ; j++)        {         dp[i][j] = -oo;        }       }          for(int i = 1 ; i < N ; i++)       {        dp[i][0] = 0;        dp[i][1] = T[i];       }          for(int i = 0 ; i < vect.size() ; i++)       {        ins[vect[i].first].push_back(i);        del[vect[i].second+1].push_back(i);       }          for(int j = 2 ; j <= K ; j++)       {         build(1,1,N-1,j-1);           for(int i = 1 ; i < N ; i++)        {         for(auto x : ins[i])         {          int v = vect[x].second-vect[x].first+1;          update(1,1,N-1,vect[x].first, vect[x].second, -v);         }         for(auto x : del[i])         {          int v = vect[x].second-vect[x].first+1;          update(1,1,N-1,vect[x].first, vect[x].second, v);         }         if(i >= j)dp[i][j] = query(1,1,N-1,1,i-1) + T[i];        }       }          int res = 0;          for(int i = 1 ; i < N ; i++)       {        res = max(res, dp[i][K]);       }          cout << sum - res <<   n ;          return 0;   }