#include <bits/stdc++.h>
using namespace std;
long long tree[500010], a[500010], lazy[500010], n, k, pre[500010], pos[500010],
    f[35001][51];
void build(int left, int right, int p, int now) {
  lazy[p] = 0;
  if (left == right) {
    tree[p] = f[now][left - 1];
    return;
  }
  int mid = (left + right) >> 1;
  build(left, mid, p * 2, now);
  build(mid + 1, right, p * 2 + 1, now);
  tree[p] = max(tree[p * 2], tree[p * 2 + 1]);
}
void down(int p, int left, int right) {
  int mid = (left + right) >> 1;
  long long l = lazy[p];
  lazy[p * 2] += l;
  lazy[p * 2 + 1] += l;
  tree[p * 2] += l;
  tree[p * 2 + 1] += l;
  lazy[p] = 0;
}
void update(int left, int right, int ql, int qr, int p, long long c) {
  if (left >= ql && right <= qr) {
    lazy[p] += c;
    tree[p] += c;
    return;
  }
  if (qr < left || ql > right) {
    return;
  }
  down(p, left, right);
  int mid = (right + left) >> 1;
  update(left, mid, ql, qr, p * 2, c);
  update(mid + 1, right, ql, qr, p * 2 + 1, c);
  tree[p] = max(tree[p * 2], tree[p * 2 + 1]);
}
long long query(int left, int right, int ql, int qr, int p) {
  if (left >= ql && right <= qr) {
    return tree[p];
  }
  if (left > qr || right < ql) {
    return 0;
  }
  int mid = (right + left) >> 1;
  down(p, left, right);
  return max(query(left, mid, ql, qr, p * 2),
             query(mid + 1, right, ql, qr, p * 2 + 1));
}
int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    pre[i] = pos[a[i]] + 1;
    pos[a[i]] = i;
  }
  for (int i = 1; i <= k; i++) {
    build(1, n, 1, i - 1);
    for (int j = 1; j <= n; j++) {
      update(1, n, pre[j], j, 1, 1);
      f[i][j] = query(1, n, i, j, 1);
    }
  }
  cout << f[k][n];
  return 0;
}
