#include <bits/stdc++.h>
using namespace std;
using LL = long long;
template <typename T>
using V = vector<T>;
template <typename T, typename S>
using P = pair<T, S>;
template <class T>
using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;
using LD = long double;
template <typename T, typename S>
void check(T& a, S& b) {
  if (a >= b) {
    a %= b;
  }
}
template <typename T>
T gcd(T u, T v) {
  if (u == v) return u;
  if (u == 0) return v;
  if (v == 0) return u;
  if (~u & 1) {
    if (v & 1)
      return gcd(u >> 1, v);
    else
      return gcd(u >> 1, v >> 1) << 1;
  }
  if (~v & 1) return gcd(u, v >> 1);
  if (u > v) return gcd((u - v) >> 1, v);
  return gcd((v - u) >> 1, u);
}
const int N = 35001;
int n, k;
int dp[N][51];
class SegmentTree {
 public:
  int n;
  V<int> arr, lazy;
  SegmentTree() {}
  SegmentTree(int n) {
    this->n = n;
    this->arr = V<int>(n << 2, 0);
    this->lazy = V<int>(n << 2, 0);
  }
  void propogate(int node, int s, int e) {
    if (lazy[node]) {
      arr[node] += lazy[node];
      if (s != e) {
        lazy[node << 1] += lazy[node];
        lazy[node << 1 | 1] += lazy[node];
      }
    }
    lazy[node] = 0;
  }
  void update(int node, int s, int e, int l, int r, int val) {
    propogate(node, s, e);
    if (l > r || s > r || e < l) return;
    if (s >= l && e <= r) {
      lazy[node] += val;
      propogate(node, s, e);
      return;
    }
    int mid = (s + e) >> 1;
    update(node << 1, s, mid, l, r, val);
    update(node << 1 | 1, mid + 1, e, l, r, val);
    arr[node] = max(arr[node << 1], arr[node << 1 | 1]);
  }
  void upd(int node, int s, int e, int l, int val) {
    propogate(node, s, e);
    if (s == e) {
      arr[node] = max(arr[node], val);
      return;
    }
    int mid = (s + e) >> 1;
    if (l <= mid)
      upd(node << 1, s, mid, l, val);
    else
      upd(node << 1 | 1, mid + 1, e, l, val);
    propogate(node << 1, s, mid);
    propogate(node << 1 | 1, mid + 1, e);
    arr[node] = max(arr[node << 1], arr[node << 1 | 1]);
    return;
  }
  int get(int node, int s, int e, int l, int r) {
    propogate(node, s, e);
    if (l > r || s > r || e < l) return 0;
    if (s >= l && e <= r) {
      return arr[node];
    }
    int mid = (s + e) >> 1;
    return max(get(node << 1, s, mid, l, r),
               get(node << 1 | 1, mid + 1, e, l, r));
  }
};
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cerr.tie(NULL);
  ;
  cin >> n >> k;
  V<int> a, f(n + 1, n);
  a.resize(n);
  for (int i = 0; i < (int)n; i++) cin >> a[i], a[i]--;
  SegmentTree seg[51];
  for (int i = 0; i < k; i++) seg[i] = SegmentTree(n);
  for (int i = n - 1; i >= 0; i--) {
    dp[i][0] = dp[i + 1][0];
    if (f[a[i]] == n) dp[i][0]++;
    seg[0].upd(1, 0, n - 1, i, dp[i][0]);
    for (int j = 1; j < min(n - i, k); j++) {
      seg[j - 1].update(1, 0, n - 1, i + 1, min(f[a[i]], n - 1), 1);
      dp[i][j] = seg[j - 1].get(1, 0, n - 1, i + 1, n - 1);
      seg[j].upd(1, 0, n - 1, i, dp[i][j]);
    }
    f[a[i]] = i;
  }
  cout << dp[0][k - 1] << '\n';
  cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms"
       << '\n';
  return 0;
}
