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 "bits/stdc++.h"
using namespace std;

vector<int>as;
bool ok(int a,int b){
  return abs(as[a]-as[b])<=1;
}

int main() {
  while(1){
    
    int N;cin>>N;
    if(!N)break;
    as.resize(N);
    vector<vector<int>>dp(N+1,vector<int>(N+1,-100000));
    for(int i=0;i<N;++i){
      int a;cin>>a;as[i]=a;
    }
    for(int i=0;i<=N;++i){
      dp[i][i]=0;
    }
    for(int t=2;t<=N;++t){
      for(int l=0;l<=N-t;++l){
	const int r=l+t;
	dp[l][r]=max(dp[l+1][r],dp[l][r-1]);
	if(ok(l,l+1))dp[l][r]=max(dp[l+2][r]+2,dp[l][r]);
	if(ok(r-2,r-1))dp[l][r]=max(dp[l][r-2]+2,dp[l][r]);
	if(ok(l,r-1)){
	  if(dp[l+1][r-1]==(r-l-2)){
	    dp[l][r]=max(dp[l+1][r-1]+2,dp[l][r]);
	  }
	}
      } 
    }

    int ans=dp[0][N];
    ans=max(0,ans)
    cout<<ans<<endl;
  }
  return 0;
}

C++: #include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<bitset>
#include<stack>
#include<memory>
using namespace std;
using namespace std::chrono;
typedef long long int llint;
typedef double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
const llint mod=998244353;
const llint big=2.19e17+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-15;
template <class T,class U>bool mineq(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool maxeq(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>llint LBI(vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>llint UBI(vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}
//  17:50-
//A 17:54 AC
//B 17:58 AC
//C 18:05 AC
bool solve(void){
	int n,m,i,j,k;cin>>n;
	if(n==0){return false;}
	vector<int>w(n);
	static bool can[300][300];
	for(i=0;i<n;i++){cin>>w[i];}
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){can[i][j]=false;}
		if(i>0){can[i][i-1]=true;}
	}
	for(i=2;i<=n;i++){
		for(j=0;j<=n-i;j++){
			int L=j,R=j+i-1;
			for(k=2;k<i;k+=2){
				int Lm=j+k-1,Rm=j+k;
				if(can[L][Lm]&&can[Rm][R]){can[L][R]=true;break;}
			}
			if(can[L+1][R-1]&&abs(w[L]-w[R])<=1){can[L][R]=true;}
		}
	}
	vector<int>dp(n+1,0);
	dp[0]=0;
	for(i=0;i<n;i++){
		maxeq(dp[i+1],dp[i]);
		for(j=i+1;j<n;j+=2){
			if(can[i][j]){maxeq(dp[j+1],dp[i]+j-i+1);}
		}
	}
	cout<<dp[n]<<endl;
	return true;
}
int main(void){
	while(solve()){}
	return 0;
}

C++: #include <iostream>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
 
#define REP(i,n) for(int i=0; i<n; ++i)
#define FOR(i,a,b) for(int i=a; i<=b; ++i)
#define FORR(i,a,b) for (int i=a; i>=b; --i)
 
typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<VI> VVI;
typedef pair<int,int> P;
typedef pair<ll,ll> PL;

int main() {
    int n;
    while (cin >> n && n){
        VI a(n);
        REP(i,n) cin >> a[i];
        VVI dp(n, VI(n+1));
        REP(i,n-1) if (abs(a[i] - a[i+1]) <= 1) dp[i][i+2] = 1;
        for (int d = 4; d <= n; d += 2){
            REP(i,n+1-d){
                FOR(j,i,i+d-1) if (dp[i][j] && dp[j][i+d]) dp[i][i+d] = 1;
                if (dp[i+1][i+d-1] && abs(a[i]-a[i+d-1]) <= 1) dp[i][i+d] = 1;
            }
        }
        
        VI dp2(n+1);
        REP(i,n){
            int ma = 0;
            REP(j,n+1){
                if (dp[i][j]) ma = max(ma, j - i);
                dp2[j] = max(dp2[j], dp2[i] + ma);
            }
        }
        int ans = 0;
        REP(i,n+1) ans = max(ans, dp2[i]);
        cout << ans << endl;
    }

    return 0;
}