#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
  x = 0;
  bool flag = 0;
  char ch = getchar();
  while (ch > '9' || ch < '0') {
    if (ch == '-') flag = 1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (((x << 2) + x) << 1) + ch - 48;
    ch = getchar();
  }
  if (flag) x = -x;
}
inline void read(unsigned int &x) {
  x = 0;
  char ch = getchar();
  while (ch > '9' || ch < '0') {
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (((x << 2) + x) << 1) + ch - 48;
    ch = getchar();
  }
}
inline void read(long long &x) {
  x = 0;
  bool flag = 0;
  char ch = getchar();
  while (ch > '9' || ch < '0') {
    if (ch == '-') flag = 1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (((x << 2) + x) << 1) + ch - 48;
    ch = getchar();
  }
  if (flag) x = -x;
}
inline void read(unsigned long long &x) {
  x = 0;
  char ch = getchar();
  while (ch > '9' || ch < '0') {
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (((x << 2) + x) << 1) + ch - 48;
    ch = getchar();
  }
}
inline void read(char &x) {
  x = getchar();
  while (x <= ' ') x = getchar();
}
int data[35001];
int dp[35001][51];
bool appeared[35001];
int lastappear[35001];
struct {
  int l, r;
  int maxn;
  int flag;
} tree[140001];
void build(int from, int to, int j, int now = 1) {
  tree[now].l = from;
  tree[now].r = to;
  tree[now].flag = 0;
  if (from == to) {
    tree[now].maxn = dp[from][j];
    return;
  }
  int mid = from + to >> 1;
  build(from, mid, j, now << 1);
  build(mid + 1, to, j, now << 1 | 1);
  tree[now].maxn = max(tree[now << 1].maxn, tree[now << 1 | 1].maxn);
}
void pushdown(int now) {
  if (tree[now].flag == 0) return;
  tree[now << 1].flag += tree[now].flag;
  tree[now << 1 | 1].flag += tree[now].flag;
  tree[now << 1].maxn += tree[now].flag;
  tree[now << 1 | 1].maxn += tree[now].flag;
  tree[now].flag = 0;
}
void add(int from, int to, int now = 1) {
  if (tree[now].l == from && tree[now].r == to) {
    tree[now].maxn++;
    tree[now].flag++;
    return;
  }
  int mid = tree[now].l + tree[now].r >> 1;
  pushdown(now);
  if (to <= mid) {
    add(from, to, now << 1);
  } else if (from > mid) {
    add(from, to, now << 1 | 1);
  } else {
    add(from, mid, now << 1);
    add(mid + 1, to, now << 1 | 1);
  }
  tree[now].maxn = max(tree[now << 1].maxn, tree[now << 1 | 1].maxn);
}
int ask(int from, int to, int now = 1) {
  if (tree[now].l == from && tree[now].r == to) {
    return tree[now].maxn;
  }
  int mid = tree[now].l + tree[now].r >> 1;
  pushdown(now);
  if (to <= mid) {
    return ask(from, to, now << 1);
  } else if (from > mid) {
    return ask(from, to, now << 1 | 1);
  } else {
    return max(ask(from, mid, now << 1), ask(mid + 1, to, now << 1 | 1));
  }
}
int main() {
  int n, k;
  read(n);
  read(k);
  for (int i = 0; i < n; i++) {
    read(data[i]);
  }
  dp[0][1] = 1;
  appeared[data[0]] = true;
  for (int i = 1; i < n; i++) {
    if (!appeared[data[i]]) {
      dp[i][1] = dp[i - 1][1] + 1;
      appeared[data[i]] = true;
    } else {
      dp[i][1] = dp[i - 1][1];
    }
  }
  for (int j = 2; j <= k; j++) {
    build(0, n - 1, j - 1);
    memset(lastappear, 0, sizeof(lastappear));
    for (int i = j - 1; i < n; i++) {
      add(lastappear[data[i]], i - 1);
      lastappear[data[i]] = i;
      dp[i][j] = ask(0, i);
    }
  }
  cout << dp[n - 1][k];
  return 0;
}
