#include <iostream>
#include <vector>

using namespace std;

int main() {
    string inp;
    cin >> inp;

    int prefix [100000];
    int all_C [100000][2];
    for (int i = 0; i < 100000; i++) {prefix[i] = 0; all_C[i][0] = 0; all_C[i][1] = 0;}

    int sum_A = 0; // Da Majority
    int sum_B = 0;
    int sum_C = 0;

    for (int i = 0; i < inp.length(); i++) {
        if (string(1,inp[i]) == "(") sum_A++;
        else if (string(1,inp[i]) == ")") sum_B++;
        else {all_C[i][0] = i; all_C[i][1] = -1; sum_C++;}
        prefix[i] = sum_A-sum_B;
//        cout << prefix[i] << endl;
    }

    if (sum_B >= sum_A) {cout << -1 << endl; return 0;}

//    cout << endl << endl;
    int run_min = 999999;
    for (int i = inp.length()-1; i >= 0; i--) {
        run_min = min(run_min, prefix[i]);
        if (all_C[i][0] == 0) continue;
        all_C[i][1] = run_min;
//        cout << run_min << endl;
    }

    int target = sum_A-sum_B;
//    cout << target << endl;
    vector<int> ans;

    for (int i = 0; i < inp.length(); i++) {
        if (all_C[i][0] == 0) continue;
        int to_app = min(all_C[i][1],target-(sum_C-1));
        target -= to_app;
        sum_C--;
        ans.emplace_back(to_app);
    }
    if (target == 0) {for (int elem: ans) cout << elem << endl;}
    else cout << -1 << endl;
}

/*
 * Edges:
 * 1) all #
 */

/*
 * (((#)((#)
   000011112
   123334555
   123323443

   1234567890
   ((()))(())
      ^^^  ^^

 ()((#((#(#()
 011111111112
 112334556677
 101223445565
     2  4 5

Need 5 to go.

  x x x

 */


#include <iostream>
#include <vector>

using namespace std;

int main() {
    string inp;
    cin >> inp;

    int prefix [100000];
    int all_C [100000][2];
    for (int i = 0; i < 100000; i++) {prefix[i] = 0; all_C[i][0] = 0; all_C[i][1] = 0;}

    int sum_A = 0; // Da Majority
    int sum_B = 0;
    int sum_C = 0;

    for (int i = 0; i < inp.length(); i++) {
        if (string(1,inp[i]) == "(") sum_A++;
        else if (string(1,inp[i]) == ")") sum_B++;
        else {all_C[i][0] = i; all_C[i][1] = -1; sum_C++;}
        prefix[i] = sum_A-sum_B;
//        cout << prefix[i] << endl;
    }

    if (sum_B >= sum_A) {cout << -1 << endl; return 0;}

//    cout << endl << endl;

    vector<int> ans;
    int target = sum_A-sum_B;
    int run_min = 999999;
    for (int i = inp.length()-1; i >= 0; i--) {
        run_min = min(run_min, prefix[i]);
        if (all_C[i][0] == 0) continue;
        int to_app = min(run_min, target-(sum_C-1));
        ans.emplace_back(to_app);
        target -= to_app;
        sum_C--;
        if (to_app <= 0) {cout << -1 << endl; return 0;}
    }

//    cout << target << endl;

//    for (int i = 0; i < inp.length(); i++) {
//        if (all_C[i][0] == 0) continue;
//        int to_app = min(all_C[i][1]-(sum_A-sum_B-target),target-(sum_C-1));
//        target -= to_app;
//        sum_C--;
//        ans.emplace_back(to_app);
//        cout << "Now: " << to_app << endl;
//        if (to_app <= 0) {cout << -1 << endl; return 0;}
//    }
    if (target == 0) {for (int i = ans.size()-1; i >= 0; i--) cout << ans[i] << endl;}
    else cout << -1 << endl;
}

/*
 * Edges:
 * 1) all #
 * 2) Didn't even write correctly
 * 3) ) in front.
 */

/*
 * (((#)((#)
   000011112
   123334555
   123323443

   1234567890
   ((()))(())
      ^^^  ^^

 ()((#((#(#()
 011111111112
 112334556677
 101223445565
     2  4 5

Need 5 to go.

  x x x

 */
/*
 *
 *
((()()(()()(()(())))((()()(()()(()(())))

(((#(#((#()((#((####(((#(#((#()((#((####
1233445667789901111123445567788900122222

((((#((#())((((#((#())((((#((#())
123445667778901123344456788900111
000000000122222222223444444444456
123445667656789901121012344566765

 21 vs 6
 15 more

  4 6 9 11 14 16

  ()(()(()()))()

 */


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

int main() {
    ios_base::sync_with_stdio(0);
    string S;
    cin >> S;
    int n = S.size();
    int t = 100000;
    int cnt = 0;
    vector <int> ans;
    int last = -1;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            if(last != -1) {
                ans.push_back(1);
            }
            last = cnt;
            cnt--;
        }
        if(cnt < 0) {
            cout << -1 << endl;
            return 0;
        }
    }
    ans.push_back(last);
    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
    cout << endl;
}


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

int main() {
    ios_base::sync_with_stdio(0);
    string S;
    cin >> S;
    int n = S.size();
    int t = 100000;
    int cnt = 0;
    vector <int> ans;
    int last = -1;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            if(last != -1) {
                ans.push_back(0);
            }
            last = cnt;
        }
    }
    ans.push_back(last);
    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
    cout << endl;
}


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

int main() {
    ios_base::sync_with_stdio(0);
    string S;
    cin >> S;
    int n = S.size();
    int t = 100000;
    int cnt = 0;
    vector <int> ans;
    int last = -1;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            cnt--;
            ans.push_back(1);
        }
        if(cnt < 0) {
            cout << -1 << endl;
            return 0;
        }
    }
    for(int i = 0; i < ans.size() - 1; i++)
        cout << ans[i] << endl;
    cout << 1 + cnt << endl;
}


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

int main() {
    ios_base::sync_with_stdio(0);
    string S;
    cin >> S;
    int n = S.size();
    int t = 100000;
    int cnt = 0;
    vector <int> ans;
    int last = -1;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            if(last != -1) {
                ans.push_back(1);
            }
            cnt--;
            last = cnt;
        }
    }
    ans.push_back(last);
    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
    cout << endl;
}


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

int main() {
    ios_base::sync_with_stdio(0);
    string S;
    cin >> S;
    int n = S.size();
    int t = 100000;
    int cnt = 0;
    vector <int> ans;
    int last = -1;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            cnt--;
            ans.push_back(1);
        }
        if(cnt < 0) {
            cout << -1 << endl;
            return 0;
        }
    }
    ans[ans.size()-1] += cnt;
    cnt = 0;
    int idx = 0;
    for(int i = 0; i < n; i++) {
        if(S[i] == '(') {
            cnt++;
        } else if(S[i] == ')') {
            cnt--;
        } else {
            cnt -= ans[idx++];
        }
        if(cnt < 0) {
            cout << -1 << endl;
            return 0;
        }
    }
    if(cnt != 0) cout << -1 << endl;
    else
        for(int i = 0; i < ans.size(); i++)
            cout << ans[i] << endl;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int MaxN = 1e5;
using namespace std;
char s[MaxN + 5];
int main()
{
	while(~scanf("%s" , s + 1)){
		int len = strlen(s + 1);
		int cnt_1 = 0 , cnt_2 = 0 , cont = 0;
		bool ok = 1;
		for(int i = 1;i <= len;i++){
			if(s[i] == '(') cnt_1++;
			else if(s[i] == ')') cnt_2++;
			else if(s[i] == '#'){
				cont++;
				if(cont + cnt_2 > cnt_1) ok = 0;
			}
		}
		if(s[len] == '(' || cnt_1 < cnt_2 + cont || ok == 0) printf("-1\n");
		else {
			int t = cnt_1 - cnt_2 - cont + 1;
			for(int i = 1;i <= cont;i++){
				if(i != cont) printf("1\n");
				else printf("%d\n" , t);
			}
		}
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int MaxN = 1e5;
using namespace std;
char s[MaxN + 5];
int main()
{
	while(~scanf("%s" , s + 1)){
		int len = strlen(s + 1);
		int cnt_1 = 0 , cnt_2 = 0 , cont = 0;
		bool ok = 1;
		for(int i = 1;i <= len;i++){
			if(s[i] == '(') cnt_1++;
			else if(s[i] == ')') {
				cnt_2++;
				if(cont + cnt_2 > cnt_1) ok = 0;
			}
			else if(s[i] == '#'){
				cont++;
				if(cont + cnt_2 > cnt_1) ok = 0;
			}
		}
		if(s[len] == '(' || cnt_1 < cnt_2 + cont || ok == 0) printf("-1\n");
		else {
			int t = cnt_1 - cnt_2 - cont + 1;
			for(int i = 1;i <= cont;i++){
				if(i != cont) printf("1\n");
				else printf("%d\n" , t);
			}
		}
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int MaxN = 1e5;
using namespace std;
char s[MaxN + 5];
int main()
{
	while(~scanf("%s" , s + 1)){
		int len = strlen(s + 1);
		int cnt_1 = 0 , cnt_2 = 0 , cont = 0;
		bool ok = 1;
		for(int i = 1;i <= len;i++){
			if(s[i] == '(') cnt_1++;
			else if(s[i] == ')') cnt_2++;
			else if(s[i] == '#'){
				cont++;
				if(cont > cnt_1) ok = 0;
			}
		}
		if(cnt_1 < cnt_2 + cont || ok == 0) printf("-1\n");
		else {
			int t = cnt_1 - cnt_2 - cont + 1;
			for(int i = 1;i <= cont;i++){
				if(i != cont) printf("1\n");
				else printf("%d\n" , t);
			}
		}
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int MaxN = 1e5;
using namespace std;
char s[MaxN + 5];
int main()
{
	while(~scanf("%s" , s + 1)){
		int len = strlen(s + 1);
		int cnt_1 = 0 , cnt_2 = 0 , cont = 0;
		bool ok = 1;
		int ans = 0;
		for(int i = 1;i <= len;i++){
			if(s[i] == '(') cnt_1++;
			else if(s[i] == ')') {
				cnt_2++;
				if(cont + cnt_2 > cnt_1) ok = 0;
			}
			else if(s[i] == '#'){
				cont++;
				if(cont + cnt_2 > cnt_1) ok = 0;
				ans = 1 + cnt_1 - cnt_2;
			}
		}
		if(s[len] == '(' || cnt_1 < cnt_2 + cont || ok == 0) printf("-1\n");
		else {
			int t = cnt_1 - cnt_2 - cont + 1;
			if(ans < t) printf("-1\n");
			else {
				for(int i = 1;i <= cont;i++){
					if(i != cont) printf("1\n");
					else printf("%d\n" , t);
				}
			}
		}
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int MaxN = 1e5;
using namespace std;
char s[MaxN + 5];
int main()
{
	while(~scanf("%s" , s + 1)){
		int len = strlen(s + 1);
		int cnt_1 = 0 , cnt_2 = 0 , cont = 0;
		bool ok = 1;
		int ans = 0;
		for(int i = 1;i <= len;i++){
			if(s[i] == '(') cnt_1++;
			else if(s[i] == ')') {
				cnt_2++;
				if(cont + cnt_2 > cnt_1) ok = 0;
			}
			else if(s[i] == '#'){
				cont++;
				if(cont + cnt_2 > cnt_1) ok = 0;
				ans = cont + cnt_2 - cnt_1;
			}
		}
		if(s[len] == '(' || cnt_1 < cnt_2 + cont || ok == 0) printf("-1\n");
		else {
			int t = cnt_1 - cnt_2 - cont + 1;
			if(ans < t) printf("-1\n");
			else {
				for(int i = 1;i <= cont;i++){
					if(i != cont) printf("1\n");
					else printf("%d\n" , t);
				}
			}
		}
	}
}


#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cassert>
#include <stack>
#include <bitset>

#define INFLL 2000000000000000000
#define INF 2000000000
#define MOD 1000000007
#define PI acos(-1.0)
#define MAXLEN 29

typedef std::pair <int, int> pii;
typedef long long ll;
typedef std::vector <ll> vll;

using namespace std;

int n, k;
int arr[100000];
int opt[100001][21];
ll dp[100001][21];
int cur;
int cnt[100001];

void solve(int l, int r, int optl, int optr, int *cnt, int mapl, int mapr, ll cost) {
	if (l > r) return;
	int mid = (l + r) / 2;
	if (mid <= 1) {
		dp[mid][cur] = 0;
		return;
	}
	int oo = optr;
	dp[mid][cur]= dp[mid - 1][cur - 1];
	vector <int> added;
	vector <int> removed;
	if (mid < mapr) {
		for (int i = mapr; i >= mid; i--) {
			cnt[arr[i]]--;
			cost -= cnt[arr[i]];
			removed.push_back(arr[i]);
		}
	} else for (int i = mapr + 1; i < mid; i++) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	optr = min(mid - 1, optr);
	for (int i = mapl; i <= optr; i++) {
		cnt[arr[i]]--;
		cost -= cnt[arr[i]];
		removed.push_back(arr[i]);
	}
	for (int i = mapl - 1; i > optr - 1; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	for (int i = optr; i >= optl; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
		if (dp[mid][cur] > dp[i][cur - 1] + cost) {
			dp[mid][cur] = dp[i][cur - 1] + cost;
			opt[mid][cur] = i;
		}
	}
	solve(l, mid - 1, optl, opt[mid][cur], cnt, optl, mid - 1, cost);
	solve(mid + 1, r, opt[mid][cur], oo, cnt, optl, mid - 1, cost);
	for (int i = 0; i < added.size(); i++) cnt[added[i]]--;
	for (int i = 0; i < removed.size(); i++) cnt[removed[i]]++;
}

int main() {
	scanf("%d %d", &n, &k);
	for (int i = 0; i < n; i++) scanf("%d", arr + i);
	for (int i = 0; i < n; i++) {
		dp[i + 1][1] = dp[i][1] + cnt[arr[i]];
		cnt[arr[i]]++;
	}
	for (cur = 2; cur <= k; cur++) solve(1, n, 0, n - 1, cnt, 0, n - 1, dp[n][1]);
	cout << dp[n][k] << endl;
	return 0;
}


#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cassert>
#include <stack>
#include <bitset>

#define INFLL 2000000000000000000
#define INF 2000000000
#define MOD 1000000007
#define PI acos(-1.0)
#define MAXLEN 29

typedef std::pair <int, int> pii;
typedef long long ll;
typedef std::vector <ll> vll;

using namespace std;

int n, k;
int arr[100000];
ll dp[100001][21];
int cur;
int cnt[100001];
int mapl, mapr;
ll cost;

void solve(int l, int r, int optl, int optr) {
	if (l > r) return;
	int mid = (l + r) / 2;
	if (mid <= 1) {
		dp[mid][cur] = 0;
		solve(mid + 1, r, 1, optr);
		return;
	}
	int oo = optr;
	optr = min(mid - 1, optr);
	dp[mid][cur] = dp[mid][cur - 1];
	int xx = mid;
	if (mid <= mapr) {
		for (int i = mapr; i >= mid; i--) {
			cnt[arr[i]]--;
			cost -= cnt[arr[i]];
		}
	} else for (int i = mapr + 1; i < mid; i++) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
	}
	mapr = mid - 1;
	if (mapl <= optr) {
		for (int i = mapl; i <= optr; i++) {
			cnt[arr[i]]--;
			cost -= cnt[arr[i]];
		}
	} else {
		for (int i = mapl; i > optr + 1; i--) {
			cost += cnt[arr[i]];
			cnt[arr[i]]++;
		}
	}
	mapl = optr + 1;
	/*cout << mid << " " << optl << " " << optr << endl;
	cout << "---" << endl << mapl << " " << mapr << " " << cost << endl;
	for (int i = 0; i < 8; i++) if (cnt[i] != 0) {
		cout << i << " " << cnt[i] << endl;
	}
	cout << "---" << endl;*/
	for (int i = optr; i >= optl; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		mapl = i;
		if (dp[mid][cur] > dp[i][cur - 1] + cost) {
			dp[mid][cur] = dp[i][cur - 1] + cost;
			xx = i;
		}
	}
	//cout << dp[mid][cur] << " " << xx << endl << endl;
	solve(l, mid - 1, optl, xx);
	solve(mid + 1, r, xx, oo);
}

int main() {
	scanf("%d %d", &n, &k);
	for (int i = 0; i < n; i++) scanf("%d", arr + i);
	for (int i = 0; i < n; i++) {
		dp[i + 1][1] = dp[i][1] + cnt[arr[i]];
		cnt[arr[i]]++;
	}
	cost = dp[n][1];
	mapl = 0;
	mapr = n - 1;
	for (cur = 2; cur <= k; cur++) {
		solve(1, n, 0, n);
		for (int j = 0; j < 100001; j++) cnt[j] = 0;
		cost = 0;
		mapl = 1;
		mapr = 0;
	//	cout << endl;
	}
	cout << dp[n][k] << endl;
	for (int i = 0; i < 500; i++) {
		for (int j = 0; j < 20; j++) dp[i][j] = 0;
		cnt[i] = 0;
	}
	return 0;
}


#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cassert>
#include <stack>
#include <bitset>

#define INFLL 2000000000000000000
#define INF 2000000000
#define MOD 1000000007
#define PI acos(-1.0)
#define MAXLEN 29

typedef std::pair <int, int> pii;
typedef long long ll;
typedef std::vector <ll> vll;

using namespace std;

int n, k;
int arr[100000];
int opt[100001][21];
ll dp[100001][21];
int cur;
int cnt[100001];

void solve(int l, int r, int optl, int optr, int* cnt, int mapl, int mapr, ll cost) {
	if (l > r) return;
	int mid = (l + r) / 2;
	if (mid <= 1) {
		dp[mid][cur] = 0;
		return;
	}
	int oo = optr;
	dp[mid][cur]= INF;
	vector <int> added;
	vector <int> removed;
	if (mid < mapr) {
		for (int i = mapr; i > mid - 1; i--) {
			cnt[arr[i]]--;
			cost -= cnt[arr[i]];
			removed.push_back(arr[i]);
		}
	} else for (int i = mapr + 1; i < mid; i++) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	optr = min(mid - 1, optr);
	for (int i = mapl; i <= optr; i++) {
		cnt[arr[i]]--;
		cost -= cnt[arr[i]];
		removed.push_back(arr[i]);
	}
	for (int i = mapl - 1; i > optr - 1; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	for (int i = optr; i >= optl; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
		if (dp[mid][cur] > dp[i][cur - 1] + cost) {
			dp[mid][cur] = dp[i][cur - 1] + cost;
			opt[mid][cur] = i;
		}
	}
	solve(l, mid - 1, optl, opt[mid][cur], cnt, optl, mid - 1, cost);
	solve(mid + 1, r, opt[mid][cur], oo, cnt, optl, mid - 1, cost);
	for (int i = 0; i < added.size(); i++) cnt[added[i]]--;
	for (int i = 0; i < removed.size(); i++) cnt[removed[i]]++;
}

int main() {
	scanf("%d %d", &n, &k);
	for (int i = 0; i < n; i++) scanf("%d", arr + i);
	for (int i = 0; i < n; i++) {
		dp[i + 1][1] = dp[i][1] + cnt[arr[i]];
		cnt[arr[i]]++;
	}
	for (cur = 2; cur <= k; cur++) solve(1, n, 0, n, cnt, 0, n - 1, dp[n][1]);
	cout << dp[n][k] << endl;
	return 0;
}


#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cassert>
#include <stack>
#include <bitset>

#define INFLL 2000000000000000000
#define INF 2000000000
#define MOD 1000000007
#define PI acos(-1.0)
#define MAXLEN 29

typedef std::pair <int, int> pii;
typedef long long ll;
typedef std::vector <ll> vll;

using namespace std;

int n, k;
int arr[100000];
int opt[100001][21];
ll dp[100001][21];
int cur;
int cnt[100001];

void solve(int l, int r, int optl, int optr, int *cnt, int mapl, int mapr, ll cost) {
	if (l > r) return;
	int mid = (l + r) / 2;
	if (mid <= 1) {
		dp[mid][cur] = 0;
		return;
	}
	int oo = optr;
	dp[mid][cur] = dp[mid][cur - 1];
	vector <int> added;
	vector <int> removed;
	if (mid < mapr) {
		for (int i = mapr; i >= mid; i--) {
			cnt[arr[i]]--;
			cost -= cnt[arr[i]];
			removed.push_back(arr[i]);
		}
	} else for (int i = mapr + 1; i < mid; i++) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	optr = min(mid - 1, optr);
	for (int i = mapl; i <= optr; i++) {
		cnt[arr[i]]--;
		cost -= cnt[arr[i]];
		removed.push_back(arr[i]);
	}
	for (int i = mapl - 1; i > optr - 1; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
	}
	dp[mid][cur] = min(dp[mid][cur], cost + dp[optr + 1][cur - 1]);
	for (int i = optr; i >= optl; i--) {
		cost += cnt[arr[i]];
		cnt[arr[i]]++;
		added.push_back(arr[i]);
		if (dp[mid][cur] > dp[i][cur - 1] + cost) {
			dp[mid][cur] = dp[i][cur - 1] + cost;
			opt[mid][cur] = i;
		}
	}
	solve(l, mid - 1, optl, opt[mid][cur], cnt, optl, mid - 1, cost);
	solve(mid + 1, r, opt[mid][cur], oo, cnt, optl, mid - 1, cost);
	for (int i = 0; i < added.size(); i++) cnt[added[i]]--;
	for (int i = 0; i < removed.size(); i++) cnt[removed[i]]++;
}

int main() {
	scanf("%d %d", &n, &k);
	for (int i = 0; i < n; i++) scanf("%d", arr + i);
	for (int i = 0; i < n; i++) {
		dp[i + 1][1] = dp[i][1] + cnt[arr[i]];
		cnt[arr[i]]++;
	}
	for (cur = 2; cur <= k; cur++) solve(1, n, 0, n - 1, cnt, 0, n - 1, dp[n][1]);
	cout << dp[n][k] << endl;
	return 0;
}


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

typedef long long  LL;
struct node{int l,r,L,R;};
int n,k,a[100010],cnt[100010],L,R;
LL f[21][100010],s;
queue <node> Q;

void run(node x)
{
	int mid=(x.l+x.r)>>1,l=min(x.R,mid),pos;
	for (; L>l; s+=cnt[a[--L]]++);
	for (; R<mid; s+=cnt[a[++R]]++);
	for (; L<l; s-=--cnt[a[L++]]);
	for (; R>mid; s-=--cnt[a[R--]]);
	f[k][mid]=1LL<<60;
	for (; L>=x.L; s+=cnt[a[--L]]++)
		if (f[k+1][L-1]+s<f[k][mid])  f[k][mid]=f[k+1][L-1]+s,pos=L;
	if (x.l<mid)  Q.push((node){x.l,mid-1,x.L,pos});
	if (mid<x.r)  Q.push((node){mid+1,x.r,pos,x.R});
}

void work()
{
	scanf("%d %d",&n,&k),L=1;
	for (int i=1; i<=n; i++)  scanf("%d",&a[i]),f[k][i]=1LL<<60;
	while (k--)
		{
			Q.push((node){1,n,1,n});
			while (!Q.empty())  run(Q.front()),Q.pop();
		}
	printf("%I64d",f[0][n]);
}

int main()
{
	work();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define N 100010
int A[N],cnt[N],PL,PR;
long long sum;
void Move(int l,int r){
	while (PL>l){
		sum+=cnt[A[--PL]]++;
	}
	while (PR<r){
		sum+=cnt[A[++PR]]++;
	}
	while (PL<l){
		sum-=--cnt[A[PL++]];
	}
	while (PR>r){
		sum-=--cnt[A[PR--]];
	}
}
int dp[2][N],f;
void Solve(int l,int r,int pl,int pr){
	if (l>r){
		return;
	}
	int mid=(l+r)>>1,i,pos=l;
	for (i=pl;i<=pr && i<=mid;i++){
		Move(i,mid);
		if (dp[!f][i-1]+sum<dp[f][mid]){
			dp[f][mid]=dp[!f][i-1]+sum;
			pos=i;
		}
	}
	Solve(l,mid-1,pl,pos);
	Solve(mid+1,r,pos,pr);
}
int main(){
	PL=1,PR=0;
	int n,m,i;
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%d",&A[i]);
		Move(1,i);
		dp[f][i]=sum;
	}
	for (i=2;i<=m;i++){
		f^=1;
		memset(dp[f],63,sizeof(dp[f]));
		Solve(1,n,2,n-(m-i));
	}
	printf("%d\n",dp[f][n]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define N 100010
int A[N],cnt[N],PL,PR;
long long sum;
void Move(int l,int r){
	while (PL>l){
		sum+=cnt[A[--PL]]++;
	}
	while (PR<r){
		sum+=cnt[A[++PR]]++;
	}
	while (PL<l){
		sum-=--cnt[A[PL++]];
	}
	while (PR>r){
		sum-=--cnt[A[PR--]];
	}
}
long long dp[2][N];
int f;
void Solve(int l,int r,int pl,int pr){
	if (l>r){
		return;
	}
	int mid=(l+r)>>1,i,pos=l;
	for (i=pl;i<=pr && i<=mid;i++){
		Move(i,mid);
		if (dp[!f][i-1]+sum<dp[f][mid]){
			dp[f][mid]=dp[!f][i-1]+sum;
			pos=i;
		}
	}
	Solve(l,mid-1,pl,pos);
	Solve(mid+1,r,pos,pr);
}
int main(){
	PL=1,PR=0;
	int n,m,i;
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%d",&A[i]);
		Move(1,i);
		dp[f][i]=sum;
	}
	for (i=2;i<=m;i++){
		f^=1;
		memset(dp[f],63,sizeof(dp[f]));
		Solve(1,n,2,n-(m-i));
	}
	printf("%lld\n",dp[f][n]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define N 100010
int A[N],cnt[N],PL,PR;
long long sum;
void Move(int l,int r){
	while (PL>l){
		sum+=cnt[A[--PL]]++;
	}
	while (PR<r){
		sum+=cnt[A[++PR]]++;
	}
	while (PL<l){
		sum-=--cnt[A[PL++]];
	}
	while (PR>r){
		sum-=--cnt[A[PR--]];
	}
}
int dp[2][N],f;
void Solve(int l,int r,int pl,int pr){
	if (l>r){
		return;
	}
	int mid=(l+r)>>1,i,pos=l;
	for (i=pl;i<=pr && i<=mid;i++){
		Move(i,mid);
		if (dp[!f][i-1]+sum<dp[f][mid]){
			dp[f][mid]=dp[!f][i-1]+sum;
			pos=i;
		}
	}
	Solve(l,mid-1,pl,pos);
	Solve(mid+1,r,pos,pr);
}
int main(){
	PL=1,PR=0;
	int n,m,i;
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%d",&A[i]);
		Move(1,i);
		dp[f][i]=sum;
	}
	for (i=2;i<=m;i++){
		f^=1;
		memset(dp[f],63,sizeof(dp[f]));
		Solve(1,n,2,n-(m-i+1));
	}
	printf("%d\n",dp[f][n]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

int n, k, a[100010], cnt[100010];

long long f[22][100010];

//solve(l, r, L, R) : mid 的决策在[L, R]之间, 初始s为[R+1, l-1]

void solve(int d, int l, int r, int L, int R, long long s = 0) {
	if(l > r) return;
	int mid = l+r>>1;
	int pos = 0;
	//for(int i = mid; i > R; i--) s += cnt[a[i]], cnt[a[i]]++
	for(int i = mid; i >= max(l, R+1); i--) s += cnt[a[i]], cnt[a[i]]++;
	for(int i = min(R, mid); i >= L; i--) {
		if((!~f[d][mid] || f[d][mid] > f[d-1][i]+s) && ~f[d-1][i])
			f[d][mid] = f[d-1][i]+s, pos = i;
		s += cnt[a[i]], cnt[a[i]]++;
	}
	//printf("mid = %d, %d, %d, p = %d\n", mid, L, R, pos);
	for(int i = min(R, mid); i >= L; i--) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = mid; i >= max(l, R+1); i--) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = pos+1; i <= R && i < l; i++) s += cnt[a[i]], cnt[a[i]]++;
	solve(d, l, mid-1, L, pos);
	for(int i = pos+1; i <= R && i < l; i++) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = max(l, R+1); i <= mid; i++) s += cnt[a[i]], cnt[a[i]]++;
	solve(d, mid+1, r, pos, R);
	for(int i = max(l, R+1); i <= mid; i++) cnt[a[i]]--, s -= cnt[a[i]];
}

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i++) scanf("%d", a+i), f[1][i] = f[1][i-1]+cnt[a[i]], cnt[a[i]]++;
	for(int j = 2; j <= k; j++) {
		memset(cnt, 0, sizeof cnt);
		for(int i = 1; i <= n; i++) f[j][i] = -1;
		solve(j, 1, n, 1, n);
	}
	printf("%I64d\n", f[k][n]);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

int n, k, a[100010], cnt[100010];

long long f[22][100010];

//solve(l, r, L, R) : mid 的决策在[L, R]之间, 初始s为[R+1, l-1]

void solve(int d, int l, int r, int L, int R, long long s = 0) {
	if(l > r) return;
	int mid = l+r>>1;
	int pos;
	//for(int i = mid; i > R; i--) s += cnt[a[i]], cnt[a[i]]++
	for(int i = mid; i >= max(l, R+1); i--) s += cnt[a[i]], cnt[a[i]]++;
	for(int i = min(R, mid); i >= L; i--) {
		if((!~f[d][mid] || f[d][mid] > f[d-1][i]+s) && ~f[d-1][i])
			f[d][mid] = f[d-1][i]+s, pos = i;
		s += cnt[a[i]], cnt[a[i]]++;
	}
	//printf("[%d, %d, %d] : mid = %d, %d, %d, p = %d, s = %I64d\n", d, l, r, mid, L, R, pos, s);
	for(int i = mid; i >= max(l, R+1); i--) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = min(R, mid); i >= L; i--) cnt[a[i]]--, s -= cnt[a[i]];
	//printf("%I64d %d %d\n", s, cnt[1], cnt[2]);
	//[R+1, l-1]
	for(int i = pos+1; i <= R && i < l; i++) s += cnt[a[i]], cnt[a[i]]++;
	//[pos+1, l-1]
	solve(d, l, mid-1, L, pos, s);
	for(int i = pos+1; i <= R && i < l; i++) cnt[a[i]]--, s -= cnt[a[i]];
	//[R+1, l-1]
	for(int i = max(l, R+1); i <= mid; i++) s += cnt[a[i]], cnt[a[i]]++;
	//[R+1, mid]
	solve(d, mid+1, r, pos, R, s);
	for(int i = max(l, R+1); i <= mid; i++) cnt[a[i]]--, s -= cnt[a[i]];
}

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i++) scanf("%d", a+i), f[1][i] = f[1][i-1]+cnt[a[i]], cnt[a[i]]++;
	for(int j = 2; j <= k; j++) {
		memset(cnt, 0, sizeof cnt);
		for(int i = 1; i <= n; i++) f[j][i] = -1;
		solve(j, 1, n, 1, n);
	}
	printf("%I64d\n", f[k][n]);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

int n, k, a[100010], cnt[100010];

long long f[22][100010];

//solve(l, r, L, R) : mid 的决策在[L, R]之间

void solve(int d, int l, int r, int L, int R) {
	if(l > r) return;
	int mid = l+r>>1;
	long long s = 0; int pos = 0;
	for(int i = mid; i > R; i--) s += cnt[a[i]], cnt[a[i]]++;
	for(int i = min(R, mid); i >= L; i--) {
		if((!~f[d][mid] || f[d][mid] > f[d-1][i]+s) && ~f[d-1][i])
			f[d][mid] = f[d-1][i]+s, pos = i;
		s += cnt[a[i]], cnt[a[i]]++;
	}
	//printf("mid = %d, %d, %d, p = %d\n", mid, L, R, pos);
	for(int i = L; i <= mid; i++) --cnt[a[i]];
	solve(d, l, mid-1, L, pos);
	solve(d, mid+1, r, pos, R);
}

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i++) scanf("%d", a+i), f[1][i] = f[1][i-1]+cnt[a[i]], cnt[a[i]]++;
	for(int j = 2; j <= k; j++) {
		memset(cnt, 0, sizeof cnt);
		for(int i = 1; i <= n; i++) f[j][i] = -1;
		solve(j, 1, n, 1, n);
	}
	printf("%I64d\n", f[k][n]);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

int n, k, a[100010], cnt[100010];

long long f[22][100010];

//solve(l, r, L, R) : mid 的决策在[L, R]之间, 初始s为[R+1, l-1]

void solve(int d, int l, int r, int L, int R, long long s = 0) {
	if(l > r) return;
	int mid = l+r>>1;
	int pos = 0;
	//for(int i = mid; i > R; i--) s += cnt[a[i]], cnt[a[i]]++
	for(int i = mid; i >= max(l, R+1); i--) s += cnt[a[i]], cnt[a[i]]++;
	for(int i = min(R, mid); i >= L; i--) {
		if((!~f[d][mid] || f[d][mid] > f[d-1][i]+s) && ~f[d-1][i])
			f[d][mid] = f[d-1][i]+s, pos = i;
		s += cnt[a[i]], cnt[a[i]]++;
	}
	//printf("mid = %d, %d, %d, p = %d\n", mid, L, R, pos);
	for(int i = min(R, mid); i >= L; i--) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = mid; i >= max(l, R+1); i--) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = pos+1; i <= R; i++) s += cnt[a[i]], cnt[a[i]]++;
	solve(d, l, mid-1, L, pos);
	for(int i = pos+1; i <= R; i++) cnt[a[i]]--, s -= cnt[a[i]];
	for(int i = max(l, R+1); i <= mid; i++) s += cnt[a[i]], cnt[a[i]]++;
	solve(d, mid+1, r, pos, R);
	for(int i = max(l, R+1); i <= mid; i++) cnt[a[i]]--, s -= cnt[a[i]];
}

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i++) scanf("%d", a+i), f[1][i] = f[1][i-1]+cnt[a[i]], cnt[a[i]]++;
	for(int j = 2; j <= k; j++) {
		memset(cnt, 0, sizeof cnt);
		for(int i = 1; i <= n; i++) f[j][i] = -1;
		solve(j, 1, n, 1, n);
	}
	printf("%I64d\n", f[k][n]);
}


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

#define FOR(i,a,b) for(int i = (a); i < (b); i++)
#define RFOR(i,b,a) for(int i = (b) - 1; i >= (a); i--)
#define ITER(it, a) for(typeof(a.begin()) it = a.begin(); it != a.end(); it++)
#define FILL(a, value) memset(a, value, sizeof(a))

#define SZ(a) (int) a.size()
#define ALL(a) a.begin(),a.end()
#define PB push_back
#define MP make_pair

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;

const double PI = acos(-1.0);
const LL INF = 1000 * 1000 * 1000 + 7;
const LL LINF = INF * (LL)INF;

const int MAX = 100100;
const int MIN = 22;

int A[MAX];
LL C[MAX];

LL DP[MIN][MAX];

int qh, qt;
LL sum;

LL F(LL x)
{
	return x * (x-1) / 2;
}

void add(int x, int val)
{
	sum -= F(C[A[x]]);
	C[A[x]] += val;
	sum += F(C[A[x]]);
}

void remove(int x)
{
	add(x, -1);
}

void add(int x)
{
	add(x, 1);
}

void moveTo(int x, int y)
{
	while(qh > x)
	{
		qh--;
		add(qh);
	}

	while(qt < y)
	{
		qt++;
		add(qt);
	}

	while(qh < x)
	{
		remove(qh);
		qh++;
	}

	while(qt > y)
	{
		remove(qt);
		qt--;
	}
}

LL get(int l, int r)
{
	moveTo(l, r);
	return sum;
}

void solve(int k, int l, int r, int L, int R)
{
	if (l > r) return;
	int m = (l + r) / 2;

	pair<LL, int> res = MP(LINF, INF);
	FOR (i, L, min(m, R) + 1)
	{
		LL cur = get(i, m);
		if (i) cur += DP[k-1][i-1];
		res = min(res, MP(cur, i));
	}

	DP[k][m] = res.first;
	solve(k, l, m-1, L, res.second);
	solve(k, m+1, r, res.second, R);
}

int main()
{
	//freopen("in.txt", "r", stdin);
	//ios::sync_with_stdio(false); cin.tie(0);

	int n, k;
	scanf("%d%d", &n, &k);
	FOR (i, 0, n)
	{
		scanf("%d", &A[i]);
	}

	qh = 0;
	qt = -1;

	FOR (i, 0, n)
	{
		DP[0][i] = LINF;
	}

	FOR (i, 1, k+1)
	{
		solve(i, 0, n-1, 0, n-1);
	}

	LL res = DP[k][n-1];
	cout<<res<<endl;

}


#include<bits/stdc++.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof(x.end())i=x.begin();i!=x.end();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define RX x=0;char t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;char t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int &x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char &x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char *x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf &x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf &x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint &x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull &x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;char s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){char s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char *x){while(*x)P(*x++);RT}
I Fw&OP()(const char *x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=100007;

int n,m,s[N],tag[N],cnt[N],T;
ll f[N],g[N];

inline int&cc(int x)
{
	if(tag[x]!=T)tag[x]=T,cnt[x]=0;
	return cnt[x];
}

int al,ar;ll u;

inline void trans(int l,int r)
{
	for(;ar<r;u+=cnt[s[++ar]]++);
	for(;al>l;u+=cnt[s[--al]]++);
	for(;ar>r;u-=--cnt[s[ar--]]);
	for(;al<l;u-=--cnt[s[al++]]);
}

struct sol
{
	int l,r,ql,qr;
}q[N];

int qe;

inline void solve(int l,int r,int ql,int qr)
{
	int mid=(l+r)>>1,pos;
	ll t=1e18;
	int ma=min(mid,qr);
	trans(ma+1,mid);
	//fd(i,mid,ma+1)u+=cc(s[i])++;
	fd(i,ma,ql)
	{
		trans(i,mid);
		if(f[i-1]+u<t)t=f[i-1]+u,pos=i;
	}
	al=ql;
	g[mid]=t;
	if(l<mid)q[qe++]=(sol){l,mid-1,ql,pos};
	if(mid<r)q[qe++]=(sol){mid+1,r,pos,qr};
}

int main()
{
	in,n,m;
	fo1(i,n)in,s[i];
	fo1(i,n)
	{
		f[i]=f[i-1]+(cnt[s[i]]++);
	}
	fo0(i,m-1)
	{
		al=1,ar=0,u=0,qe=0;
		mset(cnt,0);
		q[qe++]=(sol){1,n,1,n};
		for(int j=0;j<qe;j++)
			solve(q[j].l,q[j].r,q[j].ql,q[j].qr);
		mcpy(f,g);
	}
	out,f[n],'\n';
}


#include<bits/stdc++.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof(x.end())i=x.begin();i!=x.end();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define RX x=0;char t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;char t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int &x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char &x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char *x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf &x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf &x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint &x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull &x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;char s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){char s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char *x){while(*x)P(*x++);RT}
I Fw&OP()(const char *x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=100007;

int n,m,s[N],tag[N],cnt[N],T;
ll f[N],g[N];

inline int&cc(int x)
{
	if(tag[x]!=T)tag[x]=T,cnt[x]=0;
	return cnt[x];
}

inline void solve(int l,int r,int ql,int qr)
{
	int mid=(l+r)>>1,pos;
	ll t=1e18,u=0;
	++T;
	fd(i,mid,qr+1)u+=cc(s[i])++;
	fd(i,min(mid,qr),ql)
	{
		u+=cc(s[i])++;
		if(f[i-1]+u<t)t=f[i-1]+u,pos=i;
	}
	g[mid]=t;
	if(l<mid)solve(l,mid-1,ql,pos);
	if(mid<r)solve(mid+1,r,pos,qr);
}

int main()
{
	in,n,m;
	fo1(i,n)in,s[i];
	fo1(i,n)
	{
		f[i]=f[i-1]+(cnt[s[i]]++);
	}
	fo0(i,m-1)
	{
		solve(1,n,1,n);
		mcpy(f,g);
	}
	out,f[n],'\n';
}


#include<stdio.h>
#include<string.h>
int now, a[100005], sum[100005], dp[22][100005];
void Solve(int l, int r, int L, int R, int s)
{
	 if(l>r)return;
    int Mid=l+r>>1,x=0;
    for(int i=l;i<=Mid;i++)s+=sum[a[i]]++;
    for(int i=L;i<=R&&i<=Mid;i++){
        s-=--sum[a[i]];
        if(s+dp[now-1][i]<dp[now][Mid])x=i,dp[now][Mid]=s+dp[now-1][i];
    }
    for(int i=L;i<=R&&i<=Mid;i++)s+=sum[a[i]]++;
    for(int i=l;i<=Mid;i++)s-=--sum[a[i]];
    Solve(l,Mid-1,L,x,s);
    for(int i=L;i<x;i++)s-=--sum[a[i]];
    for(int i=l;i<=Mid;i++)s+=sum[a[i]]++;
    Solve(Mid+1,r,x,R,s);
    for(int i=L;i<x;i++)sum[a[i]]++;
    for(int i=l;i<=Mid;i++)sum[a[i]]--;
}
int main(void)
{
	int n, m, i;
	scanf("%d%d", &n, &m);
	for(i=1;i<=n;i++)
		scanf("%d", &a[i]);
	memset(dp, 62, sizeof(dp));
	dp[1][0] = 0;
	for(i=1;i<=n;i++)
	{
		dp[1][i] = dp[1][i-1]+sum[a[i]];
		sum[a[i]]++;
	}
	for(i=2;i<=m;i++)
	{
		now = i;
		memset(sum, 0, sizeof(sum));
		Solve(1, n, 1, n, 0);
	}
	printf("%d\n", dp[m][n]);
	return 0;
}
/*
7 3
1 1 3 3 3 2 1
*/


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
	char c=nc();
	for(;c<'0'||c>'9';c=nc());
	for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 100010
#define ll long long
ll f[2][N],Ans;
int i,j,k,n,m,p,a[N],v[N],s[N],cnt;
bool b;
inline void Update(int x,int y){
	if(v[x]!=y)v[x]=y,s[x]=1;else Ans+=s[x];
}
inline void Solve(int l,int r,int L,int R){
	if(l>r)return;
	int Mid=l+r>>1,x=0,s=0;
	Ans=0;cnt++;
	for(int i=min(R,Mid);i>=L;i--){
		if(!x||Ans+f[b^1][i]<s)x=i,s=Ans+f[b^1][i];
		Update(a[i],cnt);
	}
	f[b][Mid]=s;
	Solve(l,Mid-1,L,x);Solve(Mid+1,r,x,R);
}
int main(){
	Read(n);Read(m);
	for(i=1;i<=n;i++)Read(a[i]);
	Ans=0;
	for(i=cnt=1;i<=n;i++)Update(a[i],1),f[1][i]=Ans;
	while(--m){
		Solve(1,n,0,n);
		b^=1;
	}
	printf("%d\n",f[b^1][n]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
	char c=nc();
	for(;c<'0'||c>'9';c=nc());
	for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 100010
#define ll long long
#define INF 1e18
ll f[2][N];
int i,j,k,n,m,p,a[N],c[N];
bool b;
inline void Solve(int l,int r,int L,int R,ll s){
	if(l>r)return;
	int Mid=l+r>>1,x=0;
	for(int i=l;i<=Mid;i++)s+=c[a[i]]++;
	for(int i=L;i<=R&&i<=Mid;i++){
		s-=--c[a[i]];
		if(s+f[b^1][i]<f[b][Mid])x=i,f[b][Mid]=s+f[b^1][i];
	}
	for(int i=L;i<=R&&i<=Mid;i++)s+=c[a[i]]++;
	for(int i=l;i<=Mid;i++)s-=--c[a[i]];
	Solve(l,Mid-1,L,x,s);
	for(int i=L;i<x;i++)s-=--c[a[i]];
	for(int i=l;i<=Mid;i++)s+=c[a[i]]++;
	Solve(Mid+1,r,x,R,s);
	for(int i=L;i<x;i++)c[a[i]]++;
	for(int i=l;i<=Mid;i++)c[a[i]]--;
}
int main(){
	Read(n);Read(m);
	for(i=1;i<=n;i++)Read(a[i]);
	for(i=1;i<=n;i++)f[1][i]=f[1][i-1]+(c[a[i]]++);
	while(--m){
		memset(c,0,sizeof(c));
		for(i=1;i<=n;i++)f[b][i]=INF;
		Solve(1,n,1,n,0);
		b^=1;
	}
	printf("%d\n",f[b^1][n]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
	char c=nc();
	for(;c<'0'||c>'9';c=nc());
	for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 100010
#define ll long long
#define INF 1e18
ll f[2][N];
int i,j,k,n,m,p,a[N],c[N];
bool b;
inline void Solve(int l,int r,int L,int R,ll s){
	if(l>r)return;
	int Mid=l+r>>1,x=0;
	for(int i=l;i<=Mid;i++)s+=c[a[i]]++;
	for(int i=L;i<=R&&i<=Mid;i++){
		s-=--c[a[i]];
		if(s+f[b^1][i]<f[b][Mid])x=i,f[b][Mid]=s+f[b^1][i];
	}
	for(int i=L;i<=R&&i<=Mid;i++)s+=c[a[i]]++;
	for(int i=l;i<=Mid;i++)s-=--c[a[i]];
	Solve(l,Mid-1,L,x,s);
	for(int i=L;i<x;i++)s-=--c[a[i]];
	for(int i=l;i<=Mid;i++)s+=c[a[i]]++;
	Solve(Mid+1,r,x,R,s);
	for(int i=L;i<x;i++)c[a[i]]++;
	for(int i=l;i<=Mid;i++)c[a[i]]--;
}
int main(){
	Read(n);Read(m);
	for(i=1;i<=n;i++)Read(a[i]);
	for(i=1;i<=n;i++)f[1][i]=f[1][i-1]+(c[a[i]]++);
	while(--m){
		memset(c,0,sizeof(c));
		for(i=1;i<=n;i++)f[b][i]=INF;
		Solve(1,n,1,n,0);
		b^=1;
	}
	cout<<f[b^1][n]<<endl;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
	char c=nc();
	for(;c<'0'||c>'9';c=nc());
	for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 100010
#define ll long long
ll f[2][N],Ans;
int i,j,k,n,m,p,a[N],v[N],s[N],cnt;
bool b;
inline void Update(int x,int y){
	if(v[x]!=y)v[x]=y,s[x]=1;else Ans+=s[x],s[x]++;
}
inline void Solve(int l,int r,int L,int R){
	if(l>r)return;
	int Mid=l+r>>1,x=0,s=0;
	Ans=0;cnt++;
	for(int i=Mid;i>R;i--)Update(a[i],cnt);
	for(int i=min(R,Mid);i>=L;i--){
		if(!x||Ans+f[b^1][i]<s)x=i,s=Ans+f[b^1][i];
		Update(a[i],cnt);
	}
	f[b][Mid]=s;
	Solve(l,Mid-1,L,x);Solve(Mid+1,r,x,R);
}
int main(){
	Read(n);Read(m);
	for(i=1;i<=n;i++)Read(a[i]);
	Ans=0;
	for(i=cnt=1;i<=n;i++)Update(a[i],1),f[1][i]=Ans;
	while(--m){
		Solve(1,n,1,n);
		b^=1;
	}
	printf("%d\n",f[b^1][n]);
	return 0;
}


#include"iostream"
#include"stdio.h"
#define ll long long
using namespace std;
const int Maxn=1e5+5;
int a[Maxn],p[Maxn];ll f[Maxn][25];
void solve(int l,int r,int L,int R,int k,ll tmp)
{
	if(L>R)return ;
	int mid=(L+R)>>1,x;
	for(int i=L;i<=mid;i++)tmp+=p[a[i]]++;
	for(int i=l;i<=r&&i<=mid;i++)
	{
		tmp-=--p[a[i]];
		if(f[i][k-1]+tmp<f[mid][k])
			f[mid][k]=f[i][k-1]+tmp,x=i;
	}
	for(int i=L;i<=mid;i++)tmp-=--p[a[i]];
	for(int i=l;i<=r&&i<=mid;i++)tmp+=p[a[i]]++;
	solve(l,x,L,mid-1,k,tmp);
	for(int i=l;i<x;i++)tmp-=--p[a[i]];
	for(int i=L;i<=mid;i++)tmp+=p[a[i]]++;
	solve(x,r,mid+1,R,k,tmp);
	for(int i=l;i<x;i++)p[a[i]]++;
	for(int i=L;i<=mid;i++)p[a[i]]--;
}
int main()
{
	#ifdef cf
	freopen("text.in","r",stdin);
	#endif
	int n,k;ll tmp=0;scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		tmp+=p[a[i]]++,f[i][1]=tmp;
	for(int i=1;i<=n;i++)
		for(int j=2;j<=k;j++)
			f[i][j]=1ll<<60;
	//		while(1);
	for(int j=2;j<=k;j++)
	{
		for(int i=1;i<=n;i++)p[i]=0;
		solve(1,n,1,n,j,0);
	}
	printf("%lld",f[n][k]);
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL oo=1e18;
LL G[N],F[N],now;
int num[N],a[N],col[N],Case,n,m,i,k;
void add(int val){
	if (col[val]!=Case) col[val]=Case,num[val]=0;
	now+=num[val]++;
}
void solve(int l,int r,int ml,int mr){
	int mid=(l+r)>>1,st=min(mr,mid-1);
	++Case;now=0;
	for (int i=mid;i>st;i--)
	  add(a[i]);
	F[mid]=oo;int id=0;
	for (int i=st;i>=ml;i--){
		if (G[i]+now<F[mid])
		  F[mid]=G[i]+now,id=i;
		add(a[i]);
	}
	if (l<mid) solve(l,mid-1,ml,id);
	if (mid<r) solve(mid+1,r,id,mr);
}
int main(){
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++)
	  scanf("%d",&a[i]);
	G[0]=0;for (i=1;i<=n;i++) G[i]=oo;
	for (k=1;k<=m;k++){
		solve(1,n,0,n-1);
		for (i=0;i<=n;i++)
		  G[i]=F[i];
	}
	printf("%lld\n",F[n]);
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL oo=1e18;
LL G[N],F[N],now;
int num[N],a[N],col[N],Case,n,m,i,k,L,R;
void add(int val){
	//if (col[val]!=Case)
	  //col[val]=Case,num[val]=0;
	now+=num[val]++;
}
void del(int val){
	now-=(--num[val]);
}
void solve(int l,int r,int ml,int mr){
	int mid=(l+r)>>1,st=min(mr,mid-1);
	int tmpL=L,tmpR=R;
	for (;R<mid;add(a[++R]));
	for (;L>st+1;add(a[--L]));
	for (;R>mid;del(a[R--]));
	for (;L<st+1;del(a[L++]));
	F[mid]=oo;int id=0;
	for (int i=st;i>=ml;i--){
		if (G[i]+now<F[mid])
		  F[mid]=G[i]+now,id=i;
		add(a[--L]);
	}
	if (l<mid) solve(l,mid-1,ml,id);
	if (mid<r) solve(mid+1,r,id,mr);
  for (;R<tmpR;add(a[++R]));
  for (;L>tmpL;add(a[--L]));
  for (;R>tmpR;del(a[R--]));
  for (;L<tmpL;del(a[L++]));
}
int main(){
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++)
	  scanf("%d",&a[i]);
	G[0]=0;for (i=1;i<=n;i++) G[i]=oo;
	for (k=1;k<=m;k++){
		for (i=1;i<=n;i++) num[i]=0;now=0;
		L=1;R=0;solve(1,n,0,n-1);
		for (i=0;i<=n;i++)
		  G[i]=F[i];
	}
	printf("%lld\n",F[n]);
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;
#define MAXN 100000
#define INFLL 0x3f3f3f3f3f3f3fll
#define ll long long
#define rint register int
#define gc() getchar()
inline int read(rint ans = 0, rint sgn = ' ', rint ch = gc())
{
	for(; ch < '0' || ch > '9'; sgn = ch, ch = gc());
	for(; ch >='0' && ch <='9';(ans*=10)+=ch-'0', ch = gc());
	return sgn-'-'?ans:-ans;
}
#define BUF_SIZE 1000000
#define _END fwrite(_Ob,1,_O-_Ob,stdout), _O = _Ob
#define Outc(a) (*_O++ = a)
char _Ob[BUF_SIZE+5], *_O = _Ob, _Os[25], *_Ot;
template <typename T> inline void Out(T x)
{
	if(!x){Outc('0'); return;} if(x < 0) Outc('-'), x = -x;
	for(_Ot = _Os; x; *_Ot++ = x%10+'0', x /= 10);
	for(; _Ot != _Os; Outc(*--_Ot)); if(_O-_Ob >= BUF_SIZE-50) _END;
}
ll f[MAXN+5], t[MAXN+5], RES; int c[MAXN+5], a[MAXN+5], L, R, n, K;
inline void GEN(int l, int r)
{
	for(; L > l; --L, RES += c[a[L]]++);
	for(; R < r; ++R, RES += c[a[R]]++);
	for(; L < l; RES -= --c[a[L]], ++L);
	for(; R > r; RES -= --c[a[R]], --R);
}
void DP(int lef, int rig, int dl, int dr)
{
	if(lef > rig || dl > dr) return;
	if(dl == dr){for(rint i = lef; i <= rig; GEN(dl+1,i), t[i] = RES+f[dl], i++); return;}
	static int mid, d; static ll c; mid = lef+rig>>1, c = INFLL;
	for(rint j = dl; j <= dr && j < mid; j++)
		if(GEN(j+1,mid), RES+f[j] < c) d = j, c = RES+f[j];
	t[mid] = c; DP(lef,mid-1,dl,d), DP(mid+1,rig,d,dr);
}
int main()
{
	n = read(), K = read(); for(rint i = 1; i <= n; a[i++] = read());
	L = 1, R = 0; for(rint i = 1; i <= n; GEN(1,i), f[i] = RES, i++);
	for(rint k = 2; k <= K; DP(1,n,1,n), memcpy(f+1,t+1,n<<3), k++); printf("%I64d\n",f[n]); return 0;
}


#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#define RG register
#define R RG int
#define G c=getchar()
typedef long long LL;
const int N=1e5+9;
int a[N],c[N];
LL ff[N],gg[N],*f=ff,*g=gg;
inline int in(){
	RG char G;
	while(c<'-')G;
	R x=c&15;G;
	while(c>'-')x=x*10+(c&15),G;
	return x;
}
void solve(R l,R r,R kl,R kr,RG LL w){
	if(l>r)return;
	R m=(l+r)>>1,k=0,p=m<kr?m:kr,i;
	for(i= l;i<=m;++i)w+=c[a[i]]++;
	for(i=kl;i<=p;++i)w-=--c[a[i]],g[m]>f[i]+w?g[m]=f[i]+w,k=i:0;
	for(i=kl;i<=p;++i)w+=c[a[i]]++;
	for(i= l;i<=m;++i)w-=--c[a[i]];
	solve(l,m-1,kl,k,w);
	for(i= l;i<=m;++i)w+=c[a[i]]++;
	for(i=kl;i< k;++i)w-=--c[a[i]];
	solve(m+1,r,k,kr,w);
	for(i=kl;i< k;++i)++c[a[i]];
	for(i= l;i<=m;++i)--c[a[i]];
}
int main(){
	R n=in(),k=in();
	RG LL*tmp;
	for(R i=1;i<=n;++i)
		f[i]=f[i-1]+c[a[i]=in()]++;
	memset(c,0,(n+1)<<2);
	while(--k){
		memset(g,1,(n+1)<<3);
		solve(1,n,1,n,0);
		tmp=f;f=g;g=tmp;
	}
	printf("%lld\n",f[n]);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
int n,k,i,a[N],cnt[N];
ll s,f[N],g[N];
void solve(int l,int r,int x,int y){
	register int i,m=(x+y)>>1,j;
	register ll s=0;
	for(i=m;i>r;--i)s+=cnt[a[i]]++;
	for(;i>=l;--i){
		s+=cnt[a[i]]++;
		if(f[i-1]+s<g[m])j=i,g[m]=f[i-1]+s;
	}
	for(i=l;i<=m;++i)cnt[a[i]]=0;
	if(x<m)solve(l,j,x,m-1);
	if(m<y)solve(j,r,m+1,y);
}
int main(){
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i){
		s+=cnt[a[i]]++;
		f[i]=g[i]=s;
	}
	memset(cnt+1,0,n<<2);
	for(i=2;i<=k;++i){
		solve(1,n,1,n);
		memcpy(f+1,g+1,n<<3);
	}
	cout<<f[n]<<endl;
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
const ll inf=1ll<<62;
int n,k,i,a[N],cnt[N];
ll s,f[N],g[N];
void solve(int l,int r,int x,int y){
	register int i,m=(x+y)>>1,j;
	register ll s=0;
	for(i=m;i>r;--i)s+=cnt[a[i]]++;
	for(;i>=l;--i){
		s+=cnt[a[i]]++;
		if(f[i-1]+s<g[m])j=i,g[m]=f[i-1]+s;
	}
	for(i=l;i<=m;++i)cnt[a[i]]=0;
	if(x<m)solve(l,j,x,m-1);
	if(m<y)solve(j,r,m+1,y);
}
int main(){
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i){
		s+=cnt[a[i]]++;
		f[i]=g[i]=s;
	}
	memset(cnt+1,0,n<<2);
	for(i=2;i<=k;++i){
		solve(1,n,1,n);
		memcpy(f+1,g+1,n<<3);
	}
	cout<<f[n]<<endl;
	return 0;
}


//#pragma GCC optimize("O2")
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
int n,k,i,a[N],cnt[N],u,v;
ll s,f[N],g[N];
inline void work(int l,int r){
	while(u>l)s+=cnt[a[--u]]++;
	while(v<r)
		s+=cnt[a[++v]]++;
	while(u<l)
		s-=--cnt[a[u++]];
	while(v>r)
		s-=--cnt[a[v--]];
}
void solve(int l,int r,int x,int y){
	register int i,m=(x+y)>>1,j=m<r?m:r;
	for(i=j;i>=l;--i){
		work(i,m);
		if(f[i-1]+s<g[m])j=i,g[m]=f[i-1]+s;
	}
	if(x<m && l<=j)solve(l,j,x,m-1);
	if(m<y && j<=r)solve(j,r,m+1,y);
}
int main(){
	//freopen("f.txt","r",stdin);
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i){
		s+=cnt[a[i]]++;
		f[i]=g[i]=s;
	}
	memset(cnt+1,0,n<<2);
	for(i=2;i<=k;++i){
		s=0;u=v=cnt[a[1]]=1;solve(1,n,1,n);
		memcpy(f+1,g+1,n<<3);memset(cnt+1,0,n<<2);
	}
	cout<<f[n]<<endl;
	return 0;
}


//#pragma GCC optimize("O2")
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
int n,k,i,a[N],cnt[N];
ll s,f[N],g[N];
void solve(int l,int r,int x,int y){
	register int i,m=(x+y)>>1,j=m;
	register ll s=0;
	for(i=m;i>r;--i)s+=cnt[a[i]]++;
	for(;i>=l;--i){
		s+=cnt[a[i]]++;
		if(f[i-1]+s<g[m])j=i,g[m]=f[i-1]+s;
	}
	for(i=x;i<=m;++i)cnt[a[i]]=0;
	if(x<m && l<=j)solve(l,j,x,m-1);
	if(m<y && j<=r)solve(j,r,m+1,y);
}
int main(){
	//freopen("f.txt","r",stdin);
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i){
		s+=cnt[a[i]]++;
		f[i]=g[i]=s;
	}
	memset(cnt+1,0,n<<2);
	for(i=2;i<=k;++i){
		solve(1,n,1,n);
		memcpy(f+1,g+1,n<<3);
	}
	cout<<f[n]<<endl;
	return 0;
}


#pragma GCC optimize("O2")
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
int n,k,i,a[N],cnt[N];
ll s,f[N],g[N];
void solve(int l,int r,int x,int y){
	register int i,m=(x+y)>>1,j=m;
	register ll s=0;
	for(i=m;i>r;--i)s+=cnt[a[i]]++;
	for(;i>=l;--i){
		s+=cnt[a[i]]++;
		if(f[i-1]+s<g[m])j=i,g[m]=f[i-1]+s;
	}
	for(i=l;i<=m;++i)cnt[a[i]]=0;
	if(x<m)solve(l,j,x,m-1);
	if(m<y)solve(j,r,m+1,y);
}
int main(){
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	for(i=1;i<=n;++i){
		s+=cnt[a[i]]++;
		f[i]=g[i]=s;
	}
	memset(cnt+1,0,n<<2);
	for(i=2;i<=k;++i){
		solve(1,n,1,n);
		memcpy(f+1,g+1,n<<3);
	}
	cout<<f[n]<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int p[101000],a[101000],k;long long dp[101000][22],w;
void del(int x){p[a[x]]--;w-=p[a[x]];}
void ins(int x){w+=p[a[x]];p[a[x]]++;}
void move(int &a,int &b,int c,int d)
{
	while(a<c)del(a++);
	while(a>c)ins(--a);
	while(b<d)ins(++b);
	while(b>d)del(b--);
}
void solve(int l,int r,int l1,int r1)//w=w(l1,l)=w[p,q]
{
	if(l>r)return;
	int mid=l+r>>1;
	int g=-1,p=l1+1,q=l-1;
	move(p,q,l1+1,mid);
	for(int i=l1;i<=min(mid,r1);i++)
	{
		if(dp[i][k-1]+w<dp[mid][k])
			dp[mid][k]=dp[i][k-1]+w,g=i;
		del(p++);
	}
	move(p,q,l1+1,l-1);
	solve(l,mid-1,l1,g);
	move(p,q,g+1,mid);
	solve(mid+1,r,g,r1);
	move(p,q,l1+1,l-1);
}
int main()
{
	int n,K;scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		for(int j=0;j<=K;j++)dp[i][j]=1ll<<60;
	for(int i=1;i<=K;i++)
	{
		k=i;w=0;memset(p,0,sizeof(p));solve(1,n,0,n);
	}
	printf("%lld\n",dp[n][K]);return 0;
 }
/*
dp[i][k]=min(dp[j][k-1]+w(j,i])
因为费用是平方并且是取min，所以g[i](i的决策点)单调上升
每次分治解决[l,r]区间内的DP值，且决策点范围为[l1,r1]
求出mid由哪转移(暴力做决策并更新w)
分治传给下一层
*/


#include <bits/stdc++.h>

const int N = 1000005;

using namespace std;

int n, m, a[N], nl, nr, cnt[N];
long long sum, f[N], g[N];

void divide(int l, int r, int L, int R) {
	if(l>r) return ;
	int mid = (l+r)>>1;
	int P = min(mid, R);
	while(nr < mid) ++nr, sum += cnt[a[nr]], ++cnt[a[nr]];
	while(nl < P+1) --cnt[a[nl]], sum -= cnt[a[nl]], ++nl;
	while(nr > mid) --cnt[a[nr]], sum -= cnt[a[nr]], --nr;
	while(nl > P+1)  --nl, sum += cnt[a[nl]], ++cnt[a[nl]];
	long long mn = 1ll<<60; int nP;
	for(int i=P; i>=L; --i) {
		--nl;
		sum += cnt[a[nl]];
		++cnt[a[nl]];
		if(f[i-1] + sum < mn) mn = f[i-1] + sum, nP = i;
	}
	g[mid] = mn;
	divide(l, mid-1, L, nP);
	divide(mid+1, r, nP, R);
}

int main() {

	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; ++i) scanf("%d", &a[i]);

	f[0] = 0;
	for(int i=1; i<=n; ++i) f[i] = 1ll<<60;
	for(int i=1; i<=m; ++i) {
		sum = 0; nr = 0; nl = 1;
		for(int j=0; j<=n; ++j) cnt[j] = 0;
		divide(i, n, i, n);
		for(int j=0; j<=n; ++j) f[j] = g[j];
	}

	printf("%I64d\n", f[n]);

	return 0;

}


#include<bits/stdc++.h>
#define debug(x) cout<<#x<<"="<<x<<endl
typedef long long ll;
using namespace std;
const int N = 100009, M = 21;

int a[N],cnt[N];
ll f[M][N];
int n,m,lp,rp;
ll sum;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

void modify(int l,int r)
{
	while(lp>l) lp--,sum+=cnt[a[lp]]++;
	while(rp<r) rp++,sum+=cnt[a[rp]]++;
	while(lp<l) sum-=--cnt[a[lp]],lp++;
	while(rp>r) sum-=--cnt[a[rp]],rp--;
}

void solve(int step,int l,int r,int L,int R)
{
	if(l>r) return ;
	int mid=(l+r)>>1,p=min(mid,R),Mid=L;
	for(int i=L;i<=p;i++)
	{
		modify(i,mid);
		if(f[step-1][i-1]+sum<f[step][mid]) f[step][mid]=f[step-1][i-1]+sum,Mid=i;
	}
	solve(step,l,mid-1,L,Mid);
	solve(step,mid+1,r,Mid,R);
}

int main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) f[1][i]=f[1][i-1]+(cnt[a[i]]++);
	for(int i=2;i<=m;i++)
	{
		memset(cnt,0,sizeof cnt);
		memset(f[i],63,sizeof f[i]);
		lp=1;rp=0;sum=0;
		solve(i,1,n,1,n);
	}
	cout<<f[m][n]<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read(){
	ll rt=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){rt=rt*10+ch-'0';ch=getchar();}
	return rt;
}
ll n,k,data[200000],f[22][100090],ttt[100050];
void DAC(int qqq,int l,int r,int L,int R,ll sum){
	if(l>r)return;
	int mid=(l+r)>>1,M=-1;
	int point = min(mid,R);
//	cout<<qqq<<" "<<point<<endl;
	for(int i=l;i<=mid;i++)sum += ttt[data[i]]++;
	for(int i=L;i<=point;i++){
		sum -= --ttt[data[i]];
		if(sum + f[qqq-1][i] < f[qqq][mid]){
			M = i; f[qqq][mid] = sum + f[qqq-1][i];
		}
	}

	for(int i=point;i>=L;i--) sum += ttt[data[i]]++;
	for(int i=mid;i>=l;i--) sum -= --ttt[data[i]];
	DAC(qqq,l,mid-1,L,M,sum);

	for(int i=l;i<=mid;i++) sum += ttt[data[i]]++;
	for(int i=L;i<M;i++) sum -= --ttt[data[i]];
	DAC(qqq,mid+1,r,M,R,sum);

	for(int i=mid;i>=l;i--) sum -= --ttt[data[i]];
	for(int i=M-1;i>=L;i--) sum += ttt[data[i]]++;
}
int main(){
	n=read();k=read();
	for(int i=1;i<=n;i++)data[i]=read();
	for(int i=1;i<=n;i++){
		f[0][i] = f[0][i-1] + (ttt[data[i]]++);
	//	cout<<f[i][0]<<endl;
	}

//	p = 1;
//	q = 0;
	for(int i=1;i<k;i++){
		memset(ttt,0,sizeof ttt);
		for(int j=0;j<=n;j++)f[i][j] = 0x7fffffffffffffLL;
	/*	for(int j=1;j<=n;j++)cout<<f[j][i]<<" ";
		cout<<endl;*/
		DAC(i,1,n,1,n,0);
		/*for(int j=1;j<=n;j++)cout<<f[j][i]<<" ";
		cout<<endl;*/
	}
	cout<<f[k-1][n];
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read(){
	ll rt=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){rt=rt*10+ch-'0';ch=getchar();}
	return rt;
}
ll n,k,data[200000],f[100030][22],ttt[100050];
void DAC(int qqq,int l,int r,int L,int R,ll sum){
	if(l>r)return;
	int mid=(l+r)>>1,M=-1;
	int point = min(mid,R);
//	cout<<qqq<<" "<<point<<endl;
	for(int i=l;i<=mid;i++)sum += ttt[data[i]]++;
	for(int i=L;i<=point;i++){
		sum -= --ttt[data[i]];
		if(sum + f[i][qqq-1] < f[mid][qqq]){
			M = i; f[mid][qqq] = sum + f[i][qqq-1];
		}
	}

	for(int i=point;i>=L;i--) sum += ttt[data[i]]++;
	for(int i=mid;i>=l;i--) sum -= --ttt[data[i]];
	DAC(qqq,l,mid-1,L,M,sum);

	for(int i=l;i<=mid;i++) sum += ttt[data[i]]++;
	for(int i=L;i<M;i++) sum -= --ttt[data[i]];
	DAC(qqq,mid+1,r,M,R,sum);

	for(int i=mid;i>=l;i--) sum -= --ttt[data[i]];
	for(int i=M-1;i>=L;i--) sum += ttt[data[i]]++;
}
int main(){
	n=read();k=read();
	for(int i=1;i<=n;i++)data[i]=read();
	for(int i=1;i<=n;i++){
		f[i][0] = f[i-1][0] + (ttt[data[i]]++);
	//	cout<<f[i][0]<<endl;
	}

//	p = 1;
//	q = 0;
	for(int i=1;i<k;i++){
		memset(ttt,0,sizeof ttt);
		for(int j=0;j<=n;j++)f[j][i] = 0x7fffffffffffffLL;
	/*	for(int j=1;j<=n;j++)cout<<f[j][i]<<" ";
		cout<<endl;*/
		DAC(i,1,n,1,n,0);
		/*for(int j=1;j<=n;j++)cout<<f[j][i]<<" ";
		cout<<endl;*/
	}
	cout<<f[n][k-1];
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int n,k;
int a[200007];
long long f[200007][21];
long long cnt;
int sum[200007];
int p,q;
vector< pair<pair<int,int>,pair<int,int> > >que;
void Mo_algorithm1(int x)
{
	while (p>x)
	{
		cnt+=sum[a[--p]];
		++sum[a[p]];
	}
	while (p<x)
	{
		--sum[a[p]];
		cnt-=sum[a[p++]];
	}
}
void Mo_algorithm2(int x)
{
	while (q<x)
	{
		cnt+=sum[a[++q]];
		++sum[a[q]];
	}
	while (q>x)
	{
		--sum[a[q]];
		cnt-=sum[a[q--]];
	}
}
int main()
{
	n=read(),k=read();
	for (int i=1;i<=n;i++)
		a[i]=read();
	memset(sum,0,sizeof(sum));
	++sum[a[1]];
	p=1,q=1;
	cnt=0;
	memset(f,-1,sizeof(f));
	f[0][0]=0;
	for (int i=1;i<=k;i++)
	{
		int lx=-1,rx=0;
		que.clear();
		que.push_back(make_pair(make_pair(1,n),make_pair(1,n)));
		while (lx<rx)
		{
			++lx;
			int left=que[lx].first.first,right=que[lx].first.second;
			int L=que[lx].second.first,R=que[lx].second.second;
if (left<=right&&L<=R)
{
			int mid=(left+right)/2,now;
			Mo_algorithm2(mid);
			Mo_algorithm1(L);
			for (int j=L;j<=R&&j<=mid;j++)
			{
				Mo_algorithm1(j);
				if (f[j-1][i-1]!=-1&&(f[mid][i]==-1||f[mid][i]>cnt+f[j-1][i-1]))
				{
					f[mid][i]=cnt+f[j-1][i-1];
					now=j;
				}
			}
			rx+=2;
			que.push_back(make_pair(make_pair(left,mid-1),make_pair(L,now)));
			que.push_back(make_pair(make_pair(mid+1,right),make_pair(now,R)));
}
		}
	}
	printf("%I64d\n",f[n][k]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int n,k;
int a[200007];
long long f[200007][21];
long long cnt;
int sum[200007];
int p,q;
vector< pair<pair<int,int>,pair<int,int> > >que;
void Mo_algorithm1(int x)
{
	while (p>x)
	{
		cnt+=sum[a[--p]];
		++sum[a[p]];
	}
	while (p<x)
	{
		--sum[a[p]];
		cnt-=sum[a[p++]];
	}
}
void Mo_algorithm2(int x)
{
	while (q<x)
	{
		cnt+=sum[a[++q]];
		++sum[a[q]];
	}
	while (q>x)
	{
		--sum[a[q]];
		cnt-=sum[a[q--]];
	}
}
int main()
{
	n=read(),k=read();
	for (int i=1;i<=n;i++)
		a[i]=read();
	memset(sum,0,sizeof(sum));
	++sum[a[1]];
	p=1,q=1;
	cnt=0;
	memset(f,-1,sizeof(f));
	f[0][0]=0;
	for (int i=1;i<=k;i++)
	{
		int lx=-1,rx=0;
		que.clear();
		que.push_back(make_pair(make_pair(1,n),make_pair(1,n)));
		while (lx<rx)
		{
			++lx;
			int left=que[lx].first.first,right=que[lx].first.second;
			int L=que[lx].second.first,R=que[lx].second.second;
if (left<=right&&L<=R)
{
			int mid=(left+right)/2,now=L;
			Mo_algorithm2(mid);
			Mo_algorithm1(L);
			for (int j=L;j<=R&&j<=mid;j++)
			{
				Mo_algorithm1(j);
				if (f[j-1][i-1]!=-1&&(f[mid][i]==-1||f[mid][i]>cnt+f[j-1][i-1]))
				{
					f[mid][i]=cnt+f[j-1][i-1];
					now=j;
				}
			}
			rx+=2;
			que.push_back(make_pair(make_pair(left,mid-1),make_pair(L,now)));
			que.push_back(make_pair(make_pair(mid+1,right),make_pair(now,R)));
}
		}
	}
	printf("%lld\n",f[n][k]);
	return 0;
}


#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
typedef long long LL;
int c[N],a[N];
LL f[N],g[N];
int p,q,tot,n,k;
void move(int l,int r)
{
	while (l<p) p--,tot+=c[a[p]],c[a[p]]++;
	while (r>q) q++,tot+=c[a[q]],c[a[q]]++;
	while (p<l) c[a[p]]--,tot-=c[a[p]],p++;
	while (r<q) c[a[q]]--,tot-=c[a[q]],q--;
}
void work(int l,int r,int fl,int fr)
{
	if (fl>fr) return;
	int mid=(fl+fr)>>1,mi;
	LL mx=1LL<<60;
	for (int i=l;i<=r;i++)
	if (i<mid)
	{
		move(i+1,mid);
		if (f[i]+tot<mx) mx=f[i]+tot,mi=i;
	}
	g[mid]=mx;
	work(l,mi,fl,mid-1);
	work(mi,r,mid+1,fr);
}
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	f[0]=0;
	for (int i=1;i<=n;i++) f[i]=1LL<<60;
	while (k--)
	{
		p=1,q=0,tot=0;
		for (int i=1;i<=n;i++) c[i]=0;
		work(0,n-1,1,n);
		for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0;
	}
	cout<<f[n];
	return 0;
}


#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
int c[N],f[N],g[N],a[N];
int p,q,tot,n,k;
void move(int l,int r)
{
	while (l<p) p--,tot+=c[a[p]],c[a[p]]++;
	while (r>q) q++,tot+=c[a[q]],c[a[q]]++;
	while (p<l) c[a[p]]--,tot-=c[a[p]],p++;
	while (r<q) c[a[q]]--,tot-=c[a[q]],q--;
}
void work(int l,int r,int fl,int fr)
{
	if (fl>fr) return;
	int mid=(fl+fr)>>1,mx=1<<30,mi=0;
	for (int i=l;i<=r;i++)
	if (i<mid)
	{
		move(i+1,mid);
		if (f[i]+tot<mx) mx=f[i]+tot,mi=i;
	}
	g[mid]=mx;
	work(l,mi,fl,mid-1);
	work(mi,r,mid+1,fr);
}
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	f[0]=0;
	for (int i=1;i<=n;i++) f[i]=1<<30;
	while (k--)
	{
		p=1,q=0,tot=0;
		for (int i=1;i<=n;i++) c[i]=0;
		work(0,n-1,1,n);
		for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0;
		for (int i=1;i<=n;i++) printf("%d ",f[i]);printf("\n");
	}
	printf("%d\n",f[n]);
	return 0;
}


#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
typedef long long LL;
int c[N],a[N];
LL f[N],g[N];
int p,q,n,k;
LL tot;
void move(int l,int r)
{
	while (l<p) p--,tot+=c[a[p]],c[a[p]]++;
	while (r>q) q++,tot+=c[a[q]],c[a[q]]++;
	while (p<l) c[a[p]]--,tot-=c[a[p]],p++;
	while (r<q) c[a[q]]--,tot-=c[a[q]],q--;
}
void work(int l,int r,int fl,int fr)
{
	if (fl>fr) return;
	int mid=(fl+fr)>>1,mi;
	LL mx=1LL<<60;
	for (int i=l;i<=r;i++)
	if (i<mid)
	{
		move(i+1,mid);
		if (f[i]+tot<mx) mx=f[i]+tot,mi=i;
	}
	g[mid]=mx;
	work(l,mi,fl,mid-1);
	work(mi,r,mid+1,fr);
}
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	f[0]=0;
	for (int i=1;i<=n;i++) f[i]=1LL<<60;
	while (k--)
	{
		p=1,q=0,tot=0;
		for (int i=1;i<=n;i++) c[i]=0;
		work(0,n-1,1,n);
		for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0;
	}
	cout<<f[n];
	return 0;
}


#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
int c[N],f[N],g[N],a[N];
int p,q,tot,n,k;
void move(int l,int r)
{
	while (l<p) p--,tot+=c[a[p]],c[a[p]]++;
	while (r>q) q++,tot+=c[a[q]],c[a[q]]++;
	while (p<l) c[a[p]]--,tot-=c[a[p]],p++;
	while (r<q) c[a[q]]--,tot-=c[a[q]],q--;
}
void work(int l,int r,int fl,int fr)
{
	if (fl>fr) return;
	int mid=(fl+fr)>>1,mx=1<<30,mi=0;
	for (int i=l;i<=r;i++)
	if (i<mid)
	{
		move(i+1,mid);
		if (f[i]+tot<mx) mx=f[i]+tot,mi=i;
	}
	g[mid]=mx;
	work(l,mi,fl,mid-1);
	work(mi,r,mid+1,fr);
}
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	f[0]=0;
	for (int i=1;i<=n;i++) f[i]=1<<30;
	while (k--)
	{
		p=1,q=0,tot=0;
		for (int i=1;i<=n;i++) c[i]=0;
		work(0,n-1,1,n);
		for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0;
	}
	printf("%d\n",f[n]);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <stack>
#include <bitset>
using namespace std;
typedef long long LL;
LL gi () {
    LL ret=0; char ch=getchar();
    while((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    char c=ch=='-'?getchar():ch;
    while(c>='0' && c<='9') ret=ret*10+c-'0',c=getchar();
    return ch=='-'?-ret:ret;
}
const int N = 100000 + 10;
int n,m,a[N],cl,cr;
LL cans,b[N],dp[2][N],*f,*g;
void add (int x) {
    cans -= b[a[x]] * (b[a[x]]-1) / 2;
    b[a[x]] += 1;
    cans += b[a[x]] * (b[a[x]]-1) / 2;
}
void del (int x) {
    cans -= b[a[x]] * (b[a[x]]-1) / 2;
    b[a[x]] -= 1;
    cans += b[a[x]] * (b[a[x]]-1) / 2;
}
void move (int l,int r) {
    while(cl>l) --cl, add(cl);
    while(cr<r) ++cr, add(cr);
    while(cl<l) del(cl), ++cl;
    while(cr>r) del(cr), --cr;
}
void solve (int l,int r,int L,int R) {
    if(l>r) return;
    int m = (l+r) >> 1, ed = min(R,m), M;
    f[m] = 1e18;
    for(int i=L;i<=ed;i+=1) {
        move(i+1,m);
        if(cans + g[i] < f[m]) f[m] = cans + g[i], M = i;
    }
    solve(l,m-1,L,M); solve(m+1,r,M,R);
}
int main () {
    n = gi(); m = gi();
    for(int i=1;i<=n;i+=1) a[i] = gi();
    f = dp[0]; g = dp[1];
    cl = cr = 1; b[a[1]] = 1; cans = 0;
    memset(f,60,sizeof dp[0]); f[0] = 0;
    for(int i=1;i<=m;i+=1) {
        swap(f,g);
        solve(1,n,0,n-1);
    }
    printf("%I64d",f[n]);
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef long long LL;
const LL LINF=1E18;
const int maxn=1E5+77;

int N,K,A[maxn],cnt[maxn];
LL dp[maxn],ne[maxn],tot;

void addNum(int v){tot+=cnt[v]++;}
void delNum(int v){tot-=--cnt[v];}

void solve(int L,int R,int l,int r){ //[l+1, L-1] in cnt
	if(L>R) return;
	int M=(L+R)>>1;
	for(int i=L;i<=M;++i) addNum(A[i]);
	LL &val=ne[M]=LINF;
	int n=0;
	for(int i=l;i<=r && i<M;++i){
		if(dp[i]+tot<val){
			val=dp[i]+tot;
			n=i;
		}
		delNum(A[i+1]);
	}
	for(int i=min(M,r+1);i>n;--i) addNum(A[i]);
	solve(M+1,R,n,r);
	for(int i=n;i>l;--i) addNum(A[i]);
	for(int i=M;i>=L;--i) delNum(A[i]);
	solve(L,M-1,l,n);
}

int main(){
	scanf("%d%d",&N,&K);
	for(int i=0;i<N;++i){
		scanf("%d",A+i);
		if(i) dp[i]=dp[i-1]+cnt[A[i]]++;
		else ++cnt[A[i]];
	}
	memset(cnt,0,sizeof(cnt));
	for(--K;K;K--){
		solve(1,N-1,0,N-2);
		for(int i=N-1;i;--i) dp[i]=ne[i];
	}
	int ans=dp[N-1];
	printf("%d\n",ans);
}


#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef long long LL;
const LL LINF=1E18;
const int maxn=1E5+77;

int N,K,A[maxn],cnt[maxn];
LL dp[maxn],ne[maxn],tot;

void addNum(int v){tot+=cnt[v]++;}
void delNum(int v){tot-=--cnt[v];}

void solve(int L,int R,int l,int r){ //[l+1, L-1] in cnt
	if(L>R) return;
	int M=(L+R)>>1;
	for(int i=L;i<=M;++i) addNum(A[i]);
	LL &val=ne[M]=LINF;
	int n=0;
	for(int i=l;i<=r && i<M;++i){
		if(dp[i]+tot<val){
			val=dp[i]+tot;
			n=i;
		}
		delNum(A[i+1]);
	}
	for(int i=min(M,r+1);i>n;--i) addNum(A[i]);
	solve(M+1,R,n,r);
	for(int i=n;i>l;--i) addNum(A[i]);
	for(int i=M;i>=L;--i) delNum(A[i]);
	solve(L,M-1,l,n);
}

int main(){
	scanf("%d%d",&N,&K);
	for(int i=0;i<N;++i){
		scanf("%d",A+i);
		if(i) dp[i]=dp[i-1]+cnt[A[i]]++;
		else ++cnt[A[i]];
	}
	memset(cnt,0,sizeof(cnt));
	for(--K;K;K--){
		solve(1,N-1,0,N-2);
		for(int i=N-1;i;--i) dp[i]=ne[i];
	}
	printf("%I64d\n",dp[N-1]);
}


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

const int K = 22;
const int N = 100005;

int n, k;
int a[N], cnt[N];
long long dp[K][N];

int l = 1, r = 0;
long long cur_cost = 0;

long long get_cost(int x, int y) {
    while (r < y) {
        r++;
        cur_cost += cnt[a[r]];
        cnt[a[r]]++;
    }

    while (r > y) {
        cnt[a[r]]--;
        cur_cost -= cnt[a[r]];
        r--;
    }

    while (l < x) {
        cnt[a[l]]--;
        cur_cost -= cnt[a[l]];
        l++;
    }

    while (l > x) {
        l--;
        cur_cost += cnt[a[l]];
        cnt[a[l]]++;
    }

    return cur_cost;
}

void solve(int k, int l, int r, int optL, int optR) {
    if (l > r) return;
    int mid = l + r >> 1;
    int opt = -1;

    for (int i = optL; i <= min(mid, optR); i++) {
        long long cost = get_cost(i, mid) + dp[k - 1][i - 1];
        if (cost < dp[k][mid]) {
            dp[k][mid] = cost;
            opt = i;
        }
    }

    solve(k, l, mid - 1, optL, opt);
    solve(k, mid + 1, r, opt, optR);
}

int main() {
    scanf("%d %d", &n, &k);
    for (int i = 1; i <= n; i++)
        scanf("%d", a + i);

    for (int j = 0; j <= k; j++)
        for (int i = 1; i <= n; i++)
            dp[j][i] = LLONG_MAX >> 1;

    dp[0][0] = 0;
    for (int i = 1; i <= k; i++)
        solve(i, i, n, 1, n);

    printf ("%lld\n", dp[k][n]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=100005;
const ll inf =1e15;

ll n,m,p=0;
ll f[2][maxn];
ll a[maxn],c[maxn];

void slove(ll l,ll r,ll L,ll R,ll s)
{
	if(l>r) return;
	ll mid=(l+r)>>1,x=0;
	for(ll i=l;i<=mid;i++) s+=c[a[i]]++;
	for(ll i=L;i<=R&&i<=mid;i++)
	{
		s-=--c[a[i]];
		if(s+f[p^1][i]<f[p][mid]) x=i,f[p][mid]=s+f[p^1][i];
	}
	for(ll i=L;i<=R&&i<=mid;i++) s+=c[a[i]]++;
	for(ll i=l;i<=mid;i++) s-=--c[a[i]];
	slove(l,mid-1,L,x,s);
	for(ll i=L;i<x;i++) s-=--c[a[i]];
	for(ll i=l;i<=mid;i++) s+=c[a[i]]++;
	slove(mid+1,r,x,R,s);
	for(ll i=L;i<x;i++) c[a[i]]++;
	for(ll i=l;i<=mid;i++) --c[a[i]];
}

int main()
{
	memset(c,0,sizeof(c));
	scanf("%I64d%I64d",&n,&m);
	for(ll i=1;i<=n;i++) scanf("%I64d",&a[i]);
	for(ll i=1;i<=n;i++)
	{
		f[1][i]=f[1][i-1]+c[a[i]];
		c[a[i]]++;
	}
	while(--m)
	{
		memset(c,0,sizeof(c));
		for(ll i=1;i<=n;i++) f[p][i]=inf;
		slove(1,n,1,n,0);
		p^=1;
	}
	printf("%I64d\n",f[p^1][n]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
int n,A[M],cnt[M];
long long dp[25][M];
void solve(int l,int r,int L,int R,int K,long long sum) {
	if(l>r)return;
	int mid=l+r>>1,pos=-1;
	for(int i=l; i<=mid; i++) {
		sum+=cnt[A[i]];
		cnt[A[i]]++;
	}
	//printf("sum=%lld\n",sum);
	int p=min(mid,R);
	for(int i=L; i<=p; i++) {
		cnt[A[i]]--;
		sum-=cnt[A[i]];
		if(sum+dp[K-1][i]<dp[K][mid]) {
			pos=i;
			dp[K][mid]=sum+dp[K-1][i];
		}
	}
	for(int i=l; i<=mid; i++)sum-=--cnt[A[i]];
	for(int i=L; i<=p; i++)sum+=cnt[A[i]]++;
	solve(l,mid-1,L,pos,K,sum);
	for(int i=L; i<pos; i++)sum-=--cnt[A[i]];
	for(int i=l; i<=mid; i++)sum+=cnt[A[i]]++;
	solve(mid+1,r,pos,R,K,sum);
	for(int i=L; i<pos; i++)cnt[A[i]]++;
	for(int i=l; i<=mid; i++)cnt[A[i]]--;
}
int main() {
	int K;
	scanf("%d %d",&n,&K);
	memset(dp,63,sizeof(dp));
	for(int i=1; i<=n; i++)scanf("%d",&A[i]);
	dp[1][0]=0;
	for(int i=1; i<=n; i++) {
		dp[1][i]=dp[1][i-1]+cnt[A[i]];
		cnt[A[i]]++;
	}
	for(int i=2; i<=K; i++) {
		memset(cnt,0,sizeof(cnt));
		solve(1,n,1,n,i,0);
		//printf("%d\n",i);
	}
	printf("%lld\n",dp[K][n]);
	return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1]; t=0;
                for (int j=w[i+1]-1; j>=0; j--)
                {
                    t++;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    Change(1,0,n);
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int n,k,p,a[Maxn],b[Maxn];
LL dp[22][Maxn];

void Solve(int l,int r,int Left,int Right,LL d)
{
    if (l>r) return;
//    printf("%d %d %d %d %I64d\n",l,r,Left,Right,d);
    int m=((l+r)>>1);
    LL sum=0;int w=m;
    for (int i=l; i<=m; i++) sum+=b[a[i]]++;
    for (int i=Left; i<=Right; i++) if (i<=m)
    {
        if (sum+d+dp[p-1][i-1]<dp[p][m]) dp[p][m]=sum+d+dp[p-1][i-1],w=i;
        sum-=--b[a[i]];
    } else break;
//    printf("m=%d %I64d\n",m,dp[p][m]);
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<=Right; i++) if (i<=m)  b[a[i]]++; else break;
    Solve(l,m-1,Left,w,d);
    for (int i=l; i<=m; i++) d+=b[a[i]]++;
    for (int i=Left; i<w; i++) d-=--b[a[i]];
    Solve(m+1,r,w,Right,d);
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<w; i++) b[a[i]]++;
}

int main()
{
    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        for (int i=0; i<=k; i++)
        for (int j=0; j<=n; j++) dp[i][j]=INF;
        dp[0][0]=0;
        for (p=1; p<=k; p++) Solve(1,n,1,n,0);
        printf("%I64d\n",dp[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1];
                for (int j=(sum[x]>310)?min(w[i+1]-1,20):(w[i+1]-1); j>=0; j--)
                {
                    t=w[i+1]-j;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    Change(1,0,n);
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1]; t=0;
                for (int j=w[i+1]-1; j>=0; j--)
                {
                    t++;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    if (t>20) t=INF;
                    Change(1,0,n);
                    if (t>20) break;
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int n,k,p,a[Maxn],b[Maxn];
LL dp[22][Maxn];

void Solve(int l,int r,int Left,int Right,LL d)
{
    if (l>r) return;
    int m=((l+r)>>1);
    LL sum=0;int w=0;
    for (int i=l; i<=m; i++) sum+=b[a[i]]++;
    for (int i=Left; i<=Right; i++) if (i<=m)
    {
        if (sum+d+dp[p-1][i-1]<dp[p][m]) dp[p][m]=sum+d+dp[p-1][i-1],w=i;
        sum-=--b[a[i]];
    } else break;
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<=Right; i++) if (i<=m)  b[a[i]]++; else break;
    Solve(l,m-1,Left,w,d);
    for (int i=l; i<=m; i++) d+=b[a[i]]++;
    for (int i=Left; i<w; i++) d-=--b[a[i]];
    Solve(m+1,r,w,Right,d);
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<w; i++) b[a[i]]++;
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        for (int i=0; i<=k; i++)
        for (int j=0; j<=n; j++) dp[i][j]=INF;
        dp[0][0]=0;
        for (p=1; p<=k; p++) Solve(1,n,1,n,0);
        printf("%I64d\n",dp[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int n,k,p,a[Maxn],b[Maxn];
LL dp[22][Maxn];

void Solve(int l,int r,int Left,int Right)
{
    if (l>r) return;
    int m=((l+r)>>1);
    b[a[m]]++;
    LL sum=0;int w=0;
    for (int i=m-1; i>=Left; i--)
    {
        if (i<=Right)
            if (dp[p-1][i]+sum<dp[p][m]) dp[p][m]=dp[p-1][i]+sum,w=i;
        sum+=b[a[i]]++;
    }
    for (int i=m; i>=Left; i--) b[a[i]]--;
    Solve(l,m-1,Left,w);
    Solve(m+1,r,w,Right);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        for (int i=0; i<=k; i++)
        for (int j=0; j<=n; j++) dp[i][j]=INF;
        dp[0][0]=0;
        for (p=1; p<=k; p++) Solve(1,n,0,n-1);
        printf("%I64d\n",dp[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1]; t=0;
                for (int j=w[i+1]-1; j>=0; j--)
                {
                    t++;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    Change(1,0,n);
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1];
                for (int j=(sum[x]>310)?min(w[i+1]-1,20):(w[i+1]-1); j>=0; j--)
                {
                    t=w[i+1]-j;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    Change(1,0,n);
                }
                if (sum[x]>310)
                {
                    int j=min(w[i+1]-1,20)+1;
                    if (j>=w[i+1]-1) continue;
                    L=b[x][j-1],R=b[x][j]-1; t=INF;
                    Change(1,0,n);
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1]; t=0;
                for (int j=w[i+1]-1; j>=0; j--)
                {
                    t++;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    if (t>40) t=INF;
                    Change(1,0,n);
                    if (t>40) break;
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int n,k,p,a[Maxn],b[Maxn];
LL dp[22][Maxn];

void Solve(int l,int r,int Left,int Right,LL d)
{
    if (l>r) return;
//    printf("%d %d %d %d %I64d\n",l,r,Left,Right,d);
    int m=((l+r)>>1);
    LL sum=0;int w=m;
    for (int i=l; i<=m; i++) sum+=b[a[i]]++;
    for (int i=Left; i<=Right; i++) if (i<=m)
    {
        if (sum+d+dp[p-1][i-1]<dp[p][m]) dp[p][m]=sum+d+dp[p-1][i-1],w=i;
        sum-=--b[a[i]];
    } else break;
//    printf("m=%d %I64d\n",m,dp[p][m]);
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<=Right; i++) if (i<=m)  b[a[i]]++; else break;
    Solve(l,m-1,Left,w,d);
    for (int i=l; i<=m; i++) d+=b[a[i]]++;
    for (int i=Left; i<w; i++) d-=--b[a[i]];
    Solve(m+1,r,w,Right,d);
    for (int i=l; i<=m; i++) b[a[i]]--;
    for (int i=Left; i<w; i++) b[a[i]]++;
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        for (int i=0; i<=k; i++)
        for (int j=0; j<=n; j++) dp[i][j]=INF;
        dp[0][0]=0;
        for (p=1; p<=k; p++) Solve(1,n,1,n,0);
        printf("%I64d\n",dp[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1]; t=0;
                for (int j=w[i+1]-1; j>=0; j--)
                {
                    t++;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    if (t>50) t=INF;
                    Change(1,0,n);
                    if (t>50) break;
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}


#include <bits/stdc++.h>
#define LL __int64

using namespace std;

const int Maxn=1e5+10;
const LL INF=1e16;
int L,R,p,n,k,a[Maxn],w[Maxn],sum[Maxn];
LL f[22][Maxn],t;
vector<int> b[Maxn];
struct TT
{
    LL x,dx;
}tree[Maxn*4];

void Build(int num,int Left,int Right)
{
    tree[num].x=tree[num].dx=0;
    if (Left==Right)
    {
        tree[num].x=f[p-1][Left];
        return;
    }
    int Mid=((Left+Right)>>1);
    Build(num<<1,Left,Mid);
    Build((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Updata(int num,int Left,int Right)
{
    tree[num].x+=tree[num].dx;
    if (Left!=Right)
    {
    	tree[(num<<1)].dx+=tree[num].dx;
    	tree[(num<<1)|1].dx+=tree[num].dx;
    }
    tree[num].dx=0;
}

void Change(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        tree[num].dx+=t;
        Updata(num,Left,Right);
        return;
    }
    int Mid=((Left+Right)>>1);
    Change(num<<1,Left,Mid);
    Change((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

void Ask(int num,int Left,int Right)
{
    if (L>R) return;
    if (Left>Right) return;
    if (tree[num].dx!=0) Updata(num,Left,Right);
    if (L>Right || R<Left) return;
    if (Left>=L && Right<=R)
    {
        t=min(t,tree[num].x);
        return;
    }
    int Mid=((Left+Right)>>1);
    Ask(num<<1,Left,Mid);
    Ask((num<<1)|1,Mid+1,Right);
    tree[num].x=min(tree[num<<1].x,tree[(num<<1)|1].x);
}

int main()
{
//    freopen("f.in","r",stdin);
    for ( ; scanf("%d%d",&n,&k)!=EOF; )
    {
        for (int i=1; i<=n; i++) b[i].clear(),sum[i]=0;
        for (int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            w[i]=sum[a[i]]++;
            b[a[i]].push_back(i);
        }
        for (int i=0; i<=n; i++) f[0][i]=INF;
        f[0][0]=0;
        for (p=1; p<=k; p++)
        {
            Build(1,0,n);
            for (int i=1; i<=n; i++)
            {
                L=0,R=i-1,t=INF;
                Ask(1,0,n);
                f[p][i]=t;
                int x=a[i+1];
                for (int j=(sum[x]>310)?min(w[i+1]-1,30):(w[i+1]-1); j>=0; j--)
                {
                    t=w[i+1]-j;
                    if (j==0) L=0,R=b[x][j]-1; else L=b[x][j-1],R=b[x][j]-1;
//                    printf("%d %d %d %I64d\n",j,L,R,t);
                    Change(1,0,n);
                }
                if (sum[x]>310)
                {
                    int j=min(w[i+1]-1,30)+1;
                    if (j>=w[i+1]-1) continue;
                    L=b[x][j-1],R=b[x][j]-1; t=INF;
                    Change(1,0,n);
                }
            }
        }
        printf("%I64d\n",f[k][n]);
    }
    return 0;
}