#include <bits/stdc++.h>
using namespace std;
const long double EPS = 1e-10;
const long long MOD = 1e9 + 7;
const long double PI = 3.1415926535897932384626433832795028841;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= MOD;
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % MOD;
    a = a * a % MOD;
  }
  return res;
}
template <class T>
struct segtree_t {
  T *t;
  T *lazy;
  int sz;
  T (*addition_fun)(T, T);
  T invalid_value;
  segtree_t() {}
  segtree_t(int n, T *arr, T (*add_fun)(T, T), T invalid_val) {
    t = new T[4 * n];
    lazy = new T[4 * n];
    sz = n;
    addition_fun = add_fun;
    build(1, 0, n - 1, arr);
    invalid_value = invalid_val;
  }
  void build(int i, int l, int r, T *arr) {
    if (l > r) return;
    lazy[i] = 0;
    if (l == r) {
      t[i] = arr[l];
    } else {
      build(i * 2, l, (l + r) / 2, arr);
      build(i * 2 + 1, (l + r) / 2 + 1, r, arr);
      t[i] = addition_fun(t[i * 2], t[i * 2 + 1]);
    }
  }
  void inc_range(int l, int r, T value) {
    if (l > r) return;
    inc_range_rec(1, 0, sz - 1, l, r, value);
  }
  void inc_range_rec(int i, int l, int r, int tl, int tr, T value) {
    if (lazy[i] != 0) {
      t[i] += lazy[i];
      if (l != r) {
        lazy[i * 2] += lazy[i];
        lazy[i * 2 + 1] += lazy[i];
      }
      lazy[i] = 0;
    }
    if (r < tl or l > tr) return;
    if (l > r) return;
    if (l >= tl and r <= tr) {
      if (l != r) {
        lazy[i * 2] += value;
        lazy[i * 2 + 1] += value;
      }
      t[i] += value;
    } else {
      inc_range_rec(i * 2, l, (l + r) / 2, tl, tr, value);
      inc_range_rec(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr, value);
      t[i] = addition_fun(t[i * 2], t[i * 2 + 1]);
    }
  }
  T query_rec(int i, int l, int r, int tl, int tr) {
    if (r < tl or l > tr) return invalid_value;
    if (l > r) return invalid_value;
    if (lazy[i] != 0) {
      t[i] += lazy[i];
      if (l != r) {
        lazy[i * 2] += lazy[i];
        lazy[i * 2 + 1] += lazy[i];
      }
      lazy[i] = 0;
    }
    if (l >= tl and r <= tr) {
      return t[i];
    } else {
      T m1 = query_rec(i * 2, l, (l + r) / 2, tl, tr);
      T m2 = query_rec(i * 2 + 1, (l + r) / 2 + 1, r, tl, tr);
      if (m1 == invalid_value && m2 == invalid_value) return invalid_value;
      if (m1 == invalid_value) return m2;
      if (m2 == invalid_value) return m1;
      return addition_fun(m1, m2);
    }
  }
  T query(int l, int r) { return query_rec(1, 0, sz - 1, l, r); }
  ~segtree_t() {
    delete[] t;
    delete[] lazy;
  }
};
const int maxn = 35 * 1e3 + 5;
const int maxk = 60;
int dp[maxk][maxn];
int a[maxn];
int last[maxn];
int aux[maxn];
int add_fun(int a, int b) { return max(a, b); }
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  set<int> occ;
  for (int i = 1; i <= n; i++) {
    occ.insert(a[i]);
    dp[1][i] = occ.size();
  }
  for (int b = 2; b <= k; b++) {
    fill(last, last + n + 5, b - 1);
    for (int i = 0; i <= n; i++) {
      if (i < b) {
        aux[i] = -1e9;
      } else {
        aux[i] = dp[b - 1][i - 1];
      }
    }
    segtree_t<int> tree = segtree_t<int>(n + 1, aux, add_fun, -1e9);
    for (int i = b; i <= n; i++) {
      tree.inc_range(last[a[i]] + 1, i, 1);
      last[a[i]] = i;
      dp[b][i] = tree.query(b, i);
    }
  }
  printf("%d \n", dp[k][n]);
}
