#include <bits/stdc++.h>
using namespace std;
int n, k, a[35005], tp;
int f[35005][55], last[35005], pre[35005];
struct ST {
  struct node {
    int maxl, lazy;
  } t[35005 * 5];
  void up(int rt) { t[rt].maxl = max(t[rt << 1].maxl, t[(rt << 1) | 1].maxl); }
  void push_down(int rt) {
    if (!t[rt].lazy) return;
    t[rt << 1].lazy += t[rt].lazy;
    t[rt << 1].maxl += t[rt].lazy;
    t[(rt << 1) | 1].lazy += t[rt].lazy;
    t[(rt << 1) | 1].maxl += t[rt].lazy;
    t[rt].lazy = 0;
  }
  void build(int rt, int l, int r) {
    t[rt].lazy = 0;
    if (l == r) {
      t[rt].maxl = f[l - 1][tp - 1];
      return;
    }
    int mid = (l + r) >> 1;
    build(rt << 1, l, mid);
    build((rt << 1) | 1, mid + 1, r);
    up(rt);
  }
  void update(int rt, int l, int r, int x, int y, int z) {
    if (r < x || l > y) return;
    if (x <= l && r <= y) {
      t[rt].maxl += z;
      t[rt].lazy += z;
      return;
    }
    push_down(rt);
    int mid = (l + r) >> 1;
    update(rt << 1, l, mid, x, y, z);
    update((rt << 1) | 1, mid + 1, r, x, y, z);
    up(rt);
  }
  int que(int rt, int l, int r, int x, int y) {
    if (r < x || l > y) return -0x3f3f3f3f;
    if (x <= l && r <= y) return t[rt].maxl;
    push_down(rt);
    int mid = (l + r) >> 1, zz = -0x3f3f3f3f;
    zz = max(zz, que(rt << 1, l, mid, x, y));
    zz = max(zz, que((rt << 1) | 1, mid + 1, r, x, y));
    return zz;
  }
} T;
void init() {
  memset(f, -0x3f, sizeof(f));
  cin >> n >> k;
  for (int i = 0; i <= n; i++) f[i][0] = 0;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    pre[i] = last[a[i]] + 1;
    last[a[i]] = i;
  }
  for (int p = 1; p <= k; p++) {
    tp = p;
    T.build(1, 1, n);
    for (int i = 0; i <= n; i++) {
      T.update(1, 1, n, pre[i], i, 1);
      f[i][p] = T.que(1, 1, n, 1, i);
    }
  }
  cout << f[n][k] << endl;
}
int main() { init(); }
