#include <bits/stdc++.h>
using namespace std;
const int N = 35000 + 10, K = 50 + 10;
int n, k;
int a[N];
namespace TwoPointers {
int state = 0, l = 0, r = -1;
int cnt[N];
void add(int i, bool right) {
  if (cnt[a[i]]++ == 0) state++;
}
void remove(int i, bool right) {
  if (--cnt[a[i]] == 0) state--;
}
int query(int ql, int qr) {
  while (l > ql) add(--l, 0);
  while (r < qr) add(++r, 1);
  while (l < ql) remove(l++, 0);
  while (r > qr) remove(r--, 1);
  return state;
}
}  // namespace TwoPointers
namespace DivideAndConquer {
bool pre, cur;
long long dp[2][N];
inline long long cost(int l, int r) { return TwoPointers::query(l, r); }
void solve(int l, int r, int pl, int pr) {
  if (r < l) return;
  int m = l + r >> 1;
  pair<long long, int> opt;
  opt.first = numeric_limits<long long>::min();
  for (int i = pl; i <= pr; i++) {
    if (i > m) break;
    opt = max(opt, {dp[pre][i - 1] + cost(i, m), i});
  }
  dp[cur][m] = opt.first;
  solve(l, m - 1, pl, opt.second);
  solve(m + 1, r, opt.second, pr);
}
long long solve(int n, int k) {
  cur = 0, pre = 1;
  for (int i = 0; i < n; i++) dp[cur][i] = cost(0, i);
  for (int i = 1; i < k; i++) {
    swap(cur, pre);
    solve(i, n - 1, i, n - 1);
  }
  return dp[cur][n - 1];
}
}  // namespace DivideAndConquer
int main() {
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
  }
  printf("%d\n", int(DivideAndConquer::solve(n, k)));
}
