#include <bits/stdc++.h>
using namespace std;
const int N = 400007;
const int M = 15005;
const int offset = 7500;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const double eps = 1e-3;
int n, m;
int dp[N][60];
int s[N];
struct nd {
  int val;
  int add;
} tr[N * 4];
int la[N], pos[N];
void pushup(int rt) { tr[rt].val = max(tr[rt << 1].val, tr[rt << 1 | 1].val); }
void pushdown(int rt) {
  if (tr[rt].add == 0) return;
  tr[rt << 1].val += tr[rt].add;
  tr[rt << 1 | 1].val += tr[rt].add;
  tr[rt << 1].add += tr[rt].add;
  tr[rt << 1 | 1].add += tr[rt].add;
  tr[rt].add = 0;
}
void build(int l, int r, int rt) {
  tr[rt].val = 0;
  tr[rt].add = 0;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
void update(int L, int R, int c, int l, int r, int rt) {
  if (L <= l && r <= R) {
    tr[rt].val += c;
    tr[rt].add += c;
    return;
  }
  pushdown(rt);
  int mid = (l + r) >> 1;
  if (L <= mid) update(L, R, c, l, mid, rt << 1);
  if (mid < R) update(L, R, c, mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
int query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) return tr[rt].val;
  pushdown(rt);
  int mid = (l + r) >> 1;
  int ans = 0;
  if (L <= mid) ans = max(ans, query(L, R, l, mid, rt << 1));
  if (mid < R) ans = max(ans, query(L, R, mid + 1, r, rt << 1 | 1));
  return ans;
}
int main() {
  while (~scanf("%d%d", &n, &m)) {
    memset(tr, 0, sizeof tr);
    memset(pos, 0, sizeof pos);
    memset(la, 0, sizeof la);
    memset(dp, 0, sizeof dp);
    for (int i = 1; i <= n; i++) {
      scanf("%d", &s[i]);
      la[i] = pos[s[i]];
      pos[s[i]] = i;
    }
    for (int j = 1; j <= m; j++) {
      build(1, n, 1);
      for (int i = 1; i <= n; i++) {
        update(la[i] + 1, i, 1, 1, n, 1);
        update(i, i, dp[i - 1][j - 1], 1, n, 1);
        dp[i][j] = query(1, i, 1, n, 1);
      }
    }
    printf("%d\n", dp[n][m]);
  }
  return 0;
}
