#include <bits/stdc++.h>
using namespace std;
int num[35005], dp[55][35005], pre[35005], id[35005];
struct Node {
  int l, r, lazy, mx;
} tr[35005 << 2];
void pushUp(int rt) { tr[rt].mx = max(tr[rt << 1].mx, tr[rt << 1 | 1].mx); }
void build(int l, int r, int rt) {
  tr[rt] = {l, r, 0, 0};
  if (l != r) {
    int mid = l + r >> 1;
    build(l, mid, rt << 1);
    build(mid + 1, r, rt << 1 | 1);
  }
}
void pushDown(int rt) {
  tr[rt << 1].lazy += tr[rt].lazy;
  tr[rt << 1].mx += tr[rt].lazy;
  tr[rt << 1 | 1].lazy += tr[rt].lazy;
  tr[rt << 1 | 1].mx += tr[rt].lazy;
  tr[rt].lazy = 0;
}
void change(int l, int r, int rt, int add) {
  int mid = tr[rt].l + tr[rt].r >> 1;
  if (l == tr[rt].l && r == tr[rt].r) {
    tr[rt].mx += add;
    tr[rt].lazy += add;
  } else {
    pushDown(rt);
    if (mid >= r) {
      change(l, r, rt << 1, add);
    } else if (mid < l) {
      change(l, r, rt << 1 | 1, add);
    } else {
      change(l, mid, rt << 1, add);
      change(mid + 1, r, rt << 1 | 1, add);
    }
    pushUp(rt);
  }
}
int query(int l, int r, int rt) {
  if (l == tr[rt].l && r == tr[rt].r) return tr[rt].mx;
  pushDown(rt);
  int mid = tr[rt].l + tr[rt].r >> 1;
  if (mid >= r)
    return query(l, r, rt << 1);
  else if (mid < l)
    return query(l, r, rt << 1 | 1);
  else
    return max(query(l, mid, rt << 1), query(mid + 1, r, rt << 1 | 1));
}
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &num[i]);
    pre[i] = id[num[i]];
    id[num[i]] = i;
  }
  for (int i = 1; i <= k; i++) {
    build(i - 1, n, 1);
    for (int j = i - 1; j <= n; j++) {
      change(j, j, 1, dp[i - 1][j]);
    }
    for (int j = i; j <= n; j++) {
      change(max(pre[j], i - 1), j - 1, 1, 1);
      dp[i][j] = query(i - 1, j - 1, 1);
    }
  }
  printf("%d\n", dp[k][n]);
}
