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++: // ref. http://tsutaj.hatenablog.com/entry/2017/03/07/173127

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <unordered_map>
#include <vector>
#include <string.h>
#include <set>

using namespace std;

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> void printvec(const vector<T>& v) {
  for (auto x : v) { cout << x << " "; }
  cout << endl;
}
template<class T> void printtree(const vector< vector<T> >& tree) {
  for (long long i = 0; i < tree.size(); ++i) {
    cout << i + 1 << ": "; printvec(tree[i]);
  }
}
template<class T, class U> void printmap(const map<T, U>& mp) {
  for (auto x : mp) { cout << x.first << "=>" << x.second << endl; }
}

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(ll i = 0; i < n; ++i)
#define all(s) s.begin(), s.end()
#define sz(x) (ll)(x).size()
#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define eb emplace_back

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> triple;
typedef double D;
typedef vector<ll> vl;
typedef vector<P> vp;

const ll INF = 1e9;
const ll MOD = 1000000007;  // 1e9 + 7

ll n;
vector<ll> a;

void solve() {
  // dp[l][r] = dp[l+1][r-1] + 2 if dp[l+1][r-1] == d-2 && abs(a[l]-a[r]) <= 1
  vector<vector<ll>> dp(n, vector<ll>(n));
  vector<vector<ll>> take(n, vector<ll>(n));

  for (ll d = 2; d <= n; ++d) { // dist
    rep(l,n) {
      ll r = l+d-1; // we consider [l,r]
      if (r >= n) { continue; }
      if (dp[l+1][r-1] == d-2 && abs(a[l]-a[r]) <= 1) {
        chmax(dp[l][r], d);
      }
      for (ll k = l; k < r; ++k) {
        chmax(dp[l][r], dp[l][k] + dp[k+1][r]);
      }
    }
  }
  cout << dp[0][n-1] << endl;
}

int main(int argc, char** argv) {
  cin.tie(NULL);
  cout.tie(NULL);
  ios_base::sync_with_stdio(false);
  //cout << setprecision(10) << fixed;

  while (true) {
    cin >> n;
    if (n == 0) { break; } // exit
    a.resize(n);
    rep(i,n) {
      cin >> a[i];
    }
    solve();
  }
}

C++: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

bool ok(int a, int b) {
	return abs(a - b) <= 1;
}

int solve(int l, int r, vector<int>&v) {
	if (l == r)return 0;
	else {
		if (l + 1 == r)return 0;
		else if (l + 2 == r) {
			if (ok(v[l],v[l+1]))return 2;
			else return 0;
		}
		else {
			int ans = 0;
			for (int k = l + 1; k < r - 1; ++k) {
				ans = max(ans, solve(l, k, v) + solve(k, r, v));
			}
			if (ok(v[l], v[r - 1]) && solve(l + 1, r - 1, v) == (r - l - 2)) {
				ans = r - l;
			}
			return ans;
		}
	}
}

int main() {
	while (1) {
		int N; cin >> N;
		vector<int>v(N);
		for (int i = 0; i < N; ++i)cin >> v[i];
		if (!N)break;
		int ans = solve(0, N, v);
		cout << ans << endl;
	}
	return 0;
}

C++: /*  -*- coding: utf-8 -*-
 *
 * 1611.cc: Daruma Otoshi
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 300;

/* typedef */

/* global variables */

int as[MAX_N];
bool bls[MAX_N][MAX_N + 1];
int dp[MAX_N + 1];

/* subroutines */

inline void setmax(int &a, int b) { if (a < b) a = b; }

/* main */

int main() {
  for (int n; scanf("%d", &n) > 0 && n > 0;) {
    for (int i = 0; i < n; i++) scanf("%d", as + i);

    memset(bls, false, sizeof(bls));
    for (int i = 0; i < n; i++) bls[i][i] = true;

    int maxl = 0;
    for (int l = 2; l <= n; l += 2) {
      for (int i = 0, j = l; j <= n; i++, j++) {
	if (bls[i + 1][j - 1] && abs(as[j - 1] - as[i]) <= 1)
	  bls[i][j] = true, maxl = l;
	else
	  for (int k = i + 2; k < j; k += 2)
	    if (bls[i][k] && bls[k][j]) {
	      bls[i][j] = true, maxl = l;
	      break;
	    }
	//if (bls[i][j]) printf("(%d,%d)", i, j);
      }
      //putchar('\n');
    }

    memset(dp, -1, sizeof(dp));
    dp[0] = 0;

    for (int i = 0; i < n; i++) {
      setmax(dp[i + 1], dp[i]);
      for (int j = i + 2; j <= n; j += 2)
	if (bls[i][j])
	  setmax(dp[j], dp[i] + (j - i));
    }

    printf("%d\n", dp[n]);
  }
  return 0;
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <string.h>
#include <cmath>

using namespace std;
typedef long long i64;
typedef long double ld;
typedef pair<i64,i64> P;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);++(i))

int main()
{
	int n;
	while(cin >> n , n)
	{
		vector<int> w(n,0);
		for(int i = 0;i < n;i++)
		{
			cin >> w[i];
		}
		
		vector<vector<int>> dp(n + 1,vector<int>(n + 1,0));

		for(int W = 2;W <= n;W++)
		{
			//left
			for(int l = 0;l < n;l++)
			{
				int r = l + W - 1;
				if(r >= n) continue;

				if(dp[l + 1][r - 1] == W - 2 && abs(w[l] - w[r]) <= 1)
					dp[l][r] = W;

				for(int mid = l;mid <= r;mid++)
				{
					dp[l][r] = max(dp[l][r] , dp[l][mid] + dp[mid + 1][r]);
				}

			}

		}

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