#include <bits/stdc++.h>
using namespace std;
struct Segment_Tree {
  int l, r, mx, tag;
} t[140005];
int pos[35005], pre[35005], f[35005];
inline void pushup(int p) {
  t[p].mx =
      ((t[((p) << 1)].mx) > (t[((p) << 1 | 1)].mx) ? t[((p) << 1)].mx
                                                   : t[((p) << 1 | 1)].mx);
}
inline void pushdown(int p) {
  if (t[p].tag) {
    t[((p) << 1)].mx += t[p].tag;
    t[((p) << 1 | 1)].mx += t[p].tag;
    t[((p) << 1)].tag += t[p].tag;
    t[((p) << 1 | 1)].tag += t[p].tag;
    t[p].tag = 0;
  }
}
int ask(int p, int x, int y) {
  if (x <= t[p].l && t[p].r <= y) return t[p].mx;
  int ret = 0, tmp;
  pushdown(p);
  if (t[((p) << 1)].r >= x) ret = ask(((p) << 1), x, y);
  if (t[((p) << 1 | 1)].l <= y)
    tmp = ask(((p) << 1 | 1), x, y), ret = ((tmp) > (ret) ? tmp : ret);
  return ret;
}
void change(int p, int x, int y, int z) {
  if (x <= t[p].l && t[p].r <= y) {
    t[p].mx += z;
    t[p].tag += z;
    return;
  }
  pushdown(p);
  if (t[((p) << 1)].r >= x) change(((p) << 1), x, y, z);
  if (t[((p) << 1 | 1)].l <= y) change(((p) << 1 | 1), x, y, z);
  pushup(p);
}
void build(int p, int l, int r) {
  t[p].l = l;
  t[p].r = r;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(((p) << 1), l, mid), build(((p) << 1 | 1), mid + 1, r);
}
int main() {
  int n, k, i, a, j;
  scanf("%d%d", &n, &k);
  for (i = 1; i <= (n); i++) {
    scanf("%d", &a);
    pre[i] = pos[a] + 1;
    pos[a] = i;
  }
  build(1, 1, n + 1);
  for (j = 1; j <= (k); j++) {
    for (i = 2; i <= (n + 1); i++)
      change(1, pre[i - 1], i - 1, 1), f[i] = ask(1, 1, i - 1);
    for (i = 1; i <= (n + 1); i++) change(1, i, i, f[i] - ask(1, i, i));
  }
  printf("%d", f[n + 1]);
  return 0;
}
