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>
#define loop(n) for (int ngtkana_is_genius = 0; ngtkana_is_genius < int(n); ngtkana_is_genius++)
#define rep(i, begin, end) for(int i = int(begin); i < int(end); i++)
#define lint long long
auto cmn = [](auto& a, auto b){if (a > b) {a = b; return true;} return false;};
auto cmx = [](auto& a, auto b){if (a < b) {a = b; return true;} return false;};
void debug_impl() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) {
  std::cerr << " " << head;
  debug_impl(tail...);
}
#define debug(...) std::cerr << std::boolalpha << "[" << #__VA_ARGS__ << "]:";\
  debug_impl(__VA_ARGS__);\
  std::cerr << std::noboolalpha;

template <typename T>
std::istream& operator>> (std::istream& is, std::vector<T>& v)
  { for (auto & x : v) is >> x; return is; }

template <typename T>
std::ostream& operator<< (std::ostream& os, const std::vector<T>& v) {
  auto n = v.size();
  os << "{";
  for (size_t i = 0; i < n; i++)
    {os << (i > 0 ? "," : "") << v[i];}
  return os << "}";
}

template<typename T>
class fixed_point : T {
  public:
    explicit constexpr fixed_point (T&& t) noexcept
      : T(std::forward<T>(t)) {}
    template<typename... Args>
    constexpr decltype(auto) operator()(Args&&... args) const
      {return T::operator()(*this, std::forward<Args>(args)...);}
};
template<typename T>
static inline constexpr decltype(auto) fix (T&& t) noexcept {
  return fixed_point<T>{std::forward<T>(t)};
}

template <typename T>
auto make_vector_impl(size_t sz, T t) {return std::vector<T>(sz, t);}

template <size_t N, typename T, typename U, std::enable_if_t<N == 1, std::nullptr_t> = nullptr>
auto make_vector(size_t sz, U u) {return make_vector_impl(sz, T(u));}

template <size_t N, typename T, std::enable_if_t<N == 1, std::nullptr_t> = nullptr>
auto make_vector(size_t sz) {return std::vector<T>(sz);}

template <size_t N, typename T, typename... Args, std::enable_if_t<N != 1, std::nullptr_t> = nullptr>
auto make_vector(size_t a, Args... args) {return make_vector_impl(a, make_vector<N - 1, T>(args...));}

template <typename T, typename Size_t>
auto& at(T& t, Size_t i) {return t.at(i);}

template <typename T, typename Size_t, typename... Args>
auto& at(T& t, Size_t i, Args... args) {return at(t.at(i), args...);}

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  while (true) {
    int n; std::cin >> n;
    if (n == 0) exit(0);
    std::vector<int> w(n); std::cin >> w;
    auto dp  = make_vector<2, int>(n + 1, n + 1, -1);
    auto ckd = make_vector<2, int>(n + 1, n + 1, false);
    auto ret = n - fix([&](auto f, int l, int r) -> int {
      if (at(ckd, l, r)) return at(dp, l, r);
      if (l == r) return 0;
      auto& ret = at(dp, l, r);
      ret = f(l + 1, r) + 1;
      rep(i, l + 1, r) {
        if (std::abs(w.at(l) - w.at(i)) <= 1 && f(l + 1, i) == 0) {
          cmn(ret, f(i + 1, r));
        }
      }
      at(ckd, l, r) = true;
      return ret;
    })(0, n);
    std::cout << ret << std::endl;
  }
  return 0;
}

C++: #include<cstdio>
#include<algorithm>
using namespace std;
int n, w[300];
int memo[300][300];
int dp[303];
bool check(int i, int j) {
  if (abs(w[i] - w[j]) <= 1) return true;
  return false;
}
int canRemove(int x, int y) { // 1 : can / 0 : no
  if (memo[x][y] >= 0) return memo[x][y];
  if (y == x + 1) {
    if (check(x, y)) return memo[x][y] = 1;
    return memo[x][y] = 0;
  }
  for (int i = x + 1; i < y; i += 2) {
    if (canRemove(x, i) && canRemove(i + 1, y)) return memo[x][y] = 1;
  }
  for (int i = x + 3; i < y; i += 2) {
    if (check(x, i) && canRemove(x + 1, i - 1) && canRemove(i + 1, y)) return memo[x][y] = 1;
  }
  if (check(x, y) && canRemove(x + 1, y - 1)) return memo[x][y] = 1;
  return memo[x][y] = 0;
}

int main() {
  while (1) {
    scanf("%d", &n);
    if (n == 0) break;
    for (int i = 0; i < n; i++) scanf("%d", &w[i]);
    for (int i = 0; i < n ; i++)
      for (int j = 0; j < n; j++) memo[i][j] = -1;
    for (int i = 0; i <= n; i++) dp[i] = 0;
    for (int i = 0; i < n; i++) {
      if (i > 0) dp[i] = max(dp[i], dp[i - 1]);
      for (int j = i + 1; j < n; j += 2) {
        if (canRemove(i, j)) dp[j + 1] = max(dp[j + 1], dp[i] + j - i + 1);
      }
    }
    /*
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j ++) {
        printf("%d ", memo[i][j]);
      }
      printf("\n");
    }
    */
    int ans = 0;
    for (int i = 0; i <= n; i++) ans = max(ans, dp[i]);
    printf("%d\n", ans);
  }
}

C++: #include<bits/stdc++.h>
using namespace std;
const long long INF = 1e7 + 1;
const long long MOD = 1000000007;
const long double PI = 3.1415926;
#define FOR(i,r,n) for(ll i = (ll)(r); i < (ll)(n); i++)
#define RFOR(i,r,n) for(ll i=(ll)(n-1);i>=r;i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,0,n)
#define ALL(x) x.begin(),x.end()
#define RALL(x) x.rbegin(),x.rend()
typedef long long int ll;
typedef vector<ll> vi;
typedef vector < pair<ll, ll > > vp;
typedef vector <string> vs;
typedef vector <char> vc;
typedef list <ll> lst;

ll n, m, k, ans = 0, sum = 0, cnt = 0;
string s;
char c;


/*--------------------template--------------------*/

ll dp[500][500];

int main()
{
	while (1) {
		cin >> n;
		if (n == 0) {
			return 0;
		} else {
			vi v(n, 0);
			memset(dp, 0, sizeof(dp));
			REP(i, n) cin >> v[i];
			FOR(i, 1, n)
			{
				REP(j, n - i)
				{
					FOR(k, j, j + i)
					{
						dp[j][j + i] = max(dp[j][j + i], dp[j][k] + dp[k + 1][j + i]);
						if (dp[j + 1][j + i - 1] == i - 1 && abs(v[j] - v[j + i]) < 2) {
							dp[j][j + i] = i + 1;
						}
					}
				}
			}
			cout << dp[0][n - 1] << endl;
		}
	}
}