#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> need; vector<int> noneed; int ncol; };

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.ncol = 0;
	ret.noneed = vector<int>(1, 0); inc(ret.noneed[0], 1);
	ret.need = vector<int>(1, 0);
	REPSZ(i, subs) {
		int nl = ret.ncol, nr = subs[i].ncol, ncol = nl + nr;
		vector<int> noneed(ncol + 1, 0);
		vector<int> need(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) {
			inc(noneed[j + k], (ll)ret.noneed[j] * subs[i].noneed[k] % MOD);
			inc(need[j + k], (ll)ret.need[j] * subs[i].need[k] % MOD);
			inc(need[j + k], (ll)ret.noneed[j] * subs[i].need[k] % MOD);
			inc(need[j + k], (ll)ret.need[j] * subs[i].noneed[k] % MOD);
		}
		ret.ncol = ncol;
		ret.noneed = noneed;
		ret.need = need;
	}

	{
		int nl = ret.ncol, nr = SZ(singles), ncol = nl + nr;
		vector<int> noneed(ncol + 1, 0);
		vector<int> need(ncol + 1, 0);
		REPE(j, nl) REPE(k, nr) {
			// empty row
			inc(noneed[j+k],(ll)(ret.noneed[j] + ret.need[j]) * C[nr][k] % MOD);
			// nonempty row
			int waysnonempty = (p2[ncol-j-k] + MOD - 1) % MOD;
			if(k==0) {
				inc(noneed[j+k], (ll)ret.noneed[j] * waysnonempty % MOD);
				inc(need[j+k], (ll)ret.need[j] * waysnonempty % MOD);
			} else {
				inc(need[j+k], (ll)(ret.noneed[j] + ret.need[j]) * C[nr][k] % MOD * waysnonempty % MOD);
			}
		}
		ret.ncol = ncol;
		ret.noneed = noneed;
		ret.need = need;
	}

	//printf("solve(%d,%d,%d):", l, r, y); REPSZ(i, ret.noneed) printf(" %d", ret.noneed[i]); printf(" /"); REPSZ(i, ret.need) printf(" %d", ret.need[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);
	int ret = 0; REPE(i, res.ncol) if(i % 2 == 0) inc(ret, res.noneed[i]); else dec(ret, res.noneed[i]); return ret;
}

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

}

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


Measured memory_bytes: 1152