#include <bits/stdc++.h>
struct Node {
  int l, r, sum, lazy;
} tree[140010];
int dp[61][40001], pre[35001], pos[35001];
int max(int x, int y) { return x > y ? x : y; }
void init() { memset(tree, 0, sizeof(tree)); }
void push_up(int p) {
  tree[p].sum = max(tree[p << 1].sum, tree[p << 1 | 1].sum);
}
void push_down(int p) {
  tree[p << 1].sum += tree[p].lazy;
  tree[p << 1].lazy += tree[p].lazy;
  tree[p << 1 | 1].sum += tree[p].lazy;
  tree[p << 1 | 1].lazy += tree[p].lazy;
  tree[p].lazy = 0;
}
void build(int p, int l, int r, int now) {
  if (l == r) {
    tree[p].l = l;
    tree[p].r = r;
    tree[p].sum = dp[now][l - 1];
    return;
  }
  tree[p].l = l;
  tree[p].r = r;
  int mid = (l + r) >> 1;
  build(p << 1, l, mid, now);
  build(p << 1 | 1, mid + 1, r, now);
  push_up(p);
}
void update(int p, int l, int r, int val) {
  if (tree[p].l == l && tree[p].r == r) {
    tree[p].sum += val;
    tree[p].lazy += val;
    return;
  }
  if (tree[p].lazy) push_down(p);
  int mid = (tree[p].l + tree[p].r) >> 1;
  if (mid < l)
    update(p << 1 | 1, l, r, val);
  else {
    if (mid >= r)
      update(p << 1, l, r, val);
    else {
      update(p << 1, l, mid, val);
      update(p << 1 | 1, mid + 1, r, val);
    }
  }
  push_up(p);
}
int query(int p, int l, int r) {
  if (tree[p].l == l && tree[p].r == r) return tree[p].sum;
  if (tree[p].lazy) push_down(p);
  int mid = (tree[p].l + tree[p].r) >> 1;
  if (mid < l)
    return query(p << 1 | 1, l, r);
  else {
    if (mid >= r)
      return query(p << 1, l, r);
    else
      return max(query(p << 1, l, mid), query(p << 1 | 1, mid + 1, r));
  }
}
int main() {
  int n, k, t;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &t);
    pre[i] = pos[t] + 1;
    pos[t] = i;
  }
  for (int i = 1; i <= k; i++) {
    init();
    build(1, 1, n, i - 1);
    for (int j = 1; j <= n; j++) {
      update(1, pre[j], j, 1);
      dp[i][j] = query(1, 1, j);
    }
  }
  printf("%d\n", dp[k][n]);
  return 0;
}
