#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>

#define MAXA 50000000
#define MOD 1000000007

using namespace std;

typedef map<int, int> MAP;

char arr[MAXA],*ptr;
long long ret,n,m,k;

int alF[100005],boF[100000];
int aloc,bloc;

MAP diff;
MAP ::iterator it_m;

inline long long get_int()
{
    ret =0;
    while ( !(*ptr >= '0' && *ptr <= '9'))
        ptr++;
    while (*ptr >= '0' && *ptr<= '9') {
        ret = ret*10 + (*ptr - '0');
        ptr++;
    }
    return ret;
}

int main()
{
    fread(arr,sizeof(char),MAXA,stdin);
    ptr = arr;
    n = get_int();
    m = get_int();
    k = get_int();
    int alice = 0,bob = 0;
    long long typeOfFish;
    for(int xx =0;xx< n;xx++){
        typeOfFish = get_int();
        alF[xx] = typeOfFish;
        it_m = diff.find(typeOfFish);
        if(it_m == diff.end())
            diff[typeOfFish] = 1;
        else
            (it_m->second)++;
    }
    for(int xx =0;xx< m;xx++){
        typeOfFish = get_int();
        boF[xx] = typeOfFish;
        it_m = diff.find(typeOfFish);
        if(it_m == diff.end())
            diff[typeOfFish] = -1;
        else
            (it_m->second)--;
    }

    aloc = 0;
    alice = 0;
    bob =0;
    bloc = 0;
    for(it_m = diff.begin();it_m != diff.end(); it_m++){
        if(it_m->second < 0 ){
            int temp = -(it_m->second);
            for(int xx =0;xx<temp;xx++)
                boF[bloc++] = it_m->first;
            bob++;
        }
        if(it_m->second > 0 ){
            int temp = (it_m->second);
            for(int xx =0;xx<temp;xx++)
                alF[aloc++] = it_m->first;

            alice++;
        }
    }
    int gobble = 0;
    if(n > m)
        cout << "YES";
    else if(n < m)
        cout << "NO";
    else{
        for(int xx =0;xx<bloc;xx++)
        {
            for(int yy =0;yy<aloc;yy++){
                if(boF[xx] > alF[yy]){
                    gobble++;
                    alF[yy] = 99999999;
                    break;
                }
            }
        }
        if(gobble < aloc)
            cout << "YES";
        else
            cout << "NO";
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>

#define MAXA 50000000
#define MOD 1000000007

using namespace std;

typedef map<int, int> MAP;

char arr[MAXA],*ptr;
long long ret,n,m,k;

int alF[100005],boF[100005];
int aloc,bloc;

MAP diff;
MAP ::iterator it_m;

inline long long get_int()
{
    ret =0;
    while ( !(*ptr >= '0' && *ptr <= '9'))
        ptr++;
    while (*ptr >= '0' && *ptr<= '9') {
        ret = ret*10 + (*ptr - '0');
        ptr++;
    }
    return ret;
}

int main()
{
    fread(arr,sizeof(char),MAXA,stdin);
    ptr = arr;
    n = get_int();
    m = get_int();
    k = get_int();
    int alice = 0,bob = 0;
    long long typeOfFish;

    for(int xx =0;xx< n;xx++){
        typeOfFish = get_int();
        alF[xx] = typeOfFish;
        it_m = diff.find(typeOfFish);
        if(it_m == diff.end())
            diff[typeOfFish] = 1;
        else
            (it_m->second)++;
    }
    for(int xx =0;xx< m;xx++){
        typeOfFish = get_int();
        boF[xx] = typeOfFish;
        it_m = diff.find(typeOfFish);
        if(it_m == diff.end())
            diff[typeOfFish] = -1;
        else
            (it_m->second)--;
    }

    aloc = 0;
    alice = 0;
    bob =0;
    bloc = 0;
    for(it_m = diff.begin();it_m != diff.end(); it_m++){
        if(it_m->second < 0 ){
            int temp = -(it_m->second);
            for(int xx =0;xx<temp;xx++)
                boF[bloc++] = it_m->first;
            bob++;
        }
        if(it_m->second > 0 ){
            int temp = (it_m->second);
            for(int xx =0;xx<temp;xx++)
                alF[aloc++] = it_m->first;

            alice++;
        }
    }
    int gobble = 0;
    if(aloc > bloc)
        cout << "YES";
    else if(aloc < bloc){
        for(int xx =0;xx<bloc;xx++)
        {
            for(int yy =0;yy<aloc;yy++){
                if(boF[xx] > alF[yy]){
                    gobble++;
                    alF[yy] = 99999999;
                    break;
                }
            }
        }
        if(gobble < aloc)
            cout << "NO";
        else
            cout << "YES";
    }
    else if(bloc == aloc){
        for(int xx =0;xx<bloc;xx++)
        {
            for(int yy =0;yy<aloc;yy++){
                if(boF[xx] > alF[yy]){
                    gobble++;
                    alF[yy] = 99999999;
                    break;
                }
            }
        }
        if(gobble < aloc)
            cout << "YES";
        else
            cout << "NO";
    }
    return 0;
}


import java.util.Arrays;
import java.util.Scanner;

public class C1312E {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        // g[i][j]表示将a[i]..a[j]合并并且如果能合并成1个数字的话会是几。
        int[][] g = new int[n][n];
        for (int i = 0; i < n; i++) {
            g[i][i] = a[i];
        }
        for (int len = 2; len <= n; len++) {
            for (int i = 0, j = len - 1; i + len - 1 < n; i++, j++) {
                for (int k = i; k < j; k++) {
                    if (g[i][k] != 0 && g[i][k] == g[k + 1][j]) {
                        g[i][j] = g[i][k] + 1;
                        break;
                    }
                }
            }
        }
        // f[i][head]表示将a[i]..a[n-1]进行合并后，开头数字是head的最短长度。
        // minF[i]表示f[i]中的最小值
        int[][] f = new int[n][1000 + n];
        int[] minF = new int[n];
        Arrays.fill(f[n - 1], Integer.MAX_VALUE);
        f[n - 1][a[n - 1]] = 1;
        minF[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            Arrays.fill(f[i], Integer.MAX_VALUE);
            if (g[i][n - 1] > 0) {
                f[i][g[i][n - 1]] = 1;
            }
            for (int j = i; j + 1 < n; j++) {
                if (g[i][j] > 0) {
                    int head = g[i][j] + 1;
                    f[i][head] = Math.min(f[i][head], f[j + 1][head - 1]); // 合并
                    f[i][head] = Math.min(f[i][head], minF[j + 1] + 1); // 不合并
                }
            }
            minF[i] = Arrays.stream(f[i]).min().getAsInt();
        }
        System.out.println(Arrays.stream(f[0]).min().getAsInt());
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class C1312E {

    static final int MAX = 99999999;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        // g[i][j]表示将a[i]..a[j]合并并且如果能合并成1个数字的话会是几。
        int[][] g = new int[n][n];
        for (int i = 0; i < n; i++) {
            g[i][i] = a[i];
        }
        for (int len = 2; len <= n; len++) {
            for (int i = 0, j = len - 1; i + len - 1 < n; i++, j++) {
                for (int k = i; k < j; k++) {
                    if (g[i][k] != 0 && g[i][k] == g[k + 1][j]) {
                        g[i][j] = g[i][k] + 1;
                        break;
                    }
                }
            }
        }
        // f[i][head]表示将a[i]..a[n-1]进行合并后，开头数字是head的最短长度。
        // minF[i]表示f[i]中的最小值
        int[][] f = new int[n + 1][1000 + n + 1];
        int[] minF = new int[n + 1];
        Arrays.fill(f[n], MAX);
        minF[n] = MAX;
        for (int i = n - 1; i >= 0; i--) {
            Arrays.fill(f[i], MAX);
            f[i][a[i]] = n - i;
            for (int j = i; j <= n - 1; j++) {
                if (g[i][j] > 0) {
                    f[i][g[i][j] + 1] = Math.min(f[i][g[i][j] + 1], f[j + 1][g[i][j]]); // 合并
                    f[i][g[i][j]] = Math.min(f[i][g[i][j]], minF[j + 1] + 1); // 不合并
                }
                f[i][a[i]] = Math.min(f[i][a[i]], minF[j + 1] + j - i + 1); // a[i]到a[j]不合并
            }
            minF[i] = Arrays.stream(f[i]).min().getAsInt();
        }
        System.out.println(Arrays.stream(f[0]).min().getAsInt());
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class C1312E {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        // g[i][j]表示将a[i]..a[j]合并并且如果能合并成1个数字的话会是几。
        int[][] g = new int[n][n];
        for (int i = 0; i < n; i++) {
            g[i][i] = a[i];
        }
        for (int len = 2; len <= n; len++) {
            for (int i = 0, j = len - 1; i + len - 1 < n; i++, j++) {
                for (int k = i; k < j; k++) {
                    if (g[i][k] != 0 && g[i][k] == g[k + 1][j]) {
                        g[i][j] = g[i][k] + 1;
                        break;
                    }
                }
            }
        }
        // f[i][head]表示将a[i]..a[n-1]进行合并后，开头数字是head的最短长度。
        // minF[i]表示f[i]中的最小值
        int[][] f = new int[n][1000 + n];
        int[] minF = new int[n];
        Arrays.fill(f[n - 1], Integer.MAX_VALUE);
        f[n - 1][a[n - 1]] = 1;
        minF[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            Arrays.fill(f[i], Integer.MAX_VALUE);
            if (g[i][n - 1] > 0) {
                f[i][g[i][n - 1]] = 1;
            }
            for (int j = i; j + 1 < n; j++) {
                if (g[i][j] > 0) {
                    int head = g[i][j] + 1;
                    f[i][head] = Math.min(f[i][head], f[j + 1][head - 1]); // 合并
                    f[i][head] = Math.min(f[i][head], minF[j + 1] + 1); // 不合并
                }
                f[i][a[i]] = Math.min(f[i][a[i]], minF[j + 1] + j - i + 1);
            }
            minF[i] = Arrays.stream(f[i]).min().getAsInt();
        }
        System.out.println(Arrays.stream(f[0]).min().getAsInt());
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class C1312E {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        // g[i][j]表示将a[i]..a[j]合并并且如果能合并成1个数字的话会是几。
        int[][] g = new int[n][n];
        for (int i = 0; i < n; i++) {
            g[i][i] = a[i];
        }
        for (int len = 2; len <= n; len++) {
            for (int i = 0, j = len - 1; i + len - 1 < n; i++, j++) {
                for (int k = i; k < j; k++) {
                    if (g[i][k] != 0 && g[i][k] == g[k + 1][j]) {
                        g[i][j] = g[i][k] + 1;
                        break;
                    }
                }
            }
        }
        // f[i][head]表示将a[i]..a[n-1]进行合并后，开头数字是head的最短长度。
        // minF[i]表示f[i]中的最小值
        int[][] f = new int[n][1000 + n];
        int[] minF = new int[n];
        Arrays.fill(f[n - 1], Integer.MAX_VALUE);
        f[n - 1][a[n - 1]] = 1;
        minF[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            Arrays.fill(f[i], Integer.MAX_VALUE);
            if (g[i][n - 1] > 0) {
                f[i][g[i][n - 1]] = 1;
            }
            for (int j = i; j + 1 < n; j++) {
                if (g[i][j] > 0) {
                    int head = g[i][j] + 1;
                    f[i][head] = Math.min(f[i][head], f[j + 1][head - 1]); // 合并
                    f[i][head] = Math.min(f[i][head], minF[j + 1] + 1); // 不合并
                } else {
                    f[i][a[i]] = Math.min(f[i][a[i]], minF[j + 1] + j - i + 1);
                }
            }
            minF[i] = Arrays.stream(f[i]).min().getAsInt();
        }
        System.out.println(Arrays.stream(f[0]).min().getAsInt());
    }
}


import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007L;
	long inf=Long.MAX_VALUE;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	void work() {
		int n=ni();
		int[] A=nia(n);
		int[][] dp=new int[n][n];
		int[][] V=new int[n][n];
		for(int k=0;k<n;k++) {
			out:
			for(int i=0;i+k<n;i++) {
				int j=i+k;
				if(i==j) {
					V[i][j]=A[i];
					dp[i][j]=1;
				}else {
					dp[i][j]=j-i+1;
					if(i==0&&j==n-1) {
						int a=1;
					}
					//全合并 或 中间断开
					for(int p=i;p<j;p++) {
						if(V[i][p]==V[p+1][j]&&V[i][p]!=0) {
							dp[i][j]=1;
							V[i][j]=V[i][p]+1;
							continue out;
						}
					}
					for(int p=i;p<j;p++) {
						dp[i][j]=Math.min(dp[i][j], dp[i][p]+dp[p+1][j]);
					}
				}
			}
		}
		out.println(dp[0][n-1]);
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		while(st==null || !st.hasMoreElements())//回车，空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}


import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		InputReader in = new InputReader();

		int N = in.nextInt();
		int[] A = new int[N];
		for (int i = 0; i < N; i++) {
			A[i] = in.nextInt();
		}
		int[] dp = new int[N + 1];
		Stack<Integer> stack = new Stack<>();
		for (int i = N - 1; i >= 0; i--) {
			dp[i] = dp[i + 1] + 1;
			stack.clear();
			stack.push(A[i]);
			for (int j = i + 1; j < N; j++) {
				int x = A[j];
				while (!stack.isEmpty() && stack.peek() == x) {
					stack.pop();
					x++;
				}
				stack.push(x);
				if (stack.size() == 1) {
					dp[i] = Math.min(dp[i], dp[j + 1] + 1);
				}
			}
		}

		System.out.println(dp[0]);
	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer st;

		public InputReader() {
			reader = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(nextLine());
			}
			return st.nextToken();
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
	}
}


import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		InputReader in = new InputReader();

		int N = in.nextInt();
		int[] A = new int[N];
		for (int i = 0; i < N; i++) {
			A[i] = in.nextInt();
		}
		int[][] dp = new int[1010][N + 1];
		for (int i = 0; i < dp.length; i++) {
			Arrays.fill(dp[i], -1);
		}
		for (int i = 1; i < dp.length; i++) {
			for (int j = 0; j < N; j++) {
				if (A[j] == i) {
					dp[i][j] = j + 1;
				} else {
					if (dp[i - 1][j] == -1 || dp[i - 1][dp[i - 1][j]] == -1) {
						continue;
					}
					dp[i][j] = dp[i - 1][dp[i - 1][j]];
				}
			}
		}
		int[] dp2 = new int[N + 1];
		for (int i = 0; i < N; i++) {
			dp2[i] = N - i;
		}
		for (int i = N - 1; i >= 0; i--) {
			for (int j = 0; j < dp.length; j++) {
				if (dp[j][i] == -1) {
					continue;
				}
				dp2[i] = Math.min(dp2[i], dp2[dp[j][i]] + 1);
			}
		}

		System.out.println(dp2[0]);
	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer st;

		public InputReader() {
			reader = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(nextLine());
			}
			return st.nextToken();
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
	}
}


import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		InputReader in = new InputReader();

		int N = in.nextInt();
		int[] A = new int[N];
		for (int i = 0; i < N; i++) {
			A[i] = in.nextInt();
		}
		int[][] dp = new int[N][N];
		int[][] dp2 = new int[N][N];
		for (int i = 0; i < N; i++) {
			Arrays.fill(dp[i], -1);
			Arrays.fill(dp2[i], -1);
			dp[i][i] = A[i];
			for (int j = i; j < N; j++) {
				dp2[i][j] = j - i + 1;
			}
		}
		for (int i = 1; i < N; i++) {
			for (int j = 0; j + i < N; j++) {
				for (int k = j; k < j + i; k++) {
					if (dp[j][k] != -1 && dp[j][k] == dp[k + 1][j + i]) {
						dp[j][j + i] = dp[j][k] + 1;
						dp2[j][j + i] = 1;
						break;
					}
				}
			}
		}
		for (int i = 1; i < N; i++) {
			for (int j = 0; j + i < N; j++) {
				for (int k = j; k < j + i; k++) {
					dp2[j][j + i] = Math.min(dp2[j][j + i], dp2[j][k] + dp2[k + 1][j + i]);
				}
			}
		}

		System.out.println(dp2[0][N - 1]);
	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer st;

		public InputReader() {
			reader = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(nextLine());
			}
			return st.nextToken();
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class e_e83 {

	static int MOD = 998244353;
	static long fact [];

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub

		FastScanner in = new FastScanner(System.in);
		OutputStream outputStream = System.out;
		PrintWriter out = new PrintWriter(outputStream);

		int N = in.nextInt();
		int a[]= new int [N];

		for(int i = 0; i < N; i++) {
			a[i] = in.nextInt();
		}

		int dp [][] = new int [N][N];
		// dp[i][j] = non-zero value if segemnt [i...j] can be compressed into a single number
		for(int i = 0; i < N; i++) {
			dp[i][i] = a[i];
		}

		for(int len = 1; len < N; len++) {
			for(int i = 0; i < N-len; i++) {
				for(int j = i; j < i+len; j++) {
					if(dp[i][j] == dp[j+1][i+len] && dp[i][j] != 0) {
						dp[i][i+len] = dp[i][j]+1;
					}
				}
			}
		}

		int dp2 [] = new int [N+1];
		for(int i = 0; i <= N; i++) {
			dp2[i] = Integer.MAX_VALUE/4;
		}
		dp2[0] = 0;
		for(int i = 1; i <= N; i++) {
			for(int j = 0; j < i; j++) {
				if(dp[j][i-1] != 0) {
					dp2[i] = Math.min(dp2[i], dp2[j]+1);
				}
			}
		}

		out.println(dp2[N]);

		out.close();
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(InputStream stream) {
			br = new BufferedReader(new InputStreamReader(stream));
			st = new StringTokenizer("");
		}

		public FastScanner(String fileName) throws Exception {
			br = new BufferedReader(new FileReader(new File(fileName)));
			st = new StringTokenizer("");
		}

		public String next() throws Exception {
			while (!st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine());
			}
			return st.nextToken();
		}

		public int nextInt() throws Exception {
			return Integer.parseInt(next());
		}

		public long nextLong() throws Exception {
			return Long.parseLong(next());
		}

		public Double nextDouble() throws Exception {
			return Double.parseDouble(next());
		}

		public String nextLine() throws Exception {
			if (st.hasMoreTokens()) {
				StringBuilder str = new StringBuilder();
				boolean first = true;
				while (st.hasMoreTokens()) {
					if (first) {
						first = false;
					} else {
						str.append(" ");
					}
					str.append(st.nextToken());
				}
				return str.toString();
			} else {
				return br.readLine();
			}
		}
	}

}


import java.util.*;
import java.io.*;

public class C {
	static PrintWriter pw;
	static BufferedReader br;
	static int inf = (int) 1e9;
	static long mod = (long) 1e9 + 7;

	static int[] a;
	static int[] dp;
	static int[][] memo;

	static int getval(int l, int r) {
		if (l == r)
			return memo[l][r] = a[r];
		if (memo[l][r] != -1)
			return memo[l][r];
		for (int i = l; i < r; i++) {
			if (getval(l, i) == getval(i + 1, r) && getval(l, i) != -2) {
				return memo[l][r] = getval(l, i) + 1;
			}
		}
		return memo[l][r] = -2;
	}

	static int dp(int l) {
		if (l == a.length)
			return 0;
		if (dp[l] != -1)
			return dp[l];
		int ans = (int) 1e9;
		for (int i = l; i < a.length; i++) {
			if (getval(l, i) != -2) {
				ans = Math.min(ans, 1 + dp(i + 1));
			}
		}
		return dp[l] = ans;
	}

	public static void main(String[] args) throws NumberFormatException, IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		int n = Integer.parseInt(br.readLine());
		a = nxtarr();
		memo = new int[n][n];
		for (int i = 0; i < memo.length; i++) {
			Arrays.fill(memo[i], -1);
		}
		dp = new int[n];
		Arrays.fill(dp, -1);
		pw.println(dp(0));
		pw.flush();
	}

	static class pair implements Comparable<pair> {
		int x;
		int y;

		public pair(int d, int u) {
			x = d;
			y = u;
		}

		public int compareTo(pair o) {
			return x - o.x;
		}

	}

	static class triple implements Comparable<triple> {
		int x;
		int y;
		int z;

		public triple(int a, int b, int c) {
			x = a;
			y = b;
			z = c;
		}

		public int compareTo(triple o) {
			return x - o.x;
		}
	}

	static int[] nxtarr() throws IOException {
		StringTokenizer st = new StringTokenizer(br.readLine());
		int[] a = new int[st.countTokens()];
		for (int i = 0; i < a.length; i++) {
			a[i] = Integer.parseInt(st.nextToken());
		}
		return a;
	}

	static long pow(long a, long e) // O(log e)
	{
		long res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res *= a;
			a *= a;
			e >>= 1;
		}
		return res;
	}

	static int gcd(int a, int b) {
		if (a == 0)
			return b;
		return gcd(b % a, a);
	}
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int INF = 1000000009;

int main() {
  int n; cin >> n;
  vector<int> a(n);

  for (int i = 0; i < n; i++) { cin >> a[i]; }

  vector<vector<int>> dp(n+1, vector<int>(n+1,-1));
  for (int i = 0; i < n; i++) {
    dp[i][i+1] = a[i];
  }

  for (int len = 2; len <= n; len++) {
    for (int l = 0; l + len <= n; l++) {
      int r = l + len;
      for (int m = l + 1; m < r; ++m) {
        if (dp[l][m] != -1 && dp[l][m] == dp[m][r]) {
          dp[l][r] = dp[l][m] + 1;
        }
      }
    }
  }
  vector<int> res(n+1, INF);
  res[0] = 0;
  for (int i = 1; i <= n; i++) {
    res[i] = i;
    for (int j = 0; j < i; j++) {
      if (dp[j][i] != -1) {
        res[i] = min(res[i], res[j] + 1);
      }
    }
  }
  cout << res[n] << "\n";
  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int INF = 1000000009;

int main() {
  int n; cin >> n;
  vector<int> a(n);

  for (int i = 0; i < n; i++) { cin >> a[i]; }

  vector<vector<int>> dp(n+1, vector<int>(n+1,-1));
  for (int i = 0; i < n; i++) {
    dp[i][i+1] = a[i];
  }

  for (int len = 2; len <= n; len++) {
    for (int l = 0; l + len <= n; l++) {
      int r = l + len;
      for (int m = l + 1; m < r; ++m) {
        if (dp[l][m] != -1 && dp[l][m] == dp[m][r]) {
          dp[l][r] = dp[l][m] + 1;
        }
      }
    }
  }
  vector<int> res(n+1, INF);
  res[0] = 0;
  for (int i = 1; i <= n; i++) {
    res[i] = i;
    for (int j = 0; j < i; j++) {
      if (dp[j][i] != -1) {
        res[i] = min(res[i], res[j] + 1);
      }
    }
  }
  cout << res[n] << endl;
  return 0;
}


#include <bits/stdc++.h>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define endl "\n"
#define rep(i, s, n)    for(ll i = s; i < (n); ++i)
#define F first
#define S second
#define ll long long
#define sz(a) a.size()
#define pii std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vvi vector<vi >
#define vii vector<pii >
#define vll vector<pll >
#define INF INT_MAX
#define inf 9e18
#define N int(2e5+5)
#define all(v) v.begin(),v.end()
#define mod 998244353

using namespace std;
int n,a[505];
int dp[505][505],dp2[505];
void solve()
{
	for(int i=n;i>=1;i--)
	{
		dp[i][i]=a[i];
		for(int j=i+1;j<=n;j++)
		{
			dp[i][j]=0;
			for(int k=i;k<j;k++)
			{
				if(dp[i][k]&&dp[i][k]==dp[k+1][j])dp[i][j]=dp[i][k]+1;
			}
		}
	}
	// for(int i=1;i<=n;i++)
	// {
	// 	for(int j=1;j<=n;j++)
	// 	{
	// 		cout<<dp[i][j]<<' ';
	// 	}cout<<endl;
	// }
	for(int i=1;i<=n;i++)
	{
		dp2[i]=1e9;
		for(int j=0;j<i;j++)
		{
			if(dp[j+1][i]&&dp2[j]+1<dp2[i])dp2[i]=dp2[j]+1;
		}
	}
	cout<<dp2[n];
}
int main()
{
	FAST
	ll test=1;
	// cin>>test;
	while(test--)
	{
		cin>>n;rep(i,1,n+1)cin>>a[i];
		solve();
		cout<<endl;
	}
}


#include <bits/stdc++.h>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define endl "\n"
#define rep(i, s, n)    for(ll i = s; i < (n); ++i)
#define F first
#define S second
#define ll long long
#define sz(a) a.size()
#define pii std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vvi vector<vi >
#define vii vector<pii >
#define vll vector<pll >
#define INF INT_MAX
#define inf 9e18
#define N int(2e5+5)
#define all(v) v.begin(),v.end()
#define mod 998244353

using namespace std;
int n;vector<int> v;
int f(int n,vector<int> v)
{
	int ans=0;
	bool fl=0;
	for(int i=0;i<n-1;i++)
	{
		if(v[i]==v[i+1])
		{fl=1;
			vector<int> t;v[i+1]+=1;
			rep(j,0,n)if(j!=i)t.pb(v[j]);
			ans=max(ans,1+f(n-1,t));
			v[i+1]-=1;
		}
	}
	if(!fl)return 0;
	return ans;
}
void solve()
{
	cout<<n-f(n,v);
}
int main()
{
	FAST
	ll test=1;
	// cin>>test;
	while(test--)
	{
		cin>>n;
		v=vector<int>(n,0);
		rep(i,0,n)cin>>v[i];
		solve();
		cout<<endl;
	}
}


#include <bits/stdc++.h>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define endl "\n"
#define rep(i, s, n)    for(ll i = s; i < (n); ++i)
#define F first
#define S second
#define ll long long
#define sz(a) a.size()
#define pii std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vvi vector<vi >
#define vii vector<pii >
#define vll vector<pll >
#define INF INT_MAX
#define inf 9e18
#define N int(2e5+5)
#define all(v) v.begin(),v.end()
#define mod 998244353

using namespace std;
int n,a[505];
int dp[505][505],dp2[505];
void solve()
{
	for(int i=n;i>=1;i--)
	{
		dp[i][i]=a[i];
		for(int j=i+1;j<=n;j++)
		{
			dp[i][j]=0;
			for(int k=i;k<j;k++)
			{
				if(dp[i][k]&&dp[i][k]==dp[k+1][j])dp[i][j]=dp[i][k]+1;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<dp[i][j]<<' ';
		}cout<<endl;
	}
	for(int i=1;i<=n;i++)
	{
		dp2[i]=1e9;
		for(int j=0;j<i;j++)
		{
			if(dp[j+1][i]&&dp2[j]+1<dp2[i])dp2[i]=dp2[j]+1;
		}
	}
	cout<<dp2[n];
}
int main()
{
	FAST
	ll test=1;
	// cin>>test;
	while(test--)
	{
		cin>>n;rep(i,1,n+1)cin>>a[i];
		solve();
		cout<<endl;
	}
}


#include <bits/stdc++.h>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define endl "\n"
#define rep(i, s, n)    for(ll i = s; i < (n); ++i)
#define F first
#define S second
#define ll long long
#define sz(a) a.size()
#define pii std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vvi vector<vi >
#define vii vector<pii >
#define vll vector<pll >
#define INF INT_MAX
#define inf 9e18
#define N int(2e5+5)
#define all(v) v.begin(),v.end()
#define mod 998244353

using namespace std;
int n;vector<int> v;
map<pair<int,vector<int>>,int> dp;
int f(int n,vector<int> v)
{
	int ans=0;
	bool fl=0;
	if(dp.count({n,v}))return dp[{n,v}];
	for(int i=0;i<n-1;i++)
	{
		if(v[i]==v[i+1])
		{
			fl=1;
			vector<int> t;v[i+1]+=1;
			rep(j,0,n)if(j!=i)t.pb(v[j]);
			ans=max(ans,1+f(n-1,t));
			v[i+1]-=1;
		}
	}
	if(!fl)return 0;
	return dp[{n,v}]=ans;
}
void solve()
{
	cout<<n-f(n,v);
}
int main()
{
	FAST
	ll test=1;
	// cin>>test;
	while(test--)
	{
		cin>>n;
		// n=500;
		v=vector<int>(n,0);
		// rep(i,0,n)v[i]=i;
		rep(i,0,n)cin>>v[i];
		solve();
		cout<<endl;
	}
}


#include <bits/stdc++.h>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define hell 1000000007
#define mp make_pair
#define pb push_back
#define endl "\n"
#define rep(i, s, n)    for(ll i = s; i < (n); ++i)
#define F first
#define S second
#define ll long long
#define sz(a) a.size()
#define pii std::pair<int, int>
#define pll std::pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define vvi vector<vi >
#define vii vector<pii >
#define vll vector<pll >
#define INF INT_MAX
#define inf 9e18
#define N int(2e5+5)
#define all(v) v.begin(),v.end()
#define mod 998244353

using namespace std;
int n;vector<int> v;
map<pair<int,vector<int>>,int> dp;
int f(int n,vector<int> v)
{
	int ans=0;
	bool fl=0;
	if(dp.count({n,v}))return dp[{n,v}];
	for(int i=0;i<n-1;i++)
	{
		if(v[i]==-1)continue;
		int j=i+1;
		while(v[j]==-1&&j<n)j++;
		// if(j==n)break;
		// cout<<j<<' ';
		if(v[i]==v[j])
		{
			fl=1;
			v[i]=-1;
			v[j]+=1;
			ans=max(ans,1+f(n,v));
			v[j]-=1;
		}i=j-1;
	}//cout<<endl;
	if(!fl)return 0;
	return dp[{n,v}]=ans;
}
void solve()
{
	cout<<n-f(n,v);
}
int main()
{
	FAST
	ll test=1;
	// cin>>test;
	while(test--)
	{
		cin>>n;
		// n=500;
		v=vector<int>(n,0);
		// rep(i,0,n)v[i]=i;
		rep(i,0,n)cin>>v[i];
		solve();
		cout<<endl;
	}
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <string>
using namespace std;
typedef long long int ll;
#define FOR(z,l,n) for(int z=l;z<n;z++)
void print(int a){cout<<a<<" ";}
void print(ll a){cout<<a<<" ";}
void print(double a){cout<<a<<" ";}
void print(string a){cout<<a<<" ";}
template<typename T1, typename T2>
void print(pair<T1,T2> a){print(a.first);cout<<" ::: ";print(a.second);}
template <typename Container>
void print(const Container& c){for(auto it = c.begin(); it!=c.end();it++){print(*it);}cout<<endl;}
void RUN();
void FORTCRUN(){int t;cin>>t;while(t--)RUN();}

int M = 998244353;
ll mul(ll a, ll b){return (a*b)%M;}
ll mpow(ll a,ll n){
    if(n==0)return 1;
    ll x=mpow(a,n/2);
    ll ans = mul(mul(x,x),(n&1)?a:1);
    return ans;
}
ll inv(ll x){return mpow(x, M-2);}
ll fac(ll n){
    ll ans =1;
    for(ll i=1;i<=n;i++)
        ans=mul(ans,i);
    return ans;
}
void RUN(){
    int n;
    cin>>n;
    vector<int> a(n+1);
    FOR(z,1,n+1)cin>>a[z];
    vector<vector<int>> dp(n+1,vector<int>(n+1,n+1));
    vector<vector<int>> val(n+1,vector<int>(n+1,-1));
    FOR(z,1,n+1){dp[z][z]=1;val[z][z]=a[z];}
    FOR(i,1,n){
        for(int j=1;j+i<n+1;j++){
            for(int k=j+1;k<=j+i;k++){
                if(dp[j][k-1]==1 && dp[k][j+i]==1 && val[j][k-1]==val[k][j+i] && val[k][j+i]!=-1){dp[j][j+i]=1;val[j][j+i]=val[k][j+i]+1;}
                else dp[j][j+i]=min(dp[j][j+i],dp[j][k-1]+dp[k][j+i]);
                //cout<<j<<" "<<j+i<<" "<<dp[j][j+i]<<endl;
            }
        }
    }

    cout<<dp[1][n]<<endl;
}
int main()
{
    RUN();
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <string>
using namespace std;
typedef long long int ll;
#define FOR(z,l,n) for(int z=l;z<n;z++)
void print(int a){cout<<a<<" ";}
void print(ll a){cout<<a<<" ";}
void print(double a){cout<<a<<" ";}
void print(string a){cout<<a<<" ";}
template<typename T1, typename T2>
void print(pair<T1,T2> a){print(a.first);cout<<" ::: ";print(a.second);}
template <typename Container>
void print(const Container& c){for(auto it = c.begin(); it!=c.end();it++){print(*it);}cout<<endl;}
void RUN();
void FORTCRUN(){int t;cin>>t;while(t--)RUN();}

int M = 998244353;
ll mul(ll a, ll b){return (a*b)%M;}
ll mpow(ll a,ll n){
    if(n==0)return 1;
    ll x=mpow(a,n/2);
    ll ans = mul(mul(x,x),(n&1)?a:1);
    return ans;
}
ll inv(ll x){return mpow(x, M-2);}
ll fac(ll n){
    ll ans =1;
    for(ll i=1;i<=n;i++)
        ans=mul(ans,i);
    return ans;
}
void RUN(){
    int n;
    cin>>n;
    vector<int> a(n+1);
    FOR(z,1,n+1)cin>>a[z];
    vector<vector<int>> dp(n+1,vector<int>(n+1,n+1));
    vector<vector<int>> val(n+1,vector<int>(n+1,-1));
    FOR(z,1,n+1){dp[z][z]=1;val[z][z]=a[z];}
    FOR(i,1,n){
        for(int j=1;j+i<n+1;j++){
            for(int k=j+1;k<=j+i;k++){
                if(dp[j][k-1]==1 && dp[k][j+i]==1 && val[j][k-1]==val[k][j+i] && val[k][j+i]!=1){dp[j][j+i]=1;val[j][j+i]=val[k][j+i]+1;}
                else dp[j][j+i]=min(dp[j][j+i],dp[j][k-1]+dp[k][j+i]);
                //cout<<j<<" "<<j+i<<" "<<dp[j][j+i]<<endl;
            }
        }
    }

    cout<<dp[1][n]<<endl;
}
int main()
{
    FORTCRUN();
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <string>
using namespace std;
typedef long long int ll;
#define FOR(z,l,n) for(int z=l;z<n;z++)
void print(int a){cout<<a<<" ";}
void print(ll a){cout<<a<<" ";}
void print(double a){cout<<a<<" ";}
void print(string a){cout<<a<<" ";}
template<typename T1, typename T2>
void print(pair<T1,T2> a){print(a.first);cout<<" ::: ";print(a.second);}
template <typename Container>
void print(const Container& c){for(auto it = c.begin(); it!=c.end();it++){print(*it);}cout<<endl;}
void RUN();
void FORTCRUN(){int t;cin>>t;while(t--)RUN();}

int M = 998244353;
ll mul(ll a, ll b){return (a*b)%M;}
ll mpow(ll a,ll n){
    if(n==0)return 1;
    ll x=mpow(a,n/2);
    ll ans = mul(mul(x,x),(n&1)?a:1);
    return ans;
}
ll inv(ll x){return mpow(x, M-2);}
ll fac(ll n){
    ll ans =1;
    for(ll i=1;i<=n;i++)
        ans=mul(ans,i);
    return ans;
}
void RUN(){
    int n;
    cin>>n;
    vector<int> a(n+1);
    FOR(z,1,n+1)cin>>a[z];
    vector<vector<int>> dp(n+1,vector<int>(n+1,n+1));
    vector<vector<int>> val(n+1,vector<int>(n+1,-1));
    FOR(z,1,n+1){dp[z][z]=1;val[z][z]=a[z];}
    FOR(i,1,n){
        for(int j=1;j+i<n+1;j++){
            for(int k=j+1;k<=j+i;k++){
                if(dp[j][k-1]==1 && dp[k][j+i]==1 && val[j][k-1]==val[k][j+i] && val[k][j+i]!=1){dp[j][j+i]=1;val[j][j+i]=val[k][j+i]+1;}
                else dp[j][j+i]=min(dp[j][j+i],dp[j][k-1]+dp[k][j+i]);
                //cout<<j<<" "<<j+i<<" "<<dp[j][j+i]<<endl;
            }
        }
    }

    cout<<dp[1][n]<<endl;
}
int main()
{
    RUN();
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <set>
#include <string>
using namespace std;
typedef long long int ll;
#define FOR(z,l,n) for(int z=l;z<n;z++)
void print(int a){cout<<a<<" ";}
void print(ll a){cout<<a<<" ";}
void print(double a){cout<<a<<" ";}
void print(string a){cout<<a<<" ";}
template<typename T1, typename T2>
void print(pair<T1,T2> a){print(a.first);cout<<" ::: ";print(a.second);}
template <typename Container>
void print(const Container& c){for(auto it = c.begin(); it!=c.end();it++){print(*it);}cout<<endl;}
void RUN();
void FORTCRUN(){int t;cin>>t;while(t--)RUN();}

int M = 998244353;
ll mul(ll a, ll b){return (a*b)%M;}
ll mpow(ll a,ll n){
    if(n==0)return 1;
    ll x=mpow(a,n/2);
    ll ans = mul(mul(x,x),(n&1)?a:1);
    return ans;
}
ll inv(ll x){return mpow(x, M-2);}
ll fac(ll n){
    ll ans =1;
    for(ll i=1;i<=n;i++)
        ans=mul(ans,i);
    return ans;
}
void RUN(){
    int n;
    cin>>n;
    vector<int> a(n+1);
    FOR(z,1,n+1)cin>>a[z];
    vector<vector<int>> dp(n+1,vector<int>(n+1,n+1));
    vector<vector<int>> val(n+1,vector<int>(n+1,-1));
    FOR(z,1,n+1){dp[z][z]=1;val[z][z]=a[z];}
    FOR(i,1,n){
        for(int j=1;j+i<n+1;j++){
            for(int k=j+1;k<=j+i;k++){
                if(dp[j][k-1]==1 && dp[k][j+i]==1 && val[j][k-1]==val[k][j+i] && val[k][j+i]!=-1){dp[j][j+i]=1;val[j][j+i]=val[k][j+i]+1;}
                else dp[j][j+i]=min(dp[j][j+i],dp[j][k-1]+dp[k][j+i]);
                //cout<<j<<" "<<j+i<<" "<<dp[j][j+i]<<endl;
            }
        }
    }

    cout<<dp[1][n]<<endl;
}
int main()
{
    FORTCRUN();
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;

int solve(vector<pii> v){
    if(v.size()==0) return 0;
    if(v.size()==1) return __builtin_popcount(v[0].second);
    int n = v.size();
    int m = v[0].first;
    int ret = 0;
    for(int i=0;i<n;i++){
        m = min(m, v[i].first);
        ret += v[i].second;
    }
    for(int i=0;i<n;i++){
        if(v[i].first==m){
            if(v[i].second%2){
                vector<pii> u = vector<pii>(v.begin(), v.begin()+i);
                vector<pii> w = vector<pii>(v.begin()+i+1, v.end());
                if(!u.empty() and u.back().first==m+1){
                    u.back().second += v[i].second/2;
                    ret = min(ret, solve(u)+1+solve(w));
                    u.back().second -= v[i].second/2;
                }else{
                    u.emplace_back(v[i].first+1, v[i].second/2);
                    ret = min(ret, solve(u)+1+solve(w));
                    u.pop_back();
                }
                if(!w.empty() and w[0].first==m+1){
                    w[0].second += v[i].second/2;
                    ret = min(ret, solve(u)+v[i].second%2+solve(w));
                    w[0].second -= v[i].second/2;
                }else{
                    w.insert(w.begin(), {v[i].first+1, v[i].second/2});
                    ret = min(ret, solve(u)+1+solve(w));
                    w.erase(w.begin());
                }
            }else{
                vector<pii> u = v, w;
                u[i].first++;
                u[i].second/=2;
                for(auto a:u){
                    if(w.empty() or w.back().first!=a.first){
                        w.push_back(a);
                    }else{
                        w.back().second += a.second;
                    }
                }
                ret = min(ret, solve(w));
            }
        }
    }
    return ret;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    int x; cin>>x;
    int cnt = 1;
    vector<pii> v;
    for(int i=0;i<n-1;i++){
        int y; cin>>y;
        if(x==y) cnt++;
        else{
            v.emplace_back(x, cnt);
            x = y;
            cnt = 1;
        }
    }
    v.emplace_back(x, cnt);
    cout<<solve(v);
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;

int solve(vector<pii> v){
    if(v.size()==0) return 0;
    if(v.size()==1) return __builtin_popcount(v[0].second);
    int n = v.size();
    int m = v[0].first;
    bool pos = false;
    for(int i=0;i<n;i++){
        if(v[i].second>1) pos = true;
    }
    if(!pos) return n;
    int ret = 0;
    for(int i=0;i<n;i++){
        m = min(m, v[i].first);
        ret += v[i].second;
    }
    for(int i=0;i<n;i++){
        if(v[i].first==m){
            if(v[i].second%2){
                vector<pii> u = vector<pii>(v.begin(), v.begin()+i);
                vector<pii> w = vector<pii>(v.begin()+i+1, v.end());
                if(!u.empty() and u.back().first==m+1){
                    u.back().second += v[i].second/2;
                    ret = min(ret, solve(u)+1+solve(w));
                    u.back().second -= v[i].second/2;
                }else{
                    u.emplace_back(v[i].first+1, v[i].second/2);
                    ret = min(ret, solve(u)+1+solve(w));
                    u.pop_back();
                }
                if(!w.empty() and w[0].first==m+1){
                    w[0].second += v[i].second/2;
                    ret = min(ret, solve(u)+v[i].second%2+solve(w));
                    w[0].second -= v[i].second/2;
                }else{
                    w.insert(w.begin(), {v[i].first+1, v[i].second/2});
                    ret = min(ret, solve(u)+1+solve(w));
                    w.erase(w.begin());
                }
            }else{
                vector<pii> u = v;
                u[i].first++;
                u[i].second/=2;
                if(i<n-1 and u[i+1].first==u[i].first){
                    u[i].second += u[i+1].second;
                    u.erase(u.begin()+i+1);
                }
                if(i>0 and u[i-1].first==u[i].first){
                    u[i-1].second += u[i].second;
                    u.erase(u.begin()+i);
                }
                ret = min(ret, solve(u));
            }
        }
    }
    return ret;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    int x; cin>>x;
    int cnt = 1;
    vector<pii> v;
    for(int i=0;i<n-1;i++){
        int y; cin>>y;
        if(x==y) cnt++;
        else{
            v.emplace_back(x, cnt);
            x = y;
            cnt = 1;
        }
    }
    v.emplace_back(x, cnt);
    cout<<solve(v);
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;

int solve(vector<pii> v){
    if(v.size()==0) return 0;
    int n = v.size();
    int m = v[0].first;
    bool pos = false;
    for(int i=0;i<n;i++){
        if(v[i].second>1) pos = true;
    }
    if(!pos) return n;
    int ret = 0;
    for(int i=0;i<n;i++){
        m = min(m, v[i].first);
        ret += v[i].second;
    }

    for(int i=0;i<n;i++){
        if(v[i].first==m){
            if(v[i].second%2){
                vector<pii> u = vector<pii>(v.begin(), v.begin()+i);
                vector<pii> w = vector<pii>(v.begin()+i+1, v.end());
                if(!u.empty() and u.back().first==m+1){
                    u.back().second += v[i].second/2;
                    ret = min(ret, solve(u)+1+solve(w));
                    u.back().second -= v[i].second/2;
                }else{
                    u.emplace_back(v[i].first+1, v[i].second/2);
                    ret = min(ret, solve(u)+1+solve(w));
                    u.pop_back();
                }
                if(!w.empty() and w[0].first==m+1){
                    w[0].second += v[i].second/2;
                    ret = min(ret, solve(u)+v[i].second%2+solve(w));
                    w[0].second -= v[i].second/2;
                }else{
                    w.insert(w.begin(), {v[i].first+1, v[i].second/2});
                    ret = min(ret, solve(u)+1+solve(w));
                    w.erase(w.begin());
                }
            }else{
                vector<pii> u = v, w;
                u[i].first++;
                u[i].second/=2;
                for(auto a:u){
                    if(w.empty() or w.back().first!=a.first){
                        w.push_back(a);
                    }else{
                        w.back().second += a.second;
                    }
                }
                ret = min(ret, solve(w));
            }
        }
    }
    return ret;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    int x; cin>>x;
    int cnt = 1;
    vector<pii> v;
    for(int i=0;i<n-1;i++){
        int y; cin>>y;
        if(x==y) cnt++;
        else{
            v.emplace_back(x, cnt);
            x = y;
            cnt = 1;
        }
    }
    v.emplace_back(x, cnt);
    cout<<solve(v);
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 505;
int a[MAXN];
int dp[MAXN][MAXN], dp2[MAXN];

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        dp[i][i] = a[i];
    }
    for(int i=n-2;i>=0;i--){
        for(int j=i+1;j<n;j++){
            dp[i][j] = -1;
            for(int k=i;k<j;k++){
                if(~dp[i][k] and dp[i][k]==dp[k+1][j]){
                    dp[i][j] = dp[i][k]+1;
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        dp2[i] = 1e9;
        for(int j=0;j<i;j++){
            if(~dp[j][i-1]){
                dp2[i] = min(dp2[i], dp2[j]+1);
            }
        }
    }
    cout<<dp2[n];
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;

int solve(vector<pii> v){
    if(v.size()==0) return 0;
    int n = v.size();
    int m = v[0].first;
    bool pos = false;
    for(int i=0;i<n;i++){
        if(v[i].second>1) pos = true;
    }
    if(!pos) return n;
    int ret = 0;
    for(int i=0;i<n;i++){
        m = min(m, v[i].first);
        ret += v[i].second;
    }

    for(int i=0;i<n;i++){
        if(v[i].first==m){
            if(v[i].second%2){
                vector<pii> u = vector<pii>(v.begin(), v.begin()+i);
                vector<pii> w = vector<pii>(v.begin()+i+1, v.end());
                if(!u.empty() and u.back().first==m+1){
                        u.back().second += v[i].second/2;
                        ret = min(ret, solve(u)+v[i].second%2+solve(w));
                        u.back().second -= v[i].second/2;
                }else{
                    u.emplace_back(v[i].first, v[i].second/2);
                    ret = min(ret, solve(u)+v[i].second%2+solve(w));
                }
                if(!w.empty() and w[0].first==m+1){
                        w[0].second += v[i].second/2;
                        ret = min(ret, solve(u)+v[i].second%2+solve(w));
                        w[0].second -= v[i].second/2;
                }else{
                    u.emplace_back(v[i].first, v[i].second/2);
                    ret = min(ret, solve(u)+v[i].second%2+solve(w));
                }
            }else{
                vector<pii> u = v, w;
                u[i].first++;
                u[i].second/=2;
                for(auto a:u){
                    if(w.empty() or w.back().first!=a.first){
                        w.push_back(a);
                    }else{
                        w.back().second += a.second;
                    }
                }
                ret = min(ret, solve(w));
            }
        }
    }
    return ret;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    int x; cin>>x;
    int cnt = 1;
    vector<pii> v;
    for(int i=0;i<n-1;i++){
        int y; cin>>y;
        if(x==y) cnt++;
        else{
            v.emplace_back(x, cnt);
            x = y;
            cnt = 1;
        }
    }
    v.emplace_back(x, cnt);
    cout<<solve(v);
}


#include <bits/stdc++.h>

#define int long long
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc + 1000], res[maxc + 1000];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    res[n] = 1;
    for (int i = n - 1; i >= 1; --i)
    {
        res[i] = inf;
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    vector<int> res(n + 1, inf);
    res[n] = 1;
    for (int i = n - 1; i >= 1; i--)
    {
        for (int j = 1; j <= m; j++)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    vector<int> res(n + 1, inf);
    res[n] = 1;
    for (int i = n - 1; i >= 1; i--)
    {
        for (int j = 1; j <= m; j++)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define int long long
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc + 1000], res[maxc + 1000];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    res[n] = 1;
    for (int i = n - 1; i >= 1; --i)
    {
        res[i] = inf;
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x])
                res[i] = min(res[i], res[dp[i][x] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define int long long
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxc + 1000][maxc + 1000], res[maxc + 1000];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    res[n] = 1;
    for (int i = n - 1; i >= 1; --i)
    {
        res[i] = inf;
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x])
                res[i] = min(res[i], res[dp[i][x] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define int long long
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc], res[maxc];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    for (int i = 0; i < maxc; ++i) res[i] = inf;
    res[n] = 1;
    for (int i = n - 1; i >= 1; i--)
    {
        for (int j = 1; j < maxc; j++)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define int long long
#define double long double
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) cin >> a[i];
    while (true)
    {
        int val = inf, pos = -1;
        for (int i = 0; i + 1 < sz(a); ++i)
        {
            if (a[i] == a[i + 1] && a[i] < val)
            {
                val = a[i];
                pos = i;
            }
        }
        if (pos == -1) break;
        vector<int> an;
        for (int i = 0; i < pos; ++i) an.pb(a[i]);
        an.pb(a[pos] + 1);
        for (int i = pos + 2; i < sz(a); ++i) an.pb(a[i]);
        a = an;
    }
    cout << sz(a);
    return 0;
}


#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e9;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    vector<int> res(n + 1, inf);
    res[n] = 1;
    for (int i = n - 1; i >= 1; i--)
    {
        for (int j = 1; j < maxc; j++)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    vector<int> res(n + 1, inf);
    res[n] = 1;
    for (int i = n - 1; i >= 1; i--)
    {
        for (int j = 1; j < maxc; j++)
        {
            if (dp[i][j])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


#include <bits/stdc++.h>

#define int long long
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

using namespace std;

mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count() + 'd'+'o'+'i'+'n'+'g' + 'g'+'e'+'y');

const int inf = 1e18;
const double eps = 1e-6;
const int maxn = 501;
const int maxc = 1501;

int dp[maxn][maxc + 1000], res[maxc + 1000];

signed main()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i < n + 1; ++i) cin >> a[i];
    dp[n][a[n]] = n;
    for (int i = n - 1; i >= 1; --i)
    {
        dp[i][a[i]] = i;
        if (dp[i + 1][a[i]])
            dp[i][a[i] + 1] = dp[i + 1][a[i]];
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x] && dp[dp[i][x] + 1][x])
                dp[i][x + 1] = dp[dp[i][x] + 1][x];
        }
    }
    res[n] = 1;
    for (int i = n - 1; i >= 1; --i)
    {
        res[i] = inf;
        for (int x = 1; x < maxc; ++x)
        {
            if (dp[i][x])
                res[i] = min(res[i], res[dp[i][j] + 1] + 1);
        }
    }
    cout << res[1];
    return 0;
}


// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using namespace std;

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define FOREACH(i,q) for (auto &i : q)
template<class T> bool chmax(T &a, const T b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T b) { if (a > b) {a = b; return true;} return false; }
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q,t,f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) { if (is_integral<T>() || is_floating_point<T>()) cerr << "\e[32m" << x << "\e[m"; else cerr << x; }
template<> void DUMP_PROC<char>(char x) { cerr << "\e[36m\'" << x << "\'\e[m"; }
template<> void DUMP_PROC<string>(string x) { cerr << "\e[33m\"" << x << "\"\e[m"; }
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) { cerr << "{"; DUMP_PROC(x.first); cerr << ", "; DUMP_PROC(x.second); cerr << "}"; }
template <typename ...T, typename U, U... Seq> void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) { (void)(int[]){(cerr << (const char*[]){"", ", "}[!!Seq] << (DUMP_PROC(get<Seq>(x)), ""), 0)...}; }
template <typename ...T> void DUMP_PROC(tuple<T...> x) {cerr << "{"; DUMP_PROC(x, index_sequence_for<T...>()); cerr << "}";}
template <typename T> void DUMP_PROC(vector<T> x) { cerr << "["; for (auto &xi : x) { DUMP_PROC(xi); cerr << (&xi != &*x.rbegin()?", ":""); } cerr << "]"; }
template <typename T> void DUMP_FUNC(T x, const char* name, const char* fn, int ln) { cerr << "\e[32m[DEBUG]\e[m " << name << ": "; DUMP_PROC(x); cerr << " @ " << fn << "(" << ln << ")" << endl; }
template <class T> T gcd(T a, T b) { if (a < b) swap(a, b); while (b) swap(a %= b, b); return a; }
template <class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
    size_t sz;
    qin(size_t _sz = 1) : sz(_sz) {}
    template <typename T> operator T () const { T a; cin >> a; return a; }
    template <typename T> operator vector<T> () const { vector<T> a(sz); for (size_t i = 0; i < sz; i++) cin >> a[i]; return a; }
    template <typename T, typename U> operator pair<T, U> () const { T f; U s; cin >> f >> s; return pair<T, U>(f, s); }
};
qin in1; // input one
template <typename T> void say(const T x, const char* end = "\n") { cout << x << end; }
void say(const ld x, const char* end = "\n") { cout << setprecision(30) << x << end; }
template <typename T> void say(const vector<T> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { cout << x[i] << (i+1 == i_len ? end : sep); } }
template <typename T> void say(const vector<vector<T>> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { say(x[i], sep, end); } }

// モジュール

// 処理内容
int main() {

    ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
    cin.tie(nullptr);            // インタラクティブ問題ではコメントアウトすること

    ll n = in1;
    vector<ll> a = qin(n);

    while (n > 1) {
        ll cand = -1, height = INF, hdiff = INF, hdiff2 = -INF;
        REP(i, n-1) {
            if (a[i] != a[i+1]) continue;
            ll diffmin = INF, diffmax = -INF;
            if (i-1 >= 0) chmin(diffmin, abs(a[i-1]-a[i]-1)), chmax(diffmax, a[i-1]-a[i]);
            if (i+2 <  n) chmin(diffmin, abs(a[i+2]-a[i]-1)), chmax(diffmax, a[i+2]-a[i]);
            if (chmin(height, a[i])) {
                cand = i;
                hdiff = diffmin;
                hdiff2 = diffmax;
            } else if (height == a[i]) {
                if (chmin(hdiff, diffmin)) {
                    cand = i;
                    hdiff2 = diffmax;
                } else if (hdiff == diffmin && chmax(hdiff2, diffmax)) {
                    cand = i;
                }
            }
        }
        if (cand == -1) break;
        a.erase(a.begin() + cand);
        a[cand]++;
        n--;
        DUMP(a);
    }
    say(n);

}


// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using namespace std;

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define FOREACH(i,q) for (auto &i : q)
template<class T> bool chmax(T &a, const T b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T b) { if (a > b) {a = b; return true;} return false; }
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q,t,f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) { if (is_integral<T>() || is_floating_point<T>()) cerr << "\e[32m" << x << "\e[m"; else cerr << x; }
template<> void DUMP_PROC<char>(char x) { cerr << "\e[36m\'" << x << "\'\e[m"; }
template<> void DUMP_PROC<string>(string x) { cerr << "\e[33m\"" << x << "\"\e[m"; }
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) { cerr << "{"; DUMP_PROC(x.first); cerr << ", "; DUMP_PROC(x.second); cerr << "}"; }
template <typename ...T, typename U, U... Seq> void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) { (void)(int[]){(cerr << (const char*[]){"", ", "}[!!Seq] << (DUMP_PROC(get<Seq>(x)), ""), 0)...}; }
template <typename ...T> void DUMP_PROC(tuple<T...> x) {cerr << "{"; DUMP_PROC(x, index_sequence_for<T...>()); cerr << "}";}
template <typename T> void DUMP_PROC(vector<T> x) { cerr << "["; for (auto &xi : x) { DUMP_PROC(xi); cerr << (&xi != &*x.rbegin()?", ":""); } cerr << "]"; }
template <typename T> void DUMP_FUNC(T x, const char* name, const char* fn, int ln) { cerr << "\e[32m[DEBUG]\e[m " << name << ": "; DUMP_PROC(x); cerr << " @ " << fn << "(" << ln << ")" << endl; }
template <class T> T gcd(T a, T b) { if (a < b) swap(a, b); while (b) swap(a %= b, b); return a; }
template <class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
    size_t sz;
    qin(size_t _sz = 1) : sz(_sz) {}
    template <typename T> operator T () const { T a; cin >> a; return a; }
    template <typename T> operator vector<T> () const { vector<T> a(sz); for (size_t i = 0; i < sz; i++) cin >> a[i]; return a; }
    template <typename T, typename U> operator pair<T, U> () const { T f; U s; cin >> f >> s; return pair<T, U>(f, s); }
};
qin in1; // input one
template <typename T> void say(const T x, const char* end = "\n") { cout << x << end; }
void say(const ld x, const char* end = "\n") { cout << setprecision(30) << x << end; }
template <typename T> void say(const vector<T> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { cout << x[i] << (i+1 == i_len ? end : sep); } }
template <typename T> void say(const vector<vector<T>> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { say(x[i], sep, end); } }

// モジュール

// 処理内容
int main() {

    ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
    cin.tie(nullptr);            // インタラクティブ問題ではコメントアウトすること

    ll n = in1;
    vector<ll> a = qin(n);

    while (n > 1) {
        ll cand = -1, cnmin = INF, cnmax = INF;
        REP(i, n-1) {
            if (a[i] != a[i+1]) continue;
            ll ngbmax = INF, ngbmin = a[i];
            if (i-1 >= 0) chmin(ngbmax, abs(a[i-1]-a[i]-1));
            if (i+2 <  n) chmin(ngbmax, abs(a[i+2]-a[i]-1));
            if (chmin(cnmin, ngbmin)) {
                cand = i;
                cnmax = ngbmin;
            } else if (cnmin == ngbmin && chmin(cnmax, ngbmax)) {
                cand = i;
            }
        }
        if (cand == -1) break;
        a.erase(a.begin() + cand);
        a[cand]++;
    }
    say(n);

}


// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using namespace std;

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define FOREACH(i,q) for (auto &i : q)
template<class T> bool chmax(T &a, const T b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T b) { if (a > b) {a = b; return true;} return false; }
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q,t,f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) { if (is_integral<T>() || is_floating_point<T>()) cerr << "\e[32m" << x << "\e[m"; else cerr << x; }
template<> void DUMP_PROC<char>(char x) { cerr << "\e[36m\'" << x << "\'\e[m"; }
template<> void DUMP_PROC<string>(string x) { cerr << "\e[33m\"" << x << "\"\e[m"; }
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) { cerr << "{"; DUMP_PROC(x.first); cerr << ", "; DUMP_PROC(x.second); cerr << "}"; }
template <typename ...T, typename U, U... Seq> void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) { (void)(int[]){(cerr << (const char*[]){"", ", "}[!!Seq] << (DUMP_PROC(get<Seq>(x)), ""), 0)...}; }
template <typename ...T> void DUMP_PROC(tuple<T...> x) {cerr << "{"; DUMP_PROC(x, index_sequence_for<T...>()); cerr << "}";}
template <typename T> void DUMP_PROC(vector<T> x) { cerr << "["; for (auto &xi : x) { DUMP_PROC(xi); cerr << (&xi != &*x.rbegin()?", ":""); } cerr << "]"; }
template <typename T> void DUMP_FUNC(T x, const char* name, const char* fn, int ln) { cerr << "\e[32m[DEBUG]\e[m " << name << ": "; DUMP_PROC(x); cerr << " @ " << fn << "(" << ln << ")" << endl; }
template <class T> T gcd(T a, T b) { if (a < b) swap(a, b); while (b) swap(a %= b, b); return a; }
template <class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
    size_t sz;
    qin(size_t _sz = 1) : sz(_sz) {}
    template <typename T> operator T () const { T a; cin >> a; return a; }
    template <typename T> operator vector<T> () const { vector<T> a(sz); for (size_t i = 0; i < sz; i++) cin >> a[i]; return a; }
    template <typename T, typename U> operator pair<T, U> () const { T f; U s; cin >> f >> s; return pair<T, U>(f, s); }
};
qin in1; // input one
template <typename T> void say(const T x, const char* end = "\n") { cout << x << end; }
void say(const ld x, const char* end = "\n") { cout << setprecision(30) << x << end; }
template <typename T> void say(const vector<T> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { cout << x[i] << (i+1 == i_len ? end : sep); } }
template <typename T> void say(const vector<vector<T>> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { say(x[i], sep, end); } }

// モジュール

// 処理内容
int main() {

    ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
    cin.tie(nullptr);            // インタラクティブ問題ではコメントアウトすること

    ll n = in1;
    vector<ll> a = qin(n);

    while (n > 1) {
        ll cand = -1, cnmin = INF, cnmax = INF;
        REP(i, n-1) {
            if (a[i] != a[i+1]) continue;
            ll ngbmax = 0, ngbmin = a[i];
            if (i-1 >= 0) chmin(ngbmax, abs(a[i-1]-a[i]-1));
            if (i+2 <  n) chmin(ngbmax, abs(a[i+2]-a[i]-1));
            if (chmin(cnmin, ngbmin)) {
                cand = i;
                cnmax = ngbmin;
            } else if (cnmin == ngbmin && chmin(cnmax, ngbmax)) {
                cand = i;
            }
        }
        if (cand == -1) break;
        a.erase(a.begin() + cand);
        a[cand]++;
        n--;
    }
    say(n);

}


// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using namespace std;

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define FOREACH(i,q) for (auto &i : q)
template<class T> bool chmax(T &a, const T b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T b) { if (a > b) {a = b; return true;} return false; }
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q,t,f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) { if (is_integral<T>() || is_floating_point<T>()) cerr << "\e[32m" << x << "\e[m"; else cerr << x; }
template<> void DUMP_PROC<char>(char x) { cerr << "\e[36m\'" << x << "\'\e[m"; }
template<> void DUMP_PROC<string>(string x) { cerr << "\e[33m\"" << x << "\"\e[m"; }
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) { cerr << "{"; DUMP_PROC(x.first); cerr << ", "; DUMP_PROC(x.second); cerr << "}"; }
template <typename ...T, typename U, U... Seq> void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) { (void)(int[]){(cerr << (const char*[]){"", ", "}[!!Seq] << (DUMP_PROC(get<Seq>(x)), ""), 0)...}; }
template <typename ...T> void DUMP_PROC(tuple<T...> x) {cerr << "{"; DUMP_PROC(x, index_sequence_for<T...>()); cerr << "}";}
template <typename T> void DUMP_PROC(vector<T> x) { cerr << "["; for (auto &xi : x) { DUMP_PROC(xi); cerr << (&xi != &*x.rbegin()?", ":""); } cerr << "]"; }
template <typename T> void DUMP_FUNC(T x, const char* name, const char* fn, int ln) { cerr << "\e[32m[DEBUG]\e[m " << name << ": "; DUMP_PROC(x); cerr << " @ " << fn << "(" << ln << ")" << endl; }
template <class T> T gcd(T a, T b) { if (a < b) swap(a, b); while (b) swap(a %= b, b); return a; }
template <class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
    size_t sz;
    qin(size_t _sz = 1) : sz(_sz) {}
    template <typename T> operator T () const { T a; cin >> a; return a; }
    template <typename T> operator vector<T> () const { vector<T> a(sz); for (size_t i = 0; i < sz; i++) cin >> a[i]; return a; }
    template <typename T, typename U> operator pair<T, U> () const { T f; U s; cin >> f >> s; return pair<T, U>(f, s); }
};
qin in1; // input one
template <typename T> void say(const T x, const char* end = "\n") { cout << x << end; }
void say(const ld x, const char* end = "\n") { cout << setprecision(30) << x << end; }
template <typename T> void say(const vector<T> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { cout << x[i] << (i+1 == i_len ? end : sep); } }
template <typename T> void say(const vector<vector<T>> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { say(x[i], sep, end); } }

// モジュール

// 処理内容
int main() {

    ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
    cin.tie(nullptr);            // インタラクティブ問題ではコメントアウトすること

    ll n = in1;
    vector<ll> a = qin(n);
    vector<vector<ll>> len(n, vector<ll>(n+1, INF));
    vector<vector<ll>> val(n, vector<ll>(n+1, -1));
    REP(i, n) len[i][i+1] = 1, val[i][i+1] = a[i];

    RANGE(lnew, 2, n) {
        // merge [l, c) and [c, r) (r-l==lnew)
        RANGE(l, 0, n - lnew) {
            ll r = l + lnew;
            RANGE(c, l+1, r-1) {
                if (val[l][c] == val[c][r] && len[l][c] == 1 && len[c][r] == 1) {
                    len[l][r] = 1;
                    val[l][r] = val[l][c] + 1;
                } else {
                    chmin(len[l][r], len[l][c] + len[c][r]);
                }
            }
        }
    }
    say(len[0][n]);

}


// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using  ll = long signed long;
using ull = long unsigned long;
using  ld = long double;
using namespace std;

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
#define FOREACH(i,q) for (auto &i : q)
template<class T> bool chmax(T &a, const T b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T b) { if (a > b) {a = b; return true;} return false; }
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q,t,f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) { if (is_integral<T>() || is_floating_point<T>()) cerr << "\e[32m" << x << "\e[m"; else cerr << x; }
template<> void DUMP_PROC<char>(char x) { cerr << "\e[36m\'" << x << "\'\e[m"; }
template<> void DUMP_PROC<string>(string x) { cerr << "\e[33m\"" << x << "\"\e[m"; }
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) { cerr << "{"; DUMP_PROC(x.first); cerr << ", "; DUMP_PROC(x.second); cerr << "}"; }
template <typename ...T, typename U, U... Seq> void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) { (void)(int[]){(cerr << (const char*[]){"", ", "}[!!Seq] << (DUMP_PROC(get<Seq>(x)), ""), 0)...}; }
template <typename ...T> void DUMP_PROC(tuple<T...> x) {cerr << "{"; DUMP_PROC(x, index_sequence_for<T...>()); cerr << "}";}
template <typename T> void DUMP_PROC(vector<T> x) { cerr << "["; for (auto &xi : x) { DUMP_PROC(xi); cerr << (&xi != &*x.rbegin()?", ":""); } cerr << "]"; }
template <typename T> void DUMP_FUNC(T x, const char* name, const char* fn, int ln) { cerr << "\e[32m[DEBUG]\e[m " << name << ": "; DUMP_PROC(x); cerr << " @ " << fn << "(" << ln << ")" << endl; }
template <class T> T gcd(T a, T b) { if (a < b) swap(a, b); while (b) swap(a %= b, b); return a; }
template <class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
    size_t sz;
    qin(size_t _sz = 1) : sz(_sz) {}
    template <typename T> operator T () const { T a; cin >> a; return a; }
    template <typename T> operator vector<T> () const { vector<T> a(sz); for (size_t i = 0; i < sz; i++) cin >> a[i]; return a; }
    template <typename T, typename U> operator pair<T, U> () const { T f; U s; cin >> f >> s; return pair<T, U>(f, s); }
};
qin in1; // input one
template <typename T> void say(const T x, const char* end = "\n") { cout << x << end; }
void say(const ld x, const char* end = "\n") { cout << setprecision(30) << x << end; }
template <typename T> void say(const vector<T> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { cout << x[i] << (i+1 == i_len ? end : sep); } }
template <typename T> void say(const vector<vector<T>> x, const char* sep = " ", const char* end = "\n") { REP(i, x.size()) { say(x[i], sep, end); } }

// モジュール

// 処理内容
int main() {

    ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
    cin.tie(nullptr);            // インタラクティブ問題ではコメントアウトすること

    ll n = in1;
    vector<ll> a = qin(n);

    while (n > 1) {
        ll cand = -1, cnmin = INF, cnmax = -INF;
        REP(i, n-1) {
            if (a[i] != a[i+1]) continue;
            ll ngbmax = 0, ngbmin = a[i];
            if (i-1 >= 0) chmax(ngbmax, a[i-1]);
            if (i+2 <  n) chmax(ngbmax, a[i+2]);
            if (chmin(cnmin, ngbmin)) {
                cand = i;
                cnmax = ngbmin;
            } else if (cnmin == ngbmin && chmax(cnmax, ngbmax)) {
                cand = i;
            }
        }
        if (cand == -1) break;
        a.erase(a.begin() + cand);
        a[cand]++;
        n--;
        DUMP(a);
    }
    say(n);

}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <stack>

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int arr[512];
int combined[512][512];
//combined[i][j] = if from ai..aj can be combined => combined #
//o.w. 0
int sol[512];
//sol[i] = smallest ai, ai+1, ... an

//main idea from loongnight
int main()
{
	int n;
	int cur;
	stack<int> S;
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> arr[i];

	for (int i = n; i !=0; i--) {
		combined[i][i] = arr[i];
		S.push(arr[i]);
		for (int j = i+1; j <=n; j++) {
			cur = arr[j];
			while (!S.empty() && S.top() == cur) {
				cur++;
				S.pop();
			}
			combined[i][j] = S.size() == 0 ? cur : 0;
			S.push(cur);
		}
		while (!S.empty()) S.pop();
	}

	//sol[n+1] = 0
	for (int i = n; i != 0; i--) {
		sol[i] = sol[i + 1] + 1;
		for (int j = i+1; j <= n; j++) {
			if (combined[i][j] == 0) continue;
			sol[i] = std::min( sol[i], sol[j + 1] + 1);
		}
	}
	cout << sol[1];
	return 0;
}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int arr[512];
int main()
{
	int n;
	int temp;
	int cnt = 0;
	int prev, prevPos;
	ios_base::sync_with_stdio(false);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}
	for (int j = 1; j <= 1024; j++) {
		prevPos = -1;
		for (int i = 0; i < n; i++) {
			if (arr[i] == -1) continue;
			if (arr[i] != j) {
				prevPos = -1;
				continue;
			}
			if (prevPos != -1) {
				arr[prevPos] = -1;
				arr[i]++;
				prevPos = -1;
				cnt++;
			}
			else {
				prevPos = i;
			}

		}
	}

	cout << n - cnt << '\n';
	return 0;
}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <stack>

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int arr[512];
int combined[512][512];
//combined[i][j] = if from ai..aj can be combined => combined #
//o.w. 0
int sol[512];
//sol[i] = smallest ai, ai+1, ... an

//main idea from loongnight
int main()
{
	int n;
	int cur;
	stack<int> S;
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> arr[i];

	for (int i = n; i !=0; i--) {
		combined[i][i] = arr[i];
		S.push(arr[i]);
		for (int j = i+1; j <=n; j++) {
			cur = arr[j];
			while (!S.empty() && S.top() == cur) {
				cur++;
				S.pop();
			}
			combined[i][j] = S.size() == 0 ? cur : 0;
			S.push(cur);
		}
		while (!S.empty()) S.pop();
	}

	//sol[n+1] = 0
	for (int i = n; i != 0; i--) {
		sol[i] = sol[i + 1] + 1;
		for (int j = i+1; j <= n; j++) {
			if (combined[i][j] == 0) continue;
			sol[i] = sol[j + 1] + 1;
		}
	}
	cout << sol[1];
	return 0;
}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int arr[512];
int main()
{
	int n;
	int temp;
	int cnt = 0;
	int prev, prevPos;
	ios_base::sync_with_stdio(false);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}
	for (int j = 1; j <= 1024; j++) {
		prevPos = -1;
		for (int i = 0; i < n; i++) {
			if (arr[i] == -1) continue;
			if (arr[i] != j) {
				prevPos = -1;
				continue;
			}
			if (prevPos != -1) {
				if (arr[prevPos] >j) {
					arr[i] = -1;
					prevPos = i;

				}
				else {
					arr[prevPos] = -1;
					arr[i]++;
					prevPos = i;
					cnt++;
				}
			}
			else {
				prevPos = i;
			}

		}
	}

	cout << n - cnt << '\n';
	return 0;
}


#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int arr[512];
int main()
{
	int n;
	int temp;
	int cnt = 0;
	int prev, prevPos;
	ios_base::sync_with_stdio(false);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}
	for (int j = 1; j <= 1000; j++) {
		prevPos = -1;
		for (int i = 0; i < n; i++) {
			if (arr[i] == -1) continue;
			if (arr[i] != j) {
				prevPos = -1;
				continue;
			}
			if (prevPos != -1) {
				arr[prevPos] = -1;
				arr[i]++;
				prevPos = -1;
				cnt++;
			}
			else {
				prevPos = i;
			}

		}
	}

	cout << n - cnt << '\n';
	return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define per(i, n) for(int i = (int)(n)-1;i>=0;i--)
#define per1(i, n) for(int i = (int)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int dp[maxn][maxn];
int solve(int l, int r){
    if(dp[l][r]!=0)return dp[l][r];
    // cout<<l<<" "<<r<<endl;
    for(int mid=l;mid<r;mid++){
        if(solve(l,mid)==solve(mid+1,r) && solve(l,mid)!=0){
            dp[l][r]=max(dp[l][r],solve(l,mid)+1);
        }
    }
    return dp[l][r];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    int vet[maxn];
    rep(i,n)cin>>vet[i];
    memset(dp,0,sizeof dp);
    int dp2[maxn];
    rep(i,n)dp[i+1][i+1]=vet[i];
    rep(i,n+1)dp2[i]=INF;
    dp2[0]=0;
    rep(i,n+1){
        for(int j=0;j<=i;j++){
            if(solve(j,i)>0){
                // cout<<j<<" "<<i<<endl;
                dp2[i]=min(dp2[i],dp2[j-1] + 1);
                // cout<<i<<" "<<dp2[i]<<endl;
            }
            else dp2[i]=min(dp2[i],dp2[j-1] + i - j + 1);
        }
    }
    // cout<<solve(1,4)
    // cout<<dp2[4]<<endl;
    cout<<dp2[n]<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define per(i, n) for(int i = (int)(n)-1;i>=0;i--)
#define per1(i, n) for(int i = (int)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int dp[maxn][maxn];
int solve(int l, int r){
    if(dp[l][r]!=0)return dp[l][r];
    // cout<<l<<" "<<r<<endl;
    for(int mid=l;mid<r;mid++){
        if(solve(l,mid)==solve(mid+1,r) && solve(l,mid)!=0){
            dp[l][r]=max(dp[l][r],solve(l,mid)+1);
        }
    }
    return dp[l][r];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    int vet[maxn];
    rep(i,n)cin>>vet[i];
    memset(dp,0,sizeof dp);
    rep(i,n)dp[i][i]=vet[i];
    int dp2[maxn];
    rep(i,n)dp2[i]=i;
    bool can=false;
    rep(i,n){
        for(int j=0;j<i;j++){
            if(solve(j,i)>0){
                can=true;
                dp2[i]=min(dp2[i],dp2[j]+1);
            }
        }
    }
    int ans=INF;
    rep(i,n){
        ans=min(ans,dp2[i]+n-1-i);
    }
    cout<<ans+!can<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(ll i = 0; i < (ll)(n); i ++)
#define rep1(i, n) for(ll i = 1; i <= (ll)(n); i ++)
#define per(i, n) for(ll i = (ll)(n)-1;i>=0;i--)
#define per1(i, n) for(ll i = (ll)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    int vet[maxn];
    rep(i,n)cin>>vet[i];
    ll dp[maxn][maxn];
    memset(dp,0,sizeof dp);
    rep(i,n)dp[i][i]=vet[i];
    for(int k=0;k<n;k++){
        for(int i=0;i<=k;i++){
            for(int j=k+1;j<n;j++){
                if(i>=j)continue;
                if(dp[i][k]==dp[k+1][j]  && dp[i][k]!=0){
                    dp[i][j]=dp[i][k]+1;
                }
            }
        }
    }
    cout<<dp[0][3]<<endl;
    ll dp2[maxn];
    rep(i,n)dp2[i]=i+1;
    rep(i,n){
        for(int j=0;j<i;j++){
            if(dp[j][i]>0){
                dp2[i]=min(dp2[i],dp2[j]+1);
            }
        }
    }
    cout<<dp2[n-1]<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define per(i, n) for(int i = (int)(n)-1;i>=0;i--)
#define per1(i, n) for(int i = (int)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int dp[maxn][maxn];
int vet[maxn];
int solve(int l, int r){
    // cout<<l<<" "<<r<<endl;
    if(l+1==r){
        if(vet[l-1]==vet[l])return vet[l-1]+1;
        else return 0;
    }
    if(dp[l][r]!=0)return dp[l][r];
    // cout<<l<<" "<<r<<endl;
    dp[l][r]=-1;
    for(int mid=l;mid<r;mid++){
        int a,b;
        a = solve(l,mid);
        b = solve(mid+1,r);
        if(a==b && a>0){
            dp[l][r]=max(dp[l][r],a+1);
        }
    }
    return dp[l][r];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    rep(i,n)cin>>vet[i];
    memset(dp,0,sizeof dp);
    int dp2[maxn];
    rep(i,n)dp[i+1][i+1]=vet[i];
    rep(i,n+1)dp2[i]=INF;
    // cout<<solve(1,4)<<endl;
    // return 0;
    dp2[0]=0;
    rep(i,n+1){
        for(int j=0;j<=i;j++){
            if(solve(j,i)>0){
                // cout<<j<<" "<<i<<endl;
                dp2[i]=min(dp2[i],dp2[j-1] + 1);
                // cout<<j<<" "<<i<<" "<<dp2[i]<<endl;
            }
            else dp2[i]=min(dp2[i],dp2[j-1] + i - j + 1);
        }
    }
    // cout<<dp2[4]<<endl;
    cout<<dp2[n]<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define per(i, n) for(int i = (int)(n)-1;i>=0;i--)
#define per1(i, n) for(int i = (int)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int dp[maxn][maxn];
int vet[maxn];
int solve(int l, int r){
    // cout<<l<<" "<<r<<endl;
    if(l+1==r){
        if(vet[l-1]==vet[l])return vet[l-1]+1;
        else return 0;
    }
    if(dp[l][r]!=0)return dp[l][r];
    // cout<<l<<" "<<r<<endl;
    for(int mid=l;mid<r;mid++){
        int a=solve(l,mid);
        int b=solve(mid+1,r);
        if(a==b && a!=0){
            dp[l][r]=max(dp[l][r],a+1);
        }
    }
    return dp[l][r];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    rep(i,n)cin>>vet[i];
    memset(dp,0,sizeof dp);
    int dp2[maxn];
    rep(i,n)dp[i+1][i+1]=vet[i];
    rep(i,n+1)dp2[i]=INF;
    // cout<<solve(1,4)<<endl;
    // return 0;
    dp2[0]=0;
    rep(i,n+1){
        for(int j=0;j<=i;j++){
            if(solve(j,i)>0){
                // cout<<j<<" "<<i<<endl;
                dp2[i]=min(dp2[i],dp2[j-1] + 1);
                // cout<<j<<" "<<i<<" "<<dp2[i]<<endl;
            }
            else dp2[i]=min(dp2[i],dp2[j-1] + i - j + 1);
        }
    }
    // cout<<dp2[4]<<endl;
    cout<<dp2[n]<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 509 /// Still trying to be one thing
#define MOD 1000000007
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define per(i, n) for(int i = (int)(n)-1;i>=0;i--)
#define per1(i, n) for(int i = (int)(n);i>=1;i--)
using namespace std;
const ll INF = 1e9 + 9;
int dp[maxn][maxn];
int vet[maxn];
int solve(int l, int r){
    // cout<<l<<" "<<r<<endl;
    if(l+1==r){
        if(vet[l-1]==vet[l])return vet[l-1]+1;
        else return 0;
    }
    if(dp[l][r]!=0)return dp[l][r];
    // cout<<l<<" "<<r<<endl;
    dp[l][r]=-1;
    for(int mid=l;mid<r;mid++){
        int a,b;
        dp[l][mid] = a = solve(l,mid);
        dp[mid+1][r] = b = solve(mid+1,r);
        if(a==b && a!=0){
            dp[l][r]=max(dp[l][r],a+1);
        }
    }
    return dp[l][r];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    rep(i,n)cin>>vet[i];
    memset(dp,0,sizeof dp);
    int dp2[maxn];
    rep(i,n)dp[i+1][i+1]=vet[i];
    rep(i,n+1)dp2[i]=INF;
    // cout<<solve(1,4)<<endl;
    // return 0;
    dp2[0]=0;
    rep(i,n+1){
        for(int j=0;j<=i;j++){
            if(solve(j,i)>0){
                // cout<<j<<" "<<i<<endl;
                dp2[i]=min(dp2[i],dp2[j-1] + 1);
                // cout<<j<<" "<<i<<" "<<dp2[i]<<endl;
            }
            else dp2[i]=min(dp2[i],dp2[j-1] + i - j + 1);
        }
    }
    // cout<<dp2[4]<<endl;
    cout<<dp2[n]<<endl;
    return 0;
}


#define I do solo
#include"bits/stdc++.h"
using namespace std;

#define ll long long
#define f(i,a,b) for (int i=a;i<=b;i++)
#define pb push_back
#define fi first
#define se second

#define PI 3.14159265
const long long mod=1000000007;

int n,a[1005],f[505][505];

void inp() {
	scanf("%d", &n);
	for (int i=1;i<=n;i++) scanf("%d", &a[i]);
}

void bokuwaasoloplayer() {
	inp();
	for (int i=0;i<n;i++) {
		for (int j=1;j+i<=n;j++) {
			if (i==0) f[j][j]=a[j];
			else {
				f[j][j+i]=-1;
				for (int k=j;k<j+i;k++) {
					if (f[j][k]==f[k+1][j+i]&&f[j][k]!=-1) {
						f[j][j+i]=f[j][k]+1;
						break;
					}
				}
			}
		}
	}
//	for (int i=1;i<=n;i++) {
//		f(j,1,n) {
//			cout<<f[i][j]<<" ";
//		}
//		cout<<"\n";
//	}
	int it=1,ans=0;
	while (it<=n) {
		int p=it;
		for (int i=it;i<=n;i++) {
			if (f[it][i]!=-1) p=i;
		}
		it=p+1;
		ans++;
	}
	printf("%d", ans);
}

signed main() {
	bokuwaasoloplayer();
	return 0;
}


#define I do solo
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;

#define ll long long
#define ii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define f(i,a,b) for (int i=a;i<=b;i++)
const ll mod=998244353;

int n,a[505];
vector<int> v[505][505];

void fuck(int l,int r) {
    if (r-l==0) {
        v[l][r].pb(a[l]);
        return;
    }
    vector<int> ans;
    for (int i=l;i<r;i++) {
        vector<int> L,R;
        L=v[l][i];
        R=v[i+1][r];
        while (L[L.size()-1]==R[0]) {
            R[0]++;
            L.pop_back();
        }
        for (int i=0;i<R.size();i++) {
            L.pb(R[i]);
        }
        if (i==l) ans=L;
        else {
            if (L.size()<ans.size()) ans=L;
        }
    }
    v[l][r]=ans;
}

void bokuwaasoloplayer() {
    scanf("%d", &n);
    f(i,1,n) scanf("%d", &a[i]);
    f(i,0,n) {
        f(j,1,n) {
            if (i+j>n) break;
            fuck(j,i+j);
        }
    }
    cout<<v[1][n].size();
    // cout<<"\n";
    // for (int i=0;i<v[1][n].size();i++) {
    //     cout<<v[1][n][i]<<" ";
    // }
}

signed main()
{
    bokuwaasoloplayer();
    return 0;
}


#define I do solo
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;

#define ll long long
#define ii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define f(i,a,b) for (int i=a;i<=b;i++)
const ll mod=998244353;

int n,a[505];
vector<int> v[505][505];

void fuck(int l,int r) {
    if (r-l==0) {
        v[l][r].pb(a[l]);
        return;
    }
    vector<int> ans;
    for (int i=l;i<r;i++) {
        vector<int> L,R;
        L=v[l][i];
        R=v[i+1][r];
        while (L[L.size()-1]==R[0]) {
            R[0]++;
            L.pop_back();
        }
        if (R.size()+L.size()>=ans.size()) continue;
        for (int i=0;i<R.size();i++) {
            L.pb(R[i]);
        }
        ans=L;
    }
    v[l][r]=ans;
}

void bokuwaasoloplayer() {
    scanf("%d", &n);
    f(i,1,n) scanf("%d", &a[i]);
    f(i,0,n) {
        f(j,1,n) {
            if (i+j>n) break;
            fuck(j,i+j);
        }
    }
    // printf("%d", v[1][n].size());
    cout<<v[1][n].size();
    // cout<<"\n";
    // for (int i=0;i<v[1][n].size();i++) {
    //     cout<<v[1][n][i]<<" ";
    // }
}

signed main()
{
    bokuwaasoloplayer();
    return 0;
}