#include <bits/stdc++.h>
using namespace std;
const int N = 36001;
const int K = 55;
const int M = 4 * N;
const int Inf = 1e9;
int n, k;
int a[N];
int Next[N];
int Dp[N][K];
int SegTree[M];
int Lazy[M];
void Merge(int Node) {
  SegTree[Node] = max(SegTree[(2 * Node)], SegTree[(2 * Node + 1)]);
}
void Push_Lazy(int Node) {
  SegTree[Node] += Lazy[Node];
  if ((2 * Node) < M) Lazy[(2 * Node)] += Lazy[Node];
  if ((2 * Node + 1) < M) Lazy[(2 * Node + 1)] += Lazy[Node];
  Lazy[Node] = 0;
}
void Build(int j, int Node = 1, int L = 0, int R = n) {
  if (L == R) {
    SegTree[Node] = Dp[j][L];
    return;
  }
  Build(j, (2 * Node), L, ((L + R) / 2));
  Build(j, (2 * Node + 1), ((L + R) / 2) + 1, R);
  Merge(Node);
}
void Update(int i, int j, int v = 1, int Node = 1, int L = 0, int R = n) {
  Push_Lazy(Node);
  if (i > R || L > j) return;
  if (i <= L && R <= j) {
    Lazy[Node] += v;
    Push_Lazy(Node);
    return;
  }
  Update(i, j, v, (2 * Node), L, ((L + R) / 2));
  Update(i, j, v, (2 * Node + 1), ((L + R) / 2) + 1, R);
  Merge(Node);
}
int Query(int i, int j, int Node = 1, int L = 0, int R = n) {
  Push_Lazy(Node);
  if (i > R || L > j) return -Inf;
  if (i <= L && R <= j) return SegTree[Node];
  return max(Query(i, j, (2 * Node), L, ((L + R) / 2)),
             Query(i, j, (2 * Node + 1), ((L + R) / 2) + 1, R));
}
int main() {
  cin >> n >> k;
  for (int i = 0; i < n; i++) scanf("%d", a + i);
  Dp[0][n] = 0;
  for (int i = 0; i < n; i++) Dp[0][i] = -Inf;
  for (int j = 1; j <= k; j++) {
    memset(SegTree, 0, sizeof(SegTree));
    memset(Lazy, 0, sizeof(Lazy));
    Build(j - 1);
    for (int i = 1; i <= n; i++) Next[i] = n;
    Dp[j][n] = -Inf;
    for (int i = n - 1; ~i; --i) {
      Update(i + 1, Next[a[i]]);
      Next[a[i]] = i;
      Dp[j][i] = Query(i + 1, n);
    }
  }
  cout << Dp[k][0];
}
