#include <bits/stdc++.h>
#include <string>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double rl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pii int2;
typedef tuple<int, int, int> int3;
typedef tuple<int, int, int, int> int4;
typedef tuple<int, int, int, int, int> int5;
typedef pll ll2;
typedef tuple<ll, ll, ll> ll3;
typedef tuple<ll, ll, ll, ll> ll4;
typedef tuple<ll, ll, ll, ll, ll> ll5;
#define g0(x) get<0>(x)
#define g1(x) get<1>(x)
#define g2(x) get<2>(x)
#define g3(x) get<3>(x)
#define g4(x) get<4>(x)
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<ll> vll;
typedef vector<pll> vll_ll;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
typedef vector<vll> vvll;
typedef vector<vll_ll> vvll_ll;
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define xx first
#define yy second
#define FOR(i,N) for(int i=0; i<N; i++)
//#define my_to_string to_string
template <typename A, typename B>
string my_to_string(pair<A, B> p);
template <typename A, typename B, typename C>
string my_to_string(tuple<A, B, C> p);
template <typename A, typename B, typename C, typename D>
string my_to_string(tuple<A, B, C, D> p);
string my_to_string(const string& s) {
return '"' + s + '"';
}
string my_to_string(const char* s) {
return my_to_string((string) s);
}
string my_to_string(bool b) {
return (b ? "true" : "false");
}
string my_to_string(vector<bool> v) {
bool first = true;
string res = "{";
for (int i = 0; i < static_cast<int>(v.size()); i++) {
if (!first) {
res += ", ";
}
first = false;
res += my_to_string(v[i]);
}
res += "}";
return res;
}
template <size_t N>
string my_to_string(bitset<N> v) {
string res = "";
for (size_t i = 0; i < N; i++) {
res += static_cast<char>('0' + v[i]);
}
return res;
}
string my_to_string(uint8_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(uint16_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(uint32_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(uint64_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(int8_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(int16_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(int32_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(int64_t a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(float a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string( double a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string(long double a) { ostringstream ss; ss << a; return ss.str(); }
string my_to_string( char a) { ostringstream ss; ss << '\'' << a << '\''; return ss.str(); }
//string my_to_string(unsigned char a) { ostringstream ss; ss << '\'' << a << '\''; return ss.str(); }
// anything that's a range (has .begin(), .end())
template <typename A>
string my_to_string(A v) {
bool first = true;
string res = "{";
for (const auto &x : v) {
if (!first) {
res += ", ";
}
first = false;
res += my_to_string(x);
}
res += "}";
return res;
}
template <typename A, typename B>
string my_to_string(pair<A, B> p) {
return "(" + my_to_string(p.first) + ", " + my_to_string(p.second) + ")";
}
template <typename A, typename B, typename C>
string my_to_string(tuple<A, B, C> p) {
return "(" + my_to_string(get<0>(p)) + ", " + my_to_string(get<1>(p)) + ", " + my_to_string(get<2>(p)) + ")";
}
template <typename A, typename B, typename C, typename D>
string my_to_string(tuple<A, B, C, D> p) {
return "(" + my_to_string(get<0>(p)) + ", " + my_to_string(get<1>(p)) + ", " + my_to_string(get<2>(p)) + ", " + my_to_string(get<3>(p)) + ")";
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cerr << " " << my_to_string(H);
debug_out(T...);
}
#if !ONLINE_JUDGE && 0
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
int n;
const int MX=509;
int a[MX];
bool can1[MX][MX];
int result[MX];
int solve()
{
//for(int i=0; i<n; i++) can1[i][i]=true;
for(int L=0; L<n; L++)
{
for(int R=L; R<n; R++)
{
stack<int> S; S.push(a[L]);
for(int i=L+1; i<=R; i++)
{
S.push(a[i]);
while(S.size()>1)
{
int bb=S.top(); S.pop();
int aa=S.top(); S.pop();
if(aa==bb)
{
S.push(aa+1);
}
else
{
S.push(aa);
S.push(bb);
break;
}
}
}
can1[L][R]=(S.size()==1);
if(can1[L][R])
{
dbg(L, R);
}
}
}
const int INF=1e5;
for(int i=0; i<=n; i++) result[i]=INF;
result[0]=0;
for(int i=0; i<n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(can1[i][j-1]) result[j]=min(result[j], result[i]+1);
}
}
return result[n];
//return -3;
}
int main()
{
#if !ONLINE_JUDGE && 0
freopen("E.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
#if 0
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
#endif
cin >> n;
for(int i=0; i<n; i++) cin >> a[i];
cout << solve();
return 0;
}