#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <cstring>
#include <list>  
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;  
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN = 400;
const int MOD = 998244353;
void inc(int& a, int b) { if ((a += b) >= MOD) a -= MOD; }
void dec(int& a, int b) { inc(a, MOD - b); }
struct Res { vector<int> withempty; vector<int> withoutempty; };

int n;
int h[MAXN];

int C[MAXN + 1][MAXN + 1];
int p2[MAXN + 1];

Res solve(int l, int r, int y) {
	vector<int> singles; FORE(x, l, r) if (h[x] == y + 1) singles.PB(x);
	vector<Res> subs;
	if (SZ(singles) == 0) {
		subs.PB(solve(l, r, y + 1));
	} else {
		if (singles[0] != l) subs.PB(solve(l, singles[0] - 1, y + 1));
		FORSZ(i, 1, singles) if (singles[i] != singles[i - 1] + 1) subs.PB(solve(singles[i - 1] + 1, singles[i] - 1, y + 1));
		if (singles.back() != r) subs.PB(solve(singles.back() + 1, r, y + 1));
	}
	Res ret;
	ret.withoutempty = vector<int>(1, 0); inc(ret.withoutempty[0], 1);
	ret.withempty = vector<int>(1, 0); inc(ret.withempty[0], 1);
	REPSZ(i, subs) {
		int nl = SZ(ret.withoutempty) - 1, nr = SZ(subs[i].withoutempty) - 1, ncol = nl + nr;
		vector<int> tmp(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) inc(tmp[j + k], (ll)ret.withoutempty[j] * subs[i].withoutempty[k] % MOD);
		ret.withoutempty = tmp;
	}
	REPSZ(i, subs) {
		int nl = SZ(ret.withempty) - 1, nr = SZ(subs[i].withempty) - 1, ncol = nl + nr;
		vector<int> tmp(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) inc(tmp[j + k], (ll)ret.withempty[j] * subs[i].withempty[k] % MOD);
		ret.withempty = tmp;
	}

	{
		int nl = SZ(ret.withoutempty) - 1, nr = SZ(singles), ncol = nl + nr;
		vector<int> tmp(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) {
			REPE(extra, nl - j) {
				int ways = p2[j + nr];
				if (extra == 0) dec(ways, 1);
				ways = (ll)ways * C[SZ(singles)][k] % MOD;
				//printf("\tA(%d,%d,%d): %d+%d += %d*%d*%d (extra=%d, SZ(singles)=%d)\n", l, r, y, j, k, ret.withoutempty[j + extra], C[j + extra][extra], ways, extra, SZ(singles));
				inc(tmp[j + k], (ll)ret.withoutempty[j + extra] * C[j + extra][extra] % MOD * ways % MOD);
			}
			if (k == nr) {
				//printf("\tA(%d,%d,%d): %d+%d += %d\n", l, r, y, j, k, ret.withempty[j]);
				inc(tmp[j + k], ret.withempty[j]);
			}
		}
		ret.withoutempty = tmp;
	}
	{
		int nl = SZ(ret.withempty) - 1, nr = SZ(singles), ncol = nl + nr;
		vector<int> tmp(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) {
			REPE(extra, nl - j) {
				int ways = p2[j + k];
				ways = (ll)ways * C[SZ(singles)][k] % MOD;
				//printf("\tB(%d,%d,%d): %d+%d += %d*%d*%d (extra=%d, SZ(singles)=%d)\n", l, r, y, j, k, ret.withempty[j + extra], C[j + extra][extra], ways, extra, SZ(singles));
				inc(tmp[j + k], (ll)ret.withempty[j + extra] * C[j + extra][extra] % MOD * ways % MOD);
			}
		}
		ret.withempty = tmp;
	}

	//printf("solve(%d,%d,%d):", l, r, y); REPSZ(i, ret.withoutempty) printf(" %d", ret.withoutempty[i]); printf(" /"); REPSZ(i, ret.withempty) printf(" %d", ret.withempty[i]); puts("");
	return ret;
}

int solve() {
	REPE(i, n) { C[i][0] = C[i][i] = 1; FOR(j, 1, i) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD; }
	p2[0] = 1; FORE(i, 1, n) p2[i] = (ll)2 * p2[i - 1] % MOD;
	Res res = solve(0, n - 1, 0);
	return res.withoutempty[0];
}

void run() {
	scanf("%d", &n);
	REP(i, n) scanf("%d", &h[i]);
	printf("%d\n", solve());

}

int main() {
	run();
	return 0;
}


Measured memory_bytes: 1024