Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000000
	maxBufSize     = 100000000
)

var sc *bufio.Scanner

func initScanner(r io.Reader) *bufio.Scanner {
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines
	return sc
}

func main() {
	sc = initScanner(os.Stdin)
	resolve()
}

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	a, _ := strconv.Atoi(sc.Text())
	return int(a)
}
func nextString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextIntSlice(sc *bufio.Scanner, n int) (a []int) {
	a = make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = nextInt(sc)
	}
	return a
}

var dp [][]int

func initDP(n int) {
	dp = make([][]int, n+1)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]int, n+1)
		for j := 0; j < len(dp[0]); j++ {
			dp[i][j] = -1
		}
	}
}

func resolve() {
	ans := []int{}
	for true {
		n := nextInt(sc)
		if n == 0 {
			break
		}
		as := nextIntSlice(sc, n)
		initDP(n)
		_rec(as, n, 0, n)
		ans = append(ans, dp[0][n])
	}
	for _, v := range ans {
		fmt.Println(v)
	}
	return
}

func _rec(as []int, n, l, r int) int {
	if dp[l][r] > -1 {
		return dp[l][r]
	}
	if r-l == 1 { // prevent to hit daruma
		dp[l][r] = 0
		return dp[l][r]
	}
	if r-l == 2 {
		if abs(as[l]-as[r-1]) <= 1 {
			dp[l][r] = 2
		} else {
			dp[l][r] = 0
		}
		return dp[l][r]
	}
	if abs(as[l]-as[r-1]) <= 1 {
		v := _rec(as, n, l+1, r-1)
		// if we can remove internal blocks
		if (r - 1 - (l + 1)) == v {
			dp[l][r] = v + 2
			return dp[l][r]
		} else {
			dp[l][r] = v
		}
	}
	for i := l + 1; i < r; i++ {
		v := _rec(as, n, l, i) + _rec(as, n, i, r)
		if dp[l][r] < v {
			dp[l][r] = v
		}
	}
	return dp[l][r]
}

func abs(v int) int {
	if v < 0 {
		return -v
	}
	return v
}

C++: #include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<climits>
#include<string>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define rep(i,n) for(int i=0;i<((int)(n));i++)
#define reg(i,a,b) for(int i=((int)(a));i<=((int)(b));i++)
#define irep(i,n) for(int i=((int)(n))-1;i>=0;i--)
#define ireg(i,a,b) for(int i=((int)(b));i>=((int)(a));i--)
typedef long long int lli;
typedef pair<int,int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define pque(type) priority_queue<type,vector<type>,greater<type> >
#define memst(a,b) memset(a,b,sizeof(a))
#define iter(v,ite) for(auto ite=(v).begin();ite!=(v).end();ite++)
#define mimunum(v,x) distance((v).begin(),lower_bound((v).begin(),(v).end(),x))

int w[305];

int dp[305][305];
int ans[305];
int main(void){
	for(;;){
		int n;
		scanf("%d",&n);
		if(n==0)break;
		rep(i,n){
			scanf("%d",&w[i]);
		}
		memset(dp,0,sizeof(dp));
		rep(j,n-1){
			if(abs(w[j]-w[j+1])<=1){
				dp[j][j+1]=1;
			}
		}
		reg(k,3,n)reg(i,0,n-k-1){
			int a = i,b=i+k;
			reg(t,a+1,b-1){
				dp[a][b] |= (dp[a][t] & dp[t+1][b]);
			}
			if(a+1<=b-1 && dp[a+1][b-1] && abs(w[a]-w[b])<=1){
				dp[a][b] = 1;
			}
		}
		/*
		rep(i,n){
			reg(j,i+1,n-1){
				printf("%d %d : %d\n",i,j,dp[i][j]);
			}
			//puts("");
		}
		*/
		memset(ans,0,sizeof(ans));
		ans[0]=0;
		reg(i,1,n){
			ans[i] = ans[i-1]+1;
			rep(j,i){
				if(dp[j][i-1])ans[i]=min(ans[i],ans[j]);
			}
		}
		printf("%d\n",n-ans[n]);
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
using VI = vector<int>;
using VVI = vector<VI>;
int rec(int l, int r, VI &a, VVI &memo) {
  if (memo[l][r] != -1) return memo[l][r];
  if (r - l <= 1) return memo[l][r] = 0;
  if (r - l == 2) {
    if (abs(a[l + 1] - a[l]) <= 1) return memo[l][r] = 2;
    return memo[l][r] = 0;
  }
  int res = rec(l + 1, r, a, memo);
  for (int i = l + 1; i < r; i++) {
    if (abs(a[i] - a[l]) <= 1 and rec(l + 1, i, a, memo) == i - (l + 1)) {
      res = max(res, i + 1 - l + rec(i + 1, r, a, memo));
    }
  }
  return memo[l][r] = res;
}
int main() {
  cin.tie(0); ios::sync_with_stdio(false);
  while (true) {
    int n; cin >> n;
    if (n == 0) break;
    VI a(n); for (int i = 0; i < n; i++) cin >> a[i];
    VVI memo(n + 1, VI(n + 1, -1));
    cout << rec(0, n, a, memo) << '\n';
  }
  return 0;
}

C++: #include <bits/stdc++.h>
#define REP(i,n,N) for(int i=n;i<N;i++)
#define p(S) cout<<(S)<<endl
using namespace std;

int main(){
	int n;
	while(cin>>n,n){
		int w[310];
		int dp[310][310]={};
		REP(i,0,n) cin>>w[i];
		for(int k=1;k<n;k++){
			for(int i=0;i+k<=n;i++){
				if(dp[i+1][i+k-1]==k-1)
					dp[i][i+k]=dp[i+1][i+k-1]+(abs(w[i]-w[i+k])<=1 ? 2 : 0);
				for(int j=i+1;j<i+k;j++)
					dp[i][i+k]=max(dp[i][i+k],dp[i][j]+dp[j+1][i+k]);
			}
		}
		p(dp[0][n-1]);
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define MOD 1000000007
#define ADD(X,Y) ((X) = ((X) + (Y)%MOD) % MOD)
typedef long long i64; typedef vector<int> iv; typedef vector<string> svec; typedef pair<int, int> pi;
int dd[] = { 0, 1, 0, -1, 0 };
#define mp make_pair
#define pb push_back

int ans;
void dfs(iv E, int depth)
{
  bool flag = false;
  repi(i,1,E.size())
    {
      if(abs(E[i]-E[i-1])>1)continue;
      flag = true;
      iv F;
      rep(j,E.size())
	{
	  if(j == i || j == i - 1)continue;
	  F.pb(E[j]);
	  //printf("%d" ,E[j]);
	}
      // printf("\n");
	  
      dfs(F, depth+2);
    }
  if(!flag)ans=max(ans,depth);
}
int main()
{
  while(true)
    {
      int n;
      scanf("%d", &n);
      if(n==0)break;

      iv W;
      rep(i,n)
	{
	  int w;
	  scanf("%d", &w);
	  W.pb(w);
	}
      ans = 0;
      dfs(W, 0);
      printf("%d\n", ans);
    }
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

bool	is_removable(const vector<int> &w_vec, int i0, int i1)
{
	return (abs(w_vec.at(i0) - w_vec.at(i1)) < 2);
}

int	main()
{
	int	n;
	while (cin >> n) {
		if (n == 0) break;
		if (n == 1) {
			cout << 0 << endl;
			continue;
		}
		vector<int>	w_vec(n);
		for (int i = 0; i < n; ++i)
			cin >> w_vec.at(i);
		vector<vector<int>>	cnt(n, vector<int>(n, 0));
		for (int i = 0; i < n - 1; ++i) {
			if (is_removable(w_vec, i, i + 1)) {
				cnt.at(i).at(i + 1) = 2;
			}
		}
		for (int i = 1; i < n; ++i) {
			int	k;
			int	tmp_cnt;	
			for (int j = 0; (k = i + j) < n; ++j) {
				if (k < n - 1) {
					tmp_cnt = cnt.at(j).at(k);
					if (cnt.at(j).at(k + 1) < tmp_cnt)
						cnt.at(j).at(k + 1) = tmp_cnt;
				}
				if (0 < j) {
					tmp_cnt = cnt.at(j).at(k);
					if (cnt.at(j - 1).at(k) < tmp_cnt)
						cnt.at(j - 1).at(k) = tmp_cnt;
				}
				if (k < n - 2) {
					for (int l = k + 2; l < n; ++l) {
						tmp_cnt = cnt.at(j).at(k) + cnt.at(k + 1).at(l);
						if (cnt.at(j).at(l) < tmp_cnt)
							cnt.at(j).at(l) = tmp_cnt;
					}
				}
				if (0 < j && k < n - 1 && cnt.at(j).at(k) == k - j + 1) {
					if (is_removable(w_vec, j - 1, k + 1)) {
						tmp_cnt = cnt.at(j).at(k) + 2;
						if (cnt.at(j - 1).at(k + 1) < tmp_cnt)
							cnt.at(j - 1).at(k + 1) = tmp_cnt;
					}
				}
				if (1 < j) {
					for (int l = 0; l < j - 1; ++l) {
						tmp_cnt = cnt.at(j).at(k) + cnt.at(l).at(j - 1);
						if (cnt.at(l).at(k) < tmp_cnt)
							cnt.at(l).at(k) = tmp_cnt;
					}
				}
			}
		}
		cout << cnt.at(0).at(n - 1) << endl;
	}
}