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++: #define D(x) cout << #x " = " << x << endl
#define DD(x, y) cout << "(" #x ", " #y ") = (" << x << ", " << y << ")" << endl
#define DDD(x, y, z) cout << "(" #x ", " #y ", " #z ") = (" << x << ", " << y << ", " << z << ")" << endl
#define DV(v) for (auto __macro_vi : v){ cout << __macro_vi << "\t";} cout << endl;
#define DA(a, n) for (int __macro_i = 0; __macro_i < n; ++__macro_i) { cout << a[__macro_i] << " "; } cout << endl;
#define REP(i, n) for (int i = 0; i < n; ++i)
#define ALL(v) (v).begin(), (v).end()
#include<iostream>
#include<vector>
#include<cassert>
#include<cmath>

using namespace std;

vector<int> w;
vector<vector<int>> dp;
int n;

int f(int i, int j) {
    if (dp[i][j] != -1) return dp[i][j];
    assert(i <= j);
    if (i + 1 >= j) {dp[i][j] = 0; return 0;}
    int ans = max(f(i, j - 1), f(i + 1, j));
    for (int k = i; k < j - 1; ++k) {
        if (abs(w[j - 1] - w[k]) <= 1) {
            if (f(k + 1, j) != j - (k + 1) - 1) continue;
            ans = max(ans, f(i, k) + f(k + 1, j - 1) + 2);
        }
    }
    dp[i][j] = ans;
    return ans;
}

void solve() {
    dp = vector<vector<int>>(n + 1, vector<int>(n + 1, -1));
    cout << f(0, n) << endl;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(1) {
        cin >> n;
        if (n == 0) break;
        w.resize(n);
        REP(i, n) cin >> w[i];
        solve();
    }
}

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

#define For(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define Rep(i,n) For(i,0,n)
#define dbg(x) cout<<#x"="<<x<<endl

#define MAX_N 300+1
#define MAX_W 1000+1

int N;
int w[MAX_N];
int dp[MAX_N][MAX_N];

int main(int argc, char const *argv[])
{
	while(1){
		scanf("%d", &N);
		if(N == 0) break;
		Rep(i,N){
			scanf("%d", &w[i]);
		}
		Rep(i,MAX_N)Rep(j,MAX_N) dp[i][j] = 0;
		Rep(l,N){
			for(int s = 0, e = l; e < N; s++,e++){
				For(i,s,e){
					dp[s][e] = max(dp[s][e], dp[s][i]+dp[i+1][e]);
				}
				if((e-s-1)%2 == 0 && (e-s-1)/2 == dp[s+1][e-1] && abs(w[e]-w[s]) <= 1) dp[s][e] = max(dp[s][e], dp[s+1][e-1]+1);
			}
		}
		printf("%d\n", dp[0][N-1]*2);
	}
	return 0;
}

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

//repetition
#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)

//container util
#define all(x) (x).begin(),(x).end()

//typedef
typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;


//conversion
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
inline ll toLL(string s) {ll v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}


void solve(VLL & w){
  int n = w.size();
  bool dp[n][n];
  memset(dp,false,sizeof(dp));
  FOR(len,2,n+1){
    for(int l = 0; (l + len - 1) < n; l++){
      int r = l + len - 1;
      if(len == 2){
        dp[l][r] = dp[l][r] || (abs(w[l] - w[r]) <= 1);
      }
      FOR(k,l+1,r){

        dp[l][r] = (dp[l][k] && dp[k+1][r]) || dp[l][r];
        dp[l][r] = dp[l][r] || ( (abs(w[l] - w[r]) <= 1) && ( (dp[l+1][k] && dp[k+1][r-1]) || dp[l+1][r-1]));
      }
    }
  }
  // rep(i,n){
  //   rep(j,n){
  //     cout << dp[i][j] << ' ';
  //   }
  //   cout << endl;
  // }
  ll ep[n+1];
  memset(ep,0,sizeof(ep));
  rep(i,n){
    ep[i+1] = max(ep[i],ep[i+1]);
    FOR(j,i+1,n){
      if(dp[i][j]){
        if(i == 0) ep[j] = max((ll)(j-i+1),ep[j]);
        else ep[j] = max((ll)(j-i+1)+ep[i-1],ep[j]);
      }
    }
  }
  cout << ep[n] << endl;
  return;
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  ll n;
  while(true){
    cin >> n;
    if(n == 0) break;
    VLL w(n);
    rep(i,n) cin >> w[i];
    solve(w);
  }
  cin >> n;

  return 0;
}

C++: #include <bits/stdc++.h>
#define FOR(i,k,n) for(int i=(k);i<int(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(x) begin(x),end(x)

using namespace std;

int main() {
  while(1){
    int n;
    cin>>n;
    if(!n)break;
    vector<int> w(n);
    REP(i,n)cin>>w[i];
    vector<vector<int>> dp(n, vector<int>(n+1, 0));
    REP(i,n-1) {
      if (abs(w[i]-w[i+1]) <= 1) dp[i][2] = 2;
    }
    FOR(l,3,n+1) REP(i,n) {
      if (i+l > n) break;
      FOR(k,1,l) {
        dp[i][l] = max(dp[i][l], dp[i][k] + dp[i+k][l-k]);
      }
      if (dp[i+1][l-2] == l-2 && abs(w[i] - w[i+l-1]) <= 1) {
        dp[i][l] = l;
      }
    }
    cout << dp[0][n] << endl;
  }
  return 0;
}

C++: #include<iostream>
#include<vector>
#include<tuple>
#include<algorithm>
#include<cmath>
using namespace std;
vector<tuple<int, int, int>>vec; int n, a[1000], dp[1000][1000];
int main() {
	while (true) {
		cin >> n; if (n == 0)break; vec.clear(); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++)dp[i][j] = 0; }
		for (int i = 0; i < n; i++)cin >> a[i];
		for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { vec.push_back(make_tuple(j - i, i, j)); } }
		sort(vec.begin(), vec.end());
		for (int i = 0; i < n - 1; i++) { if (abs(a[i] - a[i + 1]) <= 1) { dp[i][i + 1] = 1; } }
		for (int i = 0; i < vec.size(); i++) {
			int a1 = get<1>(vec[i]), a2 = get<2>(vec[i]);
			if (dp[a1][a2] == 0)continue;
			if (a2 < n - 2 && abs(a[a2 + 1] - a[a2 + 2]) <= 1)dp[a1][a2 + 2] = 1;
			if (a1 > 0 && a2 < n - 1 && abs(a[a1 - 1] - a[a2 + 1]) <= 1)dp[a1 - 1][a2 + 1] = 1;
		}
		for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (dp[i][j] == 1)dp[i][j] = j - i + 1; } }
		for (int i = 2; i <= n; i++) {
			for (int j = 2; j <= n; j++) {
				for (int k = 0; k < n; k++) {
					int a1 = k, a2 = k + i, a3 = k + i + j;
					dp[a1][a3 - 1] = max(dp[a1][a3 - 1], dp[a1][a2 - 1] + dp[a2][a3 - 1]);
				}
			}
		}
		cout << dp[0][n - 1] << endl;
	}
	return 0;
}