#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T gcd(T a, T b) {
  return (b) == 0 ? (a) : gcd((b), ((a) % (b)));
}
template <class T>
inline T lcm(T a, T b) {
  return ((a) / gcd((a), (b)) * (b));
}
template <class T>
inline T BigMod(T Base, T power, T M = 1000000007) {
  if (power == 0) return 1;
  if (power & 1)
    return ((Base % M) * (BigMod(Base, power - 1, M) % M)) % M;
  else {
    T y = BigMod(Base, power / 2, M) % M;
    return (y * y) % M;
  }
}
template <class T>
inline T ModInv(T A, T M = 1000000007) {
  return BigMod(A, M - 2, M);
}
int fx[] = {-1, +0, +1, +0, +1, +1, -1, -1, +0};
int fy[] = {+0, -1, +0, +1, +1, -1, +1, -1, +0};
int day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int n, k;
int dp[400005][51];
int arr[400005];
long long W[400005], cst[400005];
vector<int> indx[400005];
int nxt[400005], petu[400005];
struct node {
  node *left, *right;
  int sum;
  node() {
    sum = 0;
    left = right = NULL;
  }
} * root[400005];
node *Build(int b, int e) {
  if (b == e) {
    node *ret = new node();
    return ret;
  }
  int mid = (b + e) >> 1;
  node *ret = new node();
  ret->left = Build(b, mid);
  ret->right = Build(mid + 1, e);
  ret->sum = ret->left->sum + ret->right->sum;
  return ret;
}
node *update(node *ptr, int b, int e, int indx, int val) {
  if (b > indx || indx > e) return ptr;
  if (b == e) {
    node *ret = new node();
    ret->sum = ptr->sum + val;
    return ret;
  }
  int mid = (b + e) >> 1;
  node *ret = new node();
  ret->left = update(ptr->left, b, mid, indx, val);
  ret->right = update(ptr->right, mid + 1, e, indx, val);
  ret->sum = ret->left->sum + ret->right->sum;
  return ret;
}
int query(node *ptr, int b, int e, int l, int r) {
  if (b > r || l > e) return 0;
  if (b >= l && e <= r) return ptr->sum;
  int mid = (b + e) >> 1;
  return query(ptr->left, b, mid, l, r) + query(ptr->right, mid + 1, e, l, r);
}
int cost(int i, int j) { return query(root[j], 1, n, i, j); }
void giveres(int gr, int b, int e, int optl, int optr) {
  if (b > e) return;
  int mid = (b + e) >> 1, best = -1;
  int cc = cost(optl + 1, mid);
  for (int i = optl; i <= min(optr, mid); i++) {
    long long xx = dp[i][gr - 1] + cc;
    if (nxt[i + 1] > mid) cc--;
    if (xx > dp[mid][gr]) {
      dp[mid][gr] = xx;
      best = i;
    }
  }
  giveres(gr, b, mid - 1, optl, best);
  giveres(gr, mid + 1, e, best, optr);
}
int main() {
  scanf("%d", &n), scanf("%d", &k);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
  }
  for (int i = n; i >= 1; i--) {
    if (petu[arr[i]] == 0)
      nxt[i] = n + 1;
    else
      nxt[i] = petu[arr[i]];
    petu[arr[i]] = i;
  }
  for (int i = 0; i <= n; i++)
    for (int j = 0; j <= k; j++) dp[i][j] = -1e9;
  root[0] = Build(1, n);
  for (int i = 1; i <= n; i++) {
    root[i] = update(root[i - 1], 1, n, i, 1);
    if (indx[arr[i]].size()) {
      root[i] = update(root[i], 1, n, indx[arr[i]][0], -1);
      indx[arr[i]].pop_back();
    }
    indx[arr[i]].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    dp[i][1] = cost(1, i);
  }
  for (int i = 2; i <= k; i++) giveres(i, 1, n, 1, n);
  printf("%d", dp[n][k]);
  return 0;
}
