#include <bits/stdc++.h>
using namespace std;
int tree[350050 * 8];
int flag[350050 * 8];
int a[350050];
int last[350050];
int dp[350050];
int n, k;
void build(int l, int r, int rt) {
  flag[rt] = 0;
  if (l == r) {
    tree[rt] = dp[l - 1];
    flag[rt] = 0;
    return;
  }
  int m = (l + r) >> 1;
  build(l, m, rt * 2);
  build(m + 1, r, rt * 2 + 1);
}
void pushdown(int l, int r, int rt) {
  if (flag[rt]) {
    int m = (l + r) / 2;
    flag[rt * 2] += flag[rt];
    flag[rt * 2 + 1] += flag[rt];
    tree[rt * 2] += flag[rt];
    tree[rt * 2 + 1] += flag[rt];
    flag[rt] = 0;
  }
}
void pushup(int rt) { tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]); }
int Query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) {
    return tree[rt];
  } else {
    pushdown(l, r, rt);
    int m = (l + r) >> 1;
    int ans = 0;
    if (L <= m) {
      ans = max(ans, Query(L, R, l, m, rt * 2));
    }
    if (m < R) {
      ans = max(ans, Query(L, R, m + 1, r, rt * 2 + 1));
    }
    pushup(rt);
    return ans;
  }
}
void update(int L, int R, int c, int l, int r, int rt) {
  if (L <= l && r <= R) {
    tree[rt] += c;
    flag[rt] += c;
    return;
  }
  pushdown(l, r, rt);
  int m = (l + r) / 2;
  if (L <= m) {
    update(L, R, c, l, m, rt * 2);
  }
  if (m < R) {
    update(L, R, c, m + 1, r, rt * 2 + 1);
  }
  pushup(rt);
}
int main() {
  while (~scanf("%d%d", &n, &k)) {
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= k; i++) {
      build(1, n, 1);
      for (int j = 1; j <= n; j++) dp[j] = 0, last[a[j]] = 0;
      for (int j = 1; j <= n; j++) {
        update(last[a[j]] + 1, j, 1, 1, n, 1);
        last[a[j]] = j;
        dp[j] = Query(1, j, 1, n, 1);
      }
    }
    printf("%d\n", dp[n]);
  }
}
