#include <bits/stdc++.h>
using namespace std;
const int N = 35005;
int head[N], pre[N];
int dp[N];
int n, k;
struct Tree {
  int left, right;
  int lz, val;
} tree[N << 2];
void build(int i, int l, int r) {
  tree[i].left = l;
  tree[i].right = r;
  tree[i].lz = 0;
  if (l == r) {
    tree[i].val = dp[l - 1];
    return;
  }
  int mid = (l + r) >> 1;
  build(i << 1, l, mid);
  build(i << 1 | 1, mid + 1, r);
  tree[i].val = max(tree[i << 1].val, tree[i << 1 | 1].val);
}
void update(int i, int l, int r) {
  if (tree[i].left == l && tree[i].right == r) {
    tree[i].val++;
    tree[i].lz++;
    return;
  }
  if (tree[i].lz > 0) {
    tree[i << 1].lz += tree[i].lz;
    tree[i << 1 | 1].lz += tree[i].lz;
    tree[i << 1].val += tree[i].lz;
    tree[i << 1 | 1].val += tree[i].lz;
    tree[i].lz = 0;
  }
  int mid = (tree[i].left + tree[i].right) >> 1;
  if (mid >= r)
    update(i << 1, l, r);
  else if (mid < l)
    update(i << 1 | 1, l, r);
  else {
    update(i << 1, l, mid);
    update(i << 1 | 1, mid + 1, r);
  }
  tree[i].val = max(tree[i << 1].val, tree[i << 1 | 1].val);
}
int query(int i, int l, int r) {
  if (tree[i].left == l && tree[i].right == r) return tree[i].val;
  if (tree[i].lz > 0) {
    tree[i << 1].lz += tree[i].lz;
    tree[i << 1 | 1].lz += tree[i].lz;
    tree[i << 1].val += tree[i].lz;
    tree[i << 1 | 1].val += tree[i].lz;
    tree[i].lz = 0;
  }
  int mid = (tree[i].left + tree[i].right) >> 1;
  if (mid >= r)
    return query(i << 1, l, r);
  else if (mid < l)
    return query(i << 1 | 1, l, r);
  else
    return max(query(i << 1, l, mid), query(i << 1 | 1, mid + 1, r));
}
int main() {
  int a;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a);
    pre[i] = head[a];
    head[a] = i;
  }
  for (int i = 1; i <= k; i++) {
    build(1, 1, n);
    for (int j = 1; j <= n; j++) {
      update(1, pre[j] + 1, j);
      dp[j] = query(1, 1, j);
    }
  }
  printf("%d\n", dp[n]);
  return 0;
}
