#include <bits/stdc++.h>
const int N = 305005;
int n, k;
int pre[N], lst[N], dp[N];
int mx[N << 3], lz[N << 3];
inline int RD() {
  int m = 0, k = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-') k = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    m = (m << 1) + (m << 3) + ch - 48;
  return k * m;
}
void upd(int rt) {
  mx[rt] =
      ((mx[rt << 1]) > (mx[rt << 1 | 1]) ? (mx[rt << 1]) : (mx[rt << 1 | 1]));
}
void pushdown(int rt) {
  if (lz[rt]) {
    lz[rt << 1] += lz[rt];
    lz[rt << 1 | 1] += lz[rt];
    mx[rt << 1] += lz[rt];
    mx[rt << 1 | 1] += lz[rt];
    lz[rt] = 0;
  }
}
void buildtree(int rt = 1, int l = 1, int r = n) {
  lz[rt] = 0;
  if (l == r) {
    mx[rt] = dp[l];
    return;
  }
  int mid = (l + r) >> 1;
  buildtree(rt << 1, l, mid);
  buildtree(rt << 1 | 1, mid + 1, r);
  upd(rt);
}
void update(int L, int R, int dlt, int rt = 1, int l = 1, int r = n) {
  if (R <= 0) return;
  if (L <= 0) L = 1;
  if (L <= l && r <= R) {
    mx[rt] += dlt;
    lz[rt] += dlt;
    return;
  }
  pushdown(rt);
  int mid = (l + r) >> 1;
  if (L <= mid) update(L, R, dlt, rt << 1, l, mid);
  if (R > mid) update(L, R, dlt, rt << 1 | 1, mid + 1, r);
  upd(rt);
}
int query(int L, int R, int rt = 1, int l = 1, int r = n) {
  if (R <= 0) return 0;
  if (L <= 0) L = 1;
  if (L <= l && r <= R) return mx[rt];
  pushdown(rt);
  int ret, ret1 = 0, ret2 = 0, mid = (l + r) >> 1;
  if (L <= mid) ret1 = query(L, R, rt << 1, l, mid);
  if (R > mid) ret2 = query(L, R, rt << 1 | 1, mid + 1, r);
  ret = ((ret1) > (ret2) ? (ret1) : (ret2));
  upd(rt);
  return ret;
}
int main() {
  n = RD();
  k = RD();
  for (int val, i = 1; i <= n; i++) {
    val = RD();
    pre[i] = lst[val];
    lst[val] = i;
    dp[i] = dp[i - 1] + (pre[i] == 0);
  }
  buildtree();
  while (--k) {
    for (int i = 2; i <= n; i++) {
      update(pre[i], i - 1, 1);
      dp[i] = query(1, i - 1);
    }
    buildtree();
  }
  printf("%d\n", dp[n]);
  return 0;
}
