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 <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>

struct Context {
	std::vector<int>& blocks;
	std::unordered_map<uint64_t, int> cache;
};

struct State {
	uint64_t data;

	State() : data(0) {}
	State(uint64_t data) : data(data) {}

	State mark(int index) {
		return data | (((uint64_t)1) << index);
	}

	bool is_marked(int index) {
		return (data & (((uint64_t)1) << index)) != 0;
	}
};

int search(Context& ctx, State state, int count) {
	if (ctx.blocks.size() == 0) return count;
	auto cache_iter = ctx.cache.find(state.data);
	if (cache_iter != ctx.cache.end()) return (*cache_iter).second;

	int max = count;

	for (int i = 0; i < ctx.blocks.size() - 1; i++) {
		if (state.is_marked(i)) continue;

		// ?¬????????????????????????¢???
		for (int j = i + 1; j < ctx.blocks.size(); j++) {
			if (state.is_marked(j)) continue;
			if (std::abs(ctx.blocks[i] - ctx.blocks[j]) > 1) break;

			int result = search(ctx, state.mark(i).mark(j), count + 2);
			if (result > max) max = result;
		}
	}

	ctx.cache[state.data] = max;
	return max;
}

int main()
{
	std::vector<int> blocks;
	blocks.reserve(300);

	while (true) {
		int num_blocks;
		std::cin >> num_blocks;

		if (num_blocks == 0) return 0;

		blocks.clear();
		for (int i = 0; i < num_blocks; i++)
		{
			int w;
			std::cin >> w;
			blocks.push_back(w);
		}

		Context ctx{ blocks, {} };
		std::cout << search(ctx, {}, 0) << std::endl;
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> Pii;
typedef pair<ll,ll> Pll;
#define rep(i,n) for (ll i=0;i<n;++i)
#define rep2(i,a,b) for (ll i=a;i<b;++i)
const ll MOD=1e9+7;
const ll INF=1e9;
const ll IINF=1e18;
const double EPS=1e-8;
const double pi=acos(-1);

template<class T> inline bool chmin(T &a,T b){
    if (a>b){
        a=b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T &a,T b){
    if (a<b){
        a=b;
        return true;
    }
    return false;
}

int n;
vector<int> w(310);

int main(){
    int n;
    while (cin >> n,n){
        rep(i,n) cin >> w[i];
        vector<vector<int>> dp(n,vector<int>(n,0));
        rep(j,n){
            for (int i=0;i+j<n;i++){
                rep(k,j) chmax(dp[i][i+j],dp[i][i+k]+dp[i+k+1][i+j]);
                if (j!=0&&abs(w[i]-w[i+j])<=1&&(j==1||dp[i+1][i+j-1]==j-1)){
                    chmax(dp[i][i+j],dp[i+1][i+j]+2);
                }
            }
        }
        cout << dp[0][n-1] << endl;
    }
}

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

//using Graph = vector<vector<edge>>;
using dou =long double;
string yes="yes";
string Yes="Yes";
string YES="YES";
string no="no";
string No="No";
string NO="NO";

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
#define rep(i, n)         for(int i = 0; i < (int)(n); i++)
#define brep(n)           for(int bit=0;bit<(1<<n);bit++)
#define erep(i,container) for (auto i : container)
#define irep(i, n)        for(int i = n-1; i >= (int)0; i--)
#define rrep(i,m,n) for(ll i = m; i < (ll)(n); i++)
#define reprep(i,j,h,w) rep(i,h)rep(j,w)
#define all(x) (x).begin(),(x).end()
#define VEC(type,name,n) std::vector<type> name(n);rep(i,n)std::cin >> name[i];
#define pb push_back
#define pf push_front
#define query int qq;std::cin >> qq;rep(qqq,qq)
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define itn int
#define mp make_pair
#define sum(a) accumulate(all(a),0ll)
#define keta fixed<<setprecision
#define vvector(name,typ,m,n,a)vector<vector<typ> > name(m,vector<typ> (n,a))
#define vvvector(name,t,l,m,n,a) vector<vector<vector<t> > > name(l, vector<vector<t> >(m, vector<t>(n,a)));
#define vvvvector(name,t,k,l,m,n,a) vector<vector<vector<vector<t> > > > name(k,vector<vector<vector<t> > >(l, vector<vector<t> >(m, vector<t>(n,a)) ));
#define case std::cout <<"Case #" <<qqq+1<<": "
#define res resize
#define as assign
#define ffor for(;;)
#define ppri(a,b) std::cout << a<<" "<<b << std::endl
#define pppri(a,b,c) std::cout << a<<" "<<b <<" "<< c<<std::endl
#define aall(x,n) (x).begin(),(x).begin()+(n)
#define ssum(a) accumulate(a,0ll) 

typedef long long ll;
typedef pair<int,int> P;
typedef pair<ll,ll> PL;
//typedef long long T;
const int INF = 2000000000;
const ll INF64 = 922337203685477580ll;
const ll MOD = 1000000007ll;
const dou pi=3.141592653589793;
int main(){
    ffor{
        int n;
        std::cin >> n;
        if(n==0)break;
        
        VEC(int,a,n);
        
        
        vvector(dp,int,n+1,n+1,0);
        for (int ii = 0; ii < n+1; ii++) {
            rep(i,n+1-ii){
                for(int jj=0;jj<=ii;jj++){
                    chmax(dp[i][ii+i],dp[i][i+jj]+dp[i+jj][ii+i]);
                    
                }
                if(i!=0&&i+ii!=n){
                    if(dp[i][i+ii]==ii&&abs(a[i-1]-a[i+ii])<=1)chmax(dp[i-1][i+ii+1],dp[i][i+ii]+2);
                }
            }
        }
        int ans=0;
        reprep(i,j,n+1,n+1){
           // pppri(i,j,dp[i][j]);
            chmax(ans,dp[i][j]);
        }
        std::cout << ans << std::endl;
        
        
        /*
        vvector(dp,bool,n+1,n+1,0);
        rep(i,n+1)dp[i][i]=1;
        
        for (int ii = 0; ii < n+1; ii+=2) {
            rep(i,n+1-ii){
                for(int jj=0;jj<=ii;jj+=2){
                    if(dp[i][i+jj]&&dp[i+jj][ii+i])dp[i][ii+i]=1;
                    
                }
                if(i!=0&&i+ii!=n){
                        if(dp[i][i+ii]&&abs(a[i-1]-a[i+ii])<=1)dp[i-1][i+ii+1]=1;
                }
            }
        }
        */
    }
    
}