#include <bits/stdc++.h>
using namespace std;
const int MAXN = 35005;
const int MAXK = 55;
int n, k;
int a[MAXN];
int tree[MAXN * 4];
int lazy[MAXN * 4];
int dp[MAXK][MAXN];
int pre[MAXN];
int pos[MAXN];
void PushUp(int rt) { tree[rt] = max(tree[rt * 2], tree[rt * 2 + 1]); }
void PushDown(int rt) {
  tree[rt * 2] += lazy[rt];
  tree[rt * 2 + 1] += lazy[rt];
  lazy[rt * 2] += lazy[rt];
  lazy[rt * 2 + 1] += lazy[rt];
  lazy[rt] = 0;
  return;
}
void Build(int pos, int l, int r, int rt) {
  lazy[rt] = 0;
  if (l == r) {
    tree[rt] = dp[pos][l - 1];
    return;
  }
  int m = (l + r) / 2;
  Build(pos, l, m, rt * 2);
  Build(pos, m + 1, r, rt * 2 + 1);
  PushUp(rt);
}
void Update(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r) {
    lazy[rt]++;
    tree[rt]++;
    return;
  }
  PushDown(rt);
  int m = (l + r) / 2;
  if (L <= m) Update(L, R, l, m, rt * 2);
  if (R > m) Update(L, R, m + 1, r, rt * 2 + 1);
  PushUp(rt);
}
int Query(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r) {
    return tree[rt];
  }
  int ans = 0;
  PushDown(rt);
  int m = (l + r) / 2;
  if (L <= m) ans = max(ans, Query(L, R, l, m, rt * 2));
  if (R > m) ans = max(ans, Query(L, R, m + 1, r, rt * 2 + 1));
  PushUp(rt);
  return ans;
}
void Work() {
  for (int i = 1; i <= k; i++) {
    Build(i - 1, 1, n, 1);
    for (int j = 1; j <= n; j++) {
      Update(pre[j] + 1, j, 1, n, 1);
      dp[i][j] = Query(i - 1, j, 1, n, 1);
    }
  }
  cout << dp[k][n] << endl;
}
int main() {
  while (scanf("%d%d", &n, &k) != EOF) {
    memset(pre, 0, sizeof(pre));
    memset(pos, 0, sizeof(pos));
    memset(tree, 0, sizeof(tree));
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
      pre[i] = pos[a[i]];
      pos[a[i]] = i;
    }
    Work();
  }
  return 0;
}
