#include <bits/stdc++.h>
using namespace std;
long long int n, k;
vector<long long int> order, last;
vector<vector<long long int>> DP;
const int pot = 65536;
vector<int> tree[pot * 2 + 1];
unordered_map<int, int> cache[35001];
void merge(vector<int> &a, vector<int> &b, vector<int> &merged) {
  unsigned int p = 0, q = 0;
  while (p < a.size() && q < b.size()) {
    if (a[p] < b[q]) {
      merged.push_back(a[p++]);
    } else {
      merged.push_back(b[q++]);
    }
  }
  while (p < a.size()) {
    merged.push_back(a[p++]);
  }
  while (q < b.size()) {
    merged.push_back(b[q++]);
  }
}
long long int vec_cost(vector<int> &v, int &le_to) {
  return upper_bound(v.begin(), v.end(), le_to) - v.begin();
}
void build() {
  for (int i = 1; i <= n; ++i) {
    tree[i + pot - 1].push_back(last[i]);
  }
  for (int j = pot - 1; j > 0; --j) {
    merge(tree[2 * j], tree[2 * j + 1], tree[j]);
  }
}
long long int query(long long int l, long long int r, int le_to) {
  l--;
  l += pot;
  r--;
  r += pot;
  long long int sum = 0;
  while (l <= r) {
    if (l % 2 == 1) {
      sum += vec_cost(tree[l++], le_to);
    }
    if (r % 2 == 0) {
      sum += vec_cost(tree[r--], le_to);
    }
    l /= 2;
    r /= 2;
  }
  return sum;
}
long long int cost(long long int left, long long int right) {
  if (cache[left].find(right) != cache[left].end()) {
    return cache[left][right];
  }
  return cache[left][right] = query(left, right, left - 1);
}
int level = 2;
void calculateDP(int L, int R, int optL, int optR) {
  if (L == R) {
    for (int j = optL; j <= min(optR, L - 1); ++j) {
      DP[L][level] = max(DP[L][level], DP[j][level - 1] + cost(j + 1, L));
    }
    return;
  }
  int M = (L + R) / 2;
  int optimalpos = optL;
  for (int j = optL; j <= min(optR, M); ++j) {
    int s = cost(j + 1, M);
    if (DP[M][level] < DP[j][level - 1] + s) {
      DP[M][level] = DP[j][level - 1] + s;
      optimalpos = j;
    }
  }
  if (L != M) calculateDP(L, M - 1, optL, optimalpos);
  if (R != M) calculateDP(M + 1, R, optimalpos, optR);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> k;
  order = vector<long long int>(n + 1);
  last = vector<long long int>(n + 1, 0);
  map<int, int> elem_to_last_index;
  for (int i = 1; i <= n; ++i) {
    cin >> order[i];
    if (elem_to_last_index.find(order[i]) != elem_to_last_index.end()) {
      last[i] = elem_to_last_index[order[i]];
    }
    elem_to_last_index[order[i]] = i;
  }
  build();
  DP = vector<vector<long long int>>(n + 1, vector<long long int>(k + 1, 0));
  set<long long int> si;
  for (int i = 1; i <= n; ++i) {
    si.insert(order[i]);
    DP[i][1] = si.size();
  }
  for (int t = 2; t <= k; ++t) {
    calculateDP(1, n, 1, n);
    ++level;
  }
  cout << DP[n][k] << "\n";
}
