#include <bits/stdc++.h>
using namespace std;
const int maxn = 35000 + 5;
int dp[55][maxn];
int ls[maxn];
int last[maxn];
int n, k;
int arr[maxn];
inline int L(int l) { return l << 1; }
inline int R(int r) { return (r << 1) + 1; }
inline int MID(int l, int r) { return (l + r) >> 1; }
typedef struct {
  int mx;
  int lazy;
} node;
node t[maxn * 5];
void pushup(int root) { t[root].mx = max(t[L(root)].mx, t[R(root)].mx); }
void pushdown(int root, int l, int r) {
  if (l == r) return;
  if (t[root].lazy) {
    int tmp = t[root].lazy;
    t[L(root)].mx += tmp;
    t[R(root)].mx += tmp;
    t[L(root)].lazy += tmp;
    t[R(root)].lazy += tmp;
    t[root].lazy = 0;
  }
}
void build(int d, int l, int r, int now) {
  t[d].lazy = 0;
  if (l == r) {
    t[d].mx = dp[now][l - 1];
    return;
  }
  int mid = MID(l, r);
  build(L(d), l, mid, now);
  build(R(d), mid + 1, r, now);
  pushup(d);
}
void ins(int d, int l, int r, int x, int y, int z) {
  if (x > y) return;
  pushdown(d, l, r);
  if (l == x && r == y) {
    t[d].mx += z;
    t[d].lazy += z;
    return;
  }
  int mid = MID(l, r);
  ins(L(d), l, mid, x, min(y, mid), z);
  ins(R(d), mid + 1, r, max(x, mid + 1), y, z);
  pushup(d);
}
int query(int d, int l, int r, int x, int y) {
  if (x > y) return 0;
  pushdown(d, l, r);
  if (l == x && r == y) return t[d].mx;
  int mid = MID(l, r);
  return max(query(L(d), l, mid, x, min(y, mid)),
             query(R(d), mid + 1, r, max(x, mid + 1), y));
}
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
    ls[i] = last[arr[i]];
    last[arr[i]] = i;
  }
  for (int i = 1; i <= k; i++) {
    build(1, 1, n, i - 1);
    for (int j = 1; j <= n; j++) {
      ins(1, 1, n, ls[j] + 1, j, 1);
      dp[i][j] = query(1, 1, n, 1, j);
    }
  }
  printf("%d", dp[k][n]);
  return 0;
}
