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 <cassert>

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
//#include <boost/foreach.hpp>
//#include <boost/range/algorithm.hpp>
#define rep(i,j,k) for(int i=(int)j;i<(int)k;i++)
#define ll long long
#define Sort(v) sort(all(v))
#define INF 1e9
#define LINF 1e18
#define END return 0
#define pb push_back
#define se second
#define fi first
#define pb push_back
#define all(v) (v).begin() , (v).end()
#define MP make_pair
#define MOD 1000000007LL
#define int long long
using namespace std;
int day[12]={31,28,31,30,31,30,31,31,30,31,30,31};
struct edge{int to,cost;};
typedef pair<int,int> P;

bool isupper(char c){if('A'<=c&&c<='Z')return 1;return 0;}
bool islower(char c){if('a'<=c&&c<='z')return 1;return 0;}
bool isPrime(int x){if(x==1)return 0;if(x==2)return 1;if(x%2==0)return 0;for(int i=3;i*i<=x;i++)if(x%i==0)return 0;return 1;}
bool iskaibun(string s){for(int i=0;i<s.size()/2;i++)if(s[i]!=s[s.size()-i-1])return 0;return 1;}

vector<int> v;
vector<vector<int>> dp;

int  rec(int l,int r){
    if(dp[l][r]!=-1)return dp[l][r];
    if(abs(r-l)<=1)return 0;
    int res=0;
    if(abs(v[l]-v[r-1])<=1 && rec(l+1,r-1)==r-l-2){
        res=r-l;
    }
    for(int i=l+1;i<=r-1;i++){
        res=max(res,rec(l,i)+rec(i,r));
    }
    return dp[l][r]=res;
}


signed main (){
    int n;
    while(cin>>n && n){
        v.resize(n);
        dp.resize(n+1,vector<int>(n+1,-1));
        rep(i,0,n)cin>>v[i];
        rec(0,n); 
        cout<<dp[0][n]<<endl;
        v.clear();
        dp.clear();
    }  


}
/*
1-2
0.5-2

010
01110
00111
000000111
*/

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

int main(){

    while(1){

        int n; cin >> n;
        if(!n) break;
        vector<int> w(n);
        for(int i = 0; i < n; i++){
            cin >> w[i];
        }

        vector<vector<bool> > take(n, vector<bool> (n, false));        //take[i][j] := 区間[i][j]を全消しできるかどうか

        for(int k = 1; k < n; k++){
            for(int i = 0; i + k < n; i++){
                if(k == 1){
                    take[i][i + k] = (abs(w[i] - w[i + k]) <= 1);
                }else{
                    take[i][i + k] = (take[i + 1][i + k - 1] && abs(w[i] - w[i + k]) <= 1);
                
                    for(int l = i + 1; l < i + k; l++){
                        if(take[i][i + k]) break;
                        take[i][i + k] = (take[i][l] && take[l][i + k]);
                    }
                }
            }
        }

        vector<vector<int> > dp(n, vector<int> (n, 0));               //dp[i][j] := 区間 [i, j] において被覆できる頂点数の最大値

        //初期化
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                if(take[i][j]) dp[i][j] = j - i + 1;
            }   
        }


        for(int k = 2; k < n; k++){
            for(int i = 0; i + k < n; i++){
                for(int l = i + 1; l < i + k; l++){
                    dp[i][i + k] = max(dp[i][i + k], dp[i][l] + dp[l + 1][i + k]);
                }  
            }
        }

        cout << dp[0][n - 1] << endl;
    }
    return 0;
}

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;


bool dp[310][310];
int dplen[310];
int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N;
  while(cin>>N,N){
	VI xs(N);
	REP(i,N) cin >> xs[i];
	fill((bool*)dp, (bool*)dp+310*310, false);
	fill(dplen, dplen+310, 0);

	REP(i,N+1) dp[i][i] = true;
	for(int l=2;l<=N;l+=2){
	  for(int b=0,e=b+l;e<=N;++b,++e){
		dp[b][e] = dp[b][e] || (dp[b+1][e-1] && abs(xs[b]-xs[e-1]) <= 1);
		if(dp[b][e]) continue;
		for(int i=b+2;i<e;i+=2)
		  dp[b][e] = dp[b][e] || (dp[b][i] && dp[i][e]);
	  }
	}

	for(int i=0;i<N;++i){
	  maxi(dplen[i+1], dplen[i]);
	  for(int j=i+2;j<=N;j+=2)
		if(dp[i][j])
		  maxi(dplen[j], dplen[i] + j-i);
	}
	cout << dplen[N] << endl;
  }

  return 0;
}