#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;
}
### Prompt

In CPP, your task is to solve the following problem:

You are given an array a of n integers. Define the cost of some array t as follows:

$$$cost(t) = ∑_{x ∈ set(t) } last(x) - first(x),$$$ 

where set(t) is the set of all values in t without repetitions, first(x), and last(x) are the indices of the first and last occurrence of x in t, respectively. In other words, we compute the distance between the first and last occurrences for each distinct element and sum them up.

You need to split the array a into k consecutive segments such that each element of a belongs to exactly one segment and the sum of the cost of individual segments is minimum.

Input

The first line contains two integers n, k (1 ≤ n ≤ 35 000, 1 ≤ k ≤ min(n,100)).

The second line contains n integers a_1, a_2, …, a_n (1 ≤ a_i ≤ n).

Output

Output the minimum sum of the cost of individual segments.

Examples

Input


7 2
1 6 6 4 6 6 6


Output


3


Input


7 4
5 5 5 5 2 3 3


Output


1

Note

In the first example, we can divide the array into [1,6,6,4] and [6,6,6]. Cost of [1,6,6,4] will be (1-1) + (3 - 2) + (4-4) = 1 and cost of [6,6,6] will be 3-1 = 2. Total cost would be 1 + 2 = 3.

In the second example, divide the array into [5,5],[5],[5,2,3] and [3]. Total Cost would be 1 + 0 + 0 + 0 = 1.

### Response

```cpp
#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;
}
```