#include <bits/stdc++.h>
using namespace std;
struct Node {
  Node *lc, *rc;
  int mx, tag;
  Node() : lc(NULL), rc(NULL), mx(0), tag(0) {}
  void pull() { mx = max(lc->mx, rc->mx); }
};
const int K = 52;
const int N = 35006;
int k;
int dp[K][N];
Node* Build(int L, int R) {
  Node* node = new Node();
  if (L == R) {
    node->mx = dp[k - 1][L];
    return node;
  }
  int mid = (L + R) >> 1;
  node->lc = Build(L, mid);
  node->rc = Build(mid + 1, R);
  node->pull();
  return node;
}
void push(Node* node, int L, int R) {
  if (L == R) node->tag = 0;
  if (!node->tag) return;
  node->lc->mx += node->tag;
  node->rc->mx += node->tag;
  node->lc->tag += node->tag;
  node->rc->tag += node->tag;
  node->tag = 0;
  return;
}
void modify(Node* node, int L, int R, int l, int r, int val) {
  if (l > R || L > r)
    return;
  else if (l <= L && R <= r) {
    node->mx += val;
    node->tag += val;
    return;
  }
  push(node, L, R);
  int mid = (L + R) >> 1;
  modify(node->lc, L, mid, l, r, val);
  modify(node->rc, mid + 1, R, l, r, val);
  node->pull();
  return;
}
int query(Node* node, int L, int R, int l, int r) {
  if (l > R || L > r)
    return 0;
  else if (l <= L && R <= r)
    return node->mx;
  push(node, L, R);
  int mid = (L + R) >> 1;
  return max(query(node->lc, L, mid, l, r), query(node->rc, mid + 1, R, l, r));
}
int a[N];
int last[N];
int main() {
  int n, kk;
  scanf("%d %d", &n, &kk);
  for (int i = 1; n >= i; i++) {
    scanf("%d", &a[i]);
  }
  for (k = 1; kk >= k; k++) {
    Node* root = Build(0, n);
    memset(last, 0, sizeof(last));
    for (int j = 1; n >= j; j++) {
      int _ = a[j];
      modify(root, 0, n, last[_], j - 1, 1);
      dp[k][j] = query(root, 0, n, 0, j - 1);
      last[_] = j;
    }
  }
  printf("%d\n", dp[kk][n]);
}
