#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <bitset>
#include <functional>
#include <tuple>
#include <complex>
#include <chrono>
#include <climits>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef unsigned int uint;
typedef unsigned long long ull;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
// default_random_engine generator;
// mt19937 rnd(1);

const int P = 998244353;

void add(int &a, int b) {
    a += b;
    if (a >= P) {
        a -= P;
    }
}

void mul(int &a, int b) {
    ll c = (ll)a * b;
    c %= P;
    a = c;
}

const int MAXN = 1010;
int f[MAXN][MAXN];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    int n, m;
    cin >> n >> m;

    vector<int> a(m);
    for (int i = 0; i < m; ++i) {
        cin >> a[i];
        --a[i];
    }

    vector<int> b = {a[0]};
    for (int i = 1; i < m; ++i) {
        if (a[i] != a[i - 1]) {
            b.push_back(a[i]);
        }
    }

    a = b;
    m = sz(a);

    if (m >= 2 * n) {
        cout << 0 << endl;
        return 0;
    }

    for (int i = 0; i < m; ++i) {
        int pos = -1;
        for (int j = 0; j < i; ++j) {
            if (a[i] == a[j]) {
                pos = j;
            }
        }
        if (pos == -1) {
            continue;
        }
        vector<int> u(n);
        vector<int> v(n);
        for (int j = 0; j < m; ++j) {
            if (pos < j && j < i) {
                u[a[j]] = 1;
            } else {
                v[a[j]] = 1 ;
            }
        }

        for (int j = 0; j < n; ++j) {
            if (u[j] && v[j]) {
                cout << 0 << endl;
                return 0;
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        vector<int> ps;
        for (int j = 0; j < m; ++j) {
            if (a[j] == i) {
                ps.push_back(j);
            }
        }
        int lf = ps[0], rg = ps.back();
        // cout << i << " " << lf << " " << rg  << endl;
        for (int j = lf; j <= rg; ++j) {
            if (a[j] < i) {
                cout << 0 << endl;
                return 0;
            }
        }
    }

    // for (int i = 0; i < m; ++i) {
    //     cout << a[i] << " ";
    // }
    // cout << endl;

    for (int i = 0; i <= m; ++i) {
        f[i][i] = 1;
    }

    for (int len = 1; len <= m; ++len) {
        for (int i = 0; i + len <= m; ++i) {
            int j = i + len;
            int pos = i;
            vector<int> ps = {i};

            for (int k = i + 1; k < j; ++k) {
                if (a[pos] > a[k]) {
                    pos = k;
                    ps = {k};
                } else if (a[pos] == a[k]) {
                    ps.push_back(k);
                }
            }

            int u = 0, v = 0;

            for (int k = i; k <= ps[0]; ++k) {
                int c = f[i][k];
                mul(c, f[k][ps[0]]);
                add(u, c);
            }

            for (int k = ps.back() + 1; k <= j; ++k) {
                int c = f[ps.back() + 1][k];
                mul(c, f[k][j]);
                add(v, c);
            }

            f[i][j] = u;
            mul(f[i][j], v);

            for (int k = 0; k < sz(ps) - 1; ++k) {
                mul(f[i][j], f[ps[k] + 1][ps[k + 1]]);
            }
            // cout << i << " " << j << " " << ps[0] << " " << ps[1] << " " << f[i][j] << endl;
        }
    }

    cout << f[0][m] << endl;

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert>
#include <unordered_map>
#include <fstream>
#include <random>
#include <cstring>
#include <bitset>
#include <functional>
#include <tuple>
#include <complex>
#include <chrono>
#include <climits>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef unsigned int uint;
typedef unsigned long long ull;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
// default_random_engine generator;
// mt19937 rnd(1);

const int P = 998244353;

void add(int &a, int b) {
    a += b;
    if (a >= P) {
        a -= P;
    }
}

void mul(int &a, int b) {
    ll c = (ll)a * b;
    c %= P;
    a = c;
}

const int MAXN = 1010;
int f[MAXN][MAXN];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    int n, m;
    cin >> n >> m;

    vector<int> a(m);
    for (int i = 0; i < m; ++i) {
        cin >> a[i];
        --a[i];
    }

    vector<int> b = {a[0]};
    for (int i = 1; i < m; ++i) {
        if (a[i] != a[i - 1]) {
            b.push_back(a[i]);
        }
    }

    a = b;
    m = sz(a);

    if (m >= 2 * n) {
        cout << 0 << endl;
        return 0;
    }

    b = vector<int>(m);
    for (int i = 0; i < n; ++i) {
        int lf = m, rg = 0;
        for (int j = 0; j < m; ++j) {
            if (a[j] == i) {
                lf = min(lf, j);
                rg = max(rg, j);
            }
        }

        for (int j = lf; j <= rg; ++j) {
            b[j] = i;
        }
    }
    if (a != b) {
        cout << 0 << endl;
        return 0;
    }

    // for (int i = 0; i < m; ++i) {
    //     cout << a[i] << " ";
    // }
    // cout << endl;

    for (int i = 0; i <= m; ++i) {
        f[i][i] = 1;
    }

    for (int len = 1; len <= m; ++len) {
        for (int i = 0; i + len <= m; ++i) {
            int j = i + len;
            int pos = i;
            vector<int> ps = {i};

            for (int k = i + 1; k < j; ++k) {
                if (a[pos] > a[k]) {
                    pos = k;
                    ps = {k};
                } else if (a[pos] == a[k]) {
                    ps.push_back(k);
                }
            }

            int u = 0, v = 0;

            for (int k = i; k <= ps[0]; ++k) {
                int c = f[i][k];
                mul(c, f[k][ps[0]]);
                add(u, c);
            }

            for (int k = ps.back() + 1; k <= j; ++k) {
                int c = f[ps.back() + 1][k];
                mul(c, f[k][j]);
                add(v, c);
            }

            f[i][j] = u;
            mul(f[i][j], v);

            for (int k = 0; k < sz(ps) - 1; ++k) {
                mul(f[i][j], f[ps[k] + 1][ps[k + 1]]);
            }
            // cout << i << " " << j << " " << ps[0] << " " << ps[1] << " " << f[i][j] << endl;
        }
    }

    cout << f[0][m] << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,N=1010;
inline int add(int a,int b)
{
	if((a+=b)>=mod)a-=mod;
	return a;
}
inline int mult(int a,int b)
{
	long long t=1ll*a*b;
	if(t>=mod)t%=mod;
	return t;
}
int n,m,a[1000010],tot,b[1010],nxt[1010],pre[1010],L[1010],R[1010],mi[1010][1010],dp[1010][1010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
		if(a[i]!=a[i-1])b[++tot]=a[i];
	if(tot>2*n)
	{
		puts("0");
		return 0;
	}
	m=tot;
	copy(b+1,b+m+1,a+1);
	for(int i=1;i<=m;i++)
	{
		if(pre[a[i]])nxt[pre[a[i]]]=i;
		pre[a[i]]=i;
	}
	for(int i=1;i<=n;i++)if(pre[a[i]])nxt[pre[a[i]]]=m+1;
	memset(L,0x3f,sizeof(L));
	memset(mi,0x3f,sizeof(mi));
	for(int i=1;i<=m;i++)L[a[i]]=min(L[a[i]],i),R[a[i]]=max(R[a[i]],i);
	for(int i=1;i<=m;i++)
	{
		for(int j=i;j<=m;j++)
		{
			for(int k=i;k<=j;k++)
			{
				mi[i][j]=min(mi[i][j],a[k]);
			}
		}
	}
	for(int i=0;i<=m+1;i++)
	{
		if(i>=1&&i<=m&&L[mi[i][i]]==i&&R[mi[i][i]]==i)dp[i][i]=1;
		for(int j=i+1;j<=m+1;j++)dp[j][i]=1;
		for(int j=0;j<=i-1;j++)dp[i][j]=1;
	}
	for(int len=1;len<m;len++)
	{
		for(int i=1;i+len<=m;i++)
		{
			int j=i+len;
			int p=mi[i][i+len];
			if(p>N)continue;
			if(L[p]<i||R[p]>j)continue;
			int cntl=0,cntr=0,t=1;
			for(int k=i;k<=L[p];k++)
			{
				cntl=add(cntl,mult(dp[i][k-1],dp[k][L[p]-1]));
			}
			for(int k=R[p];k<=j;k++)
			{
				cntr=add(cntr,mult(dp[R[p]+1][k],dp[k+1][j]));
			}
			for(int k=L[p];k<R[p];k++)t=mult(t,dp[k+1][nxt[k]-1]);
			dp[i][j]=mult(mult(cntl,cntr),t);
		}
	}
	printf("%d\n",dp[1][m]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,N=1010;
inline int add(int a,int b)
{
	if((a+=b)>=mod)a-=mod;
	return a;
}
inline int mult(int a,int b)
{
	long long t=1ll*a*b;
	if(t>=mod)t%=mod;
	return t;
}
int n,m,a[1000010],tot,b[1010],nxt[1010],pre[1010],L[1010],R[1010],mi[1010][1010],dp[1010][1010];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
		if(a[i]!=a[i-1])b[++tot]=a[i];
	if(tot>2*n)
	{
		puts("0");
		return 0;
	}
	m=tot;
	copy(b+1,b+m+1,a+1);
	for(int i=1;i<=m;i++)
	{
		if(pre[a[i]])nxt[pre[a[i]]]=i;
		pre[a[i]]=i;
	}
	for(int i=1;i<=n;i++)if(pre[a[i]])nxt[pre[a[i]]]=m+1;
	memset(L,0x3f,sizeof(L));
	memset(mi,0x3f,sizeof(mi));
	for(int i=1;i<=m;i++)L[a[i]]=min(L[a[i]],i),R[a[i]]=max(R[a[i]],i);
	for(int i=1;i<=m;i++)
	{
		for(int j=i;j<=m;j++)
		{
			for(int k=i;k<=j;k++)
			{
				mi[i][j]=min(mi[i][j],a[k]);
			}
		}
	}
	for(int i=0;i<=m+1;i++)
	{
		if(i>=1&&i<=m&&L[mi[i][i]]==i&&R[mi[i][i]]==i)dp[i][i]=1;
		for(int j=i+1;j<=m+1;j++)dp[j][i]=1;
		for(int j=0;j<=i-1;j++)dp[i][j]=1;
	}
	for(int len=1;len<m;len++)
	{
		for(int i=1;i+len<=m;i++)
		{
			int j=i+len;
			int p=mi[i][j];
			if(p>N)continue;
			if(L[p]<i||R[p]>j)continue;
			int cntl=0,cntr=0,t=1;
			for(int k=i;k<=L[p];k++)
			{
				cntl=add(cntl,mult(dp[i][k-1],dp[k][L[p]-1]));
			}
			for(int k=R[p];k<=j;k++)
			{
				cntr=add(cntr,mult(dp[R[p]+1][k],dp[k+1][j]));
			}
			for(int k=L[p];k<R[p];k=nxt[k])t=mult(t,dp[k+1][nxt[k]-1]);
			dp[i][j]=mult(mult(cntl,cntr),t);
		}
	}
	printf("%d\n",dp[1][m]);
	return 0;
}


///In the name of GOD
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MXN = 500 + 10;
const ll MX6 = 1e6 + 10;
const ll MOD = 998244353;
ll n, m, val, len = 1;
ll A[MXN], B[MX6], dp[MXN][MXN], Min[MXN][MXN];
vector<ll> Pos[MXN];
bool cont;
int main(){
    ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) cin >> B[i];
    for(int i = 1; i <= m; i ++){
        ll j = i;
        while(j <= m && B[j] == B[i]) j ++;
        A[len] = B[i];
        i = j - 1, len ++;
    }
    m = len - 1;
    if(m > 2 * n + 2) return cout << 0, 0;
    for(int i = 0; i <= m + 1; i ++){
        for(int j = 0; j <= m + 1; j ++) dp[i][j] = 1;
    }
    for(int i = 1; i <= m; i ++) Pos[A[i]].push_back(i);
    for(int len = 1; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            Min[l][r] = l;
            for(int i = l; i <= r; i ++){
                if(A[i] < A[Min[l][r]]) Min[l][r] = i;
            }
        }
    }
    for(int i = 1; i <= m; i ++) dp[i][i] = (Pos[A[i]].size() == 1);
    for(int len = 2; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            val = dp[l][r] = cont = 0;
            for(int i = l; i <= r; i ++){
                if(Pos[A[i]][0] < l || Pos[A[i]][Pos[A[i]].size() - 1] > r) cont = 1;
            }
            if(cont) continue;
            ll rng = A[Min[l][r]], now = 1, sz = Pos[rng].size();
            for(int i = 0; i < sz - 1; i ++){
                now = (now * dp[Pos[rng][i] + 1][Pos[rng][i + 1] - 1]) % MOD;
            }
            for(int i = l; i <= Pos[rng][0]; i ++){
                val = (val + (dp[l][i - 1] * dp[i][Pos[rng][0] - 1] % MOD)) % MOD;
            }
            for(int i = Pos[rng][sz - 1]; i <= r; i ++){
                dp[l][r] = (dp[l][r] + (dp[Pos[rng][sz - 1] + 1][i] * dp[i + 1][r] % MOD)) % MOD;
            }
            dp[l][r] = (dp[l][r] * (val * now % MOD)) % MOD;
        }
    }
    cout << dp[1][m] << '\n';
    return 0;
}
/*!
    HE'S AN INSTIGATOR,
    ENEMY ELIMINATOR,
    AND WHEN HE KNOCKS YOU BETTER
    YOU BETTER LET HIM IN.
*/
//! N.N


///In the name of GOD
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MXN = 2e3 + 10;
const ll MX6 = 1e6 + 10;
const ll MOD = 998244353;
ll n, m, val, len = 1;
ll A[MX6], B[MX6], dp[MXN][MXN], Min[MXN][MXN];
vector<ll> Pos[MXN];
bool cont;
int main(){
    ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) cin >> B[i];
    for(int i = 1; i <= m; i ++){
        ll j = i;
        while(j <= m && B[j] == B[i]) j ++;
        A[len] = B[i];
        i = j - 1, len ++;
    }
    m = len - 1;
    if(m > 2 * n + 2) return cout << 0, 0;
    for(int i = 0; i <= m + 1; i ++){
        for(int j = 0; j <= m + 1; j ++) dp[i][j] = 1;
    }
    for(int i = 1; i <= m; i ++) Pos[A[i]].push_back(i);
    for(int len = 1; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            Min[l][r] = l;
            for(int i = l; i <= r; i ++){
                if(A[i] < A[Min[l][r]]) Min[l][r] = i;
            }
        }
    }
    for(int i = 1; i <= m; i ++) dp[i][i] = (Pos[A[i]].size() == 1);
    for(int len = 2; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            val = dp[l][r] = cont = 0;
            for(int i = l; i <= r; i ++){
                if(Pos[A[i]][0] < l || Pos[A[i]][Pos[A[i]].size() - 1] > r) cont = 1;
            }
            if(cont) continue;
            ll rng = A[Min[l][r]], now = 1, sz = Pos[rng].size();
            for(int i = 0; i < sz - 1; i ++){
                now = (now * dp[Pos[rng][i] + 1][Pos[rng][i + 1] - 1]) % MOD;
            }
            for(int i = l; i <= Pos[rng][0]; i ++){
                val = (val + (dp[l][i - 1] * dp[i][Pos[rng][0] - 1] % MOD)) % MOD;
            }
            for(int i = Pos[rng][sz - 1]; i <= r; i ++){
                dp[l][r] = (dp[l][r] + (dp[Pos[rng][sz - 1] + 1][i] * dp[i + 1][r] % MOD)) % MOD;
            }
            dp[l][r] = (dp[l][r] * (val * now % MOD)) % MOD;
        }
    }
    cout << dp[1][m] << '\n';
    return 0;
}
/*!
    HE'S AN INSTIGATOR,
    ENEMY ELIMINATOR,
    AND WHEN HE KNOCKS YOU BETTER
    YOU BETTER LET HIM IN.
*/
//! N.N


///In the name of GOD
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MXN = 2e3 + 10;
const ll MX6 = 1e6 + 10;
const ll MOD = 998244353;
ll n, m, val, len = 1;
ll A[MXN], B[MX6], dp[MXN][MXN], Min[MXN][MXN];
vector<ll> Pos[MXN];
bool cont;
int main(){
    ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) cin >> B[i];
    for(int i = 1; i <= m; i ++){
        ll j = i;
        while(j <= m && B[j] == B[i]) j ++;
        A[len] = B[i];
        i = j - 1, len ++;
    }
    m = len - 1;
    if(m > 2 * n + 2) return cout << 0, 0;
    for(int i = 0; i <= m + 1; i ++){
        for(int j = 0; j <= m + 1; j ++) dp[i][j] = 1;
    }
    for(int i = 1; i <= m; i ++) Pos[A[i]].push_back(i);
    for(int len = 1; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            Min[l][r] = l;
            for(int i = l; i <= r; i ++){
                if(A[i] < A[Min[l][r]]) Min[l][r] = i;
            }
        }
    }
    for(int i = 1; i <= m; i ++) dp[i][i] = (Pos[A[i]].size() == 1);
    for(int len = 2; len <= m; len ++){
        for(int l = 1, r = len; r <= m; l ++, r ++){
            val = dp[l][r] = cont = 0;
            for(int i = l; i <= r; i ++){
                if(Pos[A[i]][0] < l || Pos[A[i]][Pos[A[i]].size() - 1] > r) cont = 1;
            }
            if(cont) continue;
            ll rng = A[Min[l][r]], now = 1, sz = Pos[rng].size();
            for(int i = 0; i < sz - 1; i ++){
                now = (now * dp[Pos[rng][i] + 1][Pos[rng][i + 1] - 1]) % MOD;
            }
            for(int i = l; i <= Pos[rng][0]; i ++){
                val = (val + (dp[l][i - 1] * dp[i][Pos[rng][0] - 1] % MOD)) % MOD;
            }
            for(int i = Pos[rng][sz - 1]; i <= r; i ++){
                dp[l][r] = (dp[l][r] + (dp[Pos[rng][sz - 1] + 1][i] * dp[i + 1][r] % MOD)) % MOD;
            }
            dp[l][r] = (dp[l][r] * (val * now % MOD)) % MOD;
        }
    }
    cout << dp[1][m] << '\n';
    return 0;
}
/*!
    HE'S AN INSTIGATOR,
    ENEMY ELIMINATOR,
    AND WHEN HE KNOCKS YOU BETTER
    YOU BETTER LET HIM IN.
*/
//! N.N


#include <bits/stdc++.h>

#define itn int
#define all(x) (x).begin(), (x).end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())

#define random_shuffle(...) shuffle(__VA_ARGS__, rng)
#define rand() rng()

#ifdef OLBOEB
	#define return std::cerr << __FUNCTION__ << "\n"; return
#endif  // OLBOEB

using namespace std;

inline int nxt() {
	int x;
	scanf("%d", &x);
	return x;
}

const int N = 1010;
const int mod = 998244353;

long long dp[N][N];
int mn[N][N];

int main() {
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

	int n = nxt(), m = nxt();
	vector<int> a(m);
	for (int i = 0; i < m; ++i) {
		a[i] = nxt() - 1;
	}

	vector<int> le(n, m), ri(n);
	for (int i = 0; i < m; ++i) {
		le[a[i]] = min(le[a[i]], i);
		ri[a[i]] = max(ri[a[i]], i + 1);
	}
	for (int i = n - 1; i >= 0; --i) {
		for (int j = i + 1; j < n; ++j) {
			if (le[j] >= ri[i] || le[i] >= ri[j]) {
				continue;
			}
			if (!(le[j] > le[i] && ri[j] < ri[i])) {
				cout << "0\n";
				return 0;
			}
		}
	}

	// vector<vector<int>> subs(n);
	{
		vector<int> st = {};
		for (int i = 0; i < m; ++i) {
			if (le[a[i]] == i) {
				// if (!st.empty()) {
				// 	subs[st.back()].push_back(a[i]);
				// }
				st.push_back(a[i]);
			}
			if (ri[a[i]] == i + 1) {
				assert(st.back() == a[i]);
				st.pop_back();
			}
			if (!st.empty() && !(le[st.back()] <= le[a[i]] && ri[st.back()] >= ri[a[i]])) {
				cout << "0\n";
				return 0;
			}
		}
	}

	vector<int> everything;
	for (int i = 0; i < n; ++i) {
		everything.push_back(le[i]);
		everything.push_back(ri[i]);
	}
	make_unique(everything);
	int sz = everything.size();
	for (int i = 0; i < n; ++i) {
		le[i] = lower_bound(all(everything), le[i]) - everything.begin();
		ri[i] = lower_bound(all(everything), ri[i]) - everything.begin();
	}

	memset(mn, -1, sizeof(mn));
	for (int i = n - 1; i >= 0; --i) {
		for (int l = 0; l <= le[i]; ++l) {
			for (int r = ri[i]; r <= sz; ++r) {
				mn[l][r] = i;
			}
		}
	}

	vector<vector<pair<int, int>>> subs(n);
	for (int i = 0; i < n; ++i) {
		vector<pair<int, int>> ev;
		for (int j = i + 1; j < n; ++j) {
			if (le[j] > le[i] && ri[j] < ri[i]) {
				ev.push_back({le[j], -1});
				ev.push_back({ri[j], 1});
			}
		}
		sort(all(ev));
		int bal = 0;
		for (auto [id, x] : ev) {
			if (bal == 0) {
				subs[i].push_back({id, 0});
			}
			if (x == -1) {
				++bal;
			} else {
				--bal;
			}
			if (bal == 0) {
				subs[i].back().second = id;
			}
		}
	}

	for (int i = 0; i <= sz; ++i) {
		dp[i][i] = 1;
	}
	for (int len = 1; len < sz; ++len) {
		for (int l = 0; l + len < sz; ++l) {
			int r = l + len;
			if (mn[l][r] == -1) {
				continue;
			}
			int idx = mn[l][r];

			long long t1 = 0, t2 = 0;
			for (int i = 0; i <= le[idx] - l; ++i) {
				t1 += dp[l][l + i] * dp[l + i][le[idx]] % mod;
			}
			for (int i = 0; i <= r - ri[idx]; ++i) {
				t2 += dp[ri[idx]][ri[idx] + i] * dp[ri[idx] + i][r] % mod;
			}
			t1 %= mod;
			t2 %= mod;
			dp[l][r] = t1 * t2 % mod;

			for (auto [ll, rr] : subs[idx]) {
				dp[l][r] = dp[l][r] * dp[ll][rr] % mod;
			}
			// cerr << l << " " << r << ": " << idx << ", " << dp[l][r] << "\n";
		}
	}

	// for (int i = 0; i < n; ++i) {
	// 	for (int j = i + 1; j <= n; ++j) {
	// 		cerr << dp[i][j] << " ";
	// 	}
	// 	cerr << "\n";
	// }
	cout << dp[0][sz - 1] << "\n";

	return 0;
}


#include <bits/stdc++.h>

#define itn int
#define all(x) (x).begin(), (x).end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())

#define random_shuffle(...) shuffle(__VA_ARGS__, rng)
#define rand() rng()

#ifdef OLBOEB
	#define return std::cerr << __FUNCTION__ << "\n"; return
#endif  // OLBOEB

using namespace std;

inline int nxt() {
	int x;
	scanf("%d", &x);
	return x;
}

const int N = 1010;
const int mod = 998244353;

long long dp[N][N];
int mn[N][N];

int main() {
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

	int n = nxt(), m = nxt();
	vector<int> a(m);
	for (int i = 0; i < m; ++i) {
		a[i] = nxt() - 1;
	}

	vector<int> le(n, m), ri(n);
	for (int i = 0; i < m; ++i) {
		le[a[i]] = min(le[a[i]], i);
		ri[a[i]] = max(ri[a[i]], i + 1);
	}
	for (int i = n - 1; i >= 0; --i) {
		for (int j = i + 1; j < n; ++j) {
			if (le[j] >= ri[i] || le[i] >= ri[j]) {
				continue;
			}
			if (!(le[j] > le[i] && ri[j] < ri[i])) {
				cout << "0\n";
				return 0;
			}
		}
	}

	// vector<vector<int>> subs(n);
	// {
	// 	vector<int> st = {};
	// 	for (int i = 0; i < m; ++i) {
	// 		if (le[a[i]] == i) {
	// 			if (!st.empty()) {
	// 				subs[st.back()].push_back(a[i]);
	// 			}
	// 			st.push_back(a[i]);
	// 		}
	// 		if (ri[a[i]] == i + 1) {
	// 			assert(st.back() == a[i]);
	// 			st.pop_back();
	// 		}
	// 	}
	// }

	vector<int> everything;
	for (int i = 0; i < n; ++i) {
		everything.push_back(le[i]);
		everything.push_back(ri[i]);
	}
	make_unique(everything);
	int sz = everything.size();
	for (int i = 0; i < n; ++i) {
		le[i] = lower_bound(all(everything), le[i]) - everything.begin();
		ri[i] = lower_bound(all(everything), ri[i]) - everything.begin();
	}

	memset(mn, -1, sizeof(mn));
	for (int i = n - 1; i >= 0; --i) {
		for (int l = 0; l <= le[i]; ++l) {
			for (int r = ri[i]; r <= sz; ++r) {
				mn[l][r] = i;
			}
		}
	}

	vector<vector<pair<int, int>>> subs(n);
	for (int i = 0; i < n; ++i) {
		vector<pair<int, int>> ev;
		for (int j = i + 1; j < n; ++j) {
			if (le[j] > le[i] && ri[j] < ri[i]) {
				ev.push_back({le[j], -1});
				ev.push_back({ri[j], 1});
			}
		}
		sort(all(ev));
		int bal = 0;
		for (auto [id, x] : ev) {
			if (bal == 0) {
				subs[i].push_back({id, 0});
			}
			if (x == -1) {
				++bal;
			} else {
				--bal;
			}
			if (bal == 0) {
				subs[i].back().second = id;
			}
		}
	}

	for (int i = 0; i <= sz; ++i) {
		dp[i][i] = 1;
	}
	for (int len = 1; len < sz; ++len) {
		for (int l = 0; l + len < sz; ++l) {
			int r = l + len;
			if (mn[l][r] == -1) {
				continue;
			}
			int idx = mn[l][r];

			long long t1 = 0, t2 = 0;
			for (int i = 0; i <= le[idx] - l; ++i) {
				t1 += dp[l][l + i] * dp[l + i][le[idx]] % mod;
			}
			for (int i = 0; i <= r - ri[idx]; ++i) {
				t2 += dp[ri[idx]][ri[idx] + i] * dp[ri[idx] + i][r] % mod;
			}
			t1 %= mod;
			t2 %= mod;
			dp[l][r] = t1 * t2 % mod;

			for (auto [ll, rr] : subs[idx]) {
				dp[l][r] = dp[l][r] * dp[ll][rr] % mod;
			}
			// cerr << l << " " << r << ": " << idx << ", " << dp[l][r] << "\n";
		}
	}

	// for (int i = 0; i < n; ++i) {
	// 	for (int j = i + 1; j <= n; ++j) {
	// 		cerr << dp[i][j] << " ";
	// 	}
	// 	cerr << "\n";
	// }
	cout << dp[0][sz - 1] << "\n";

	return 0;
}


#include <bits/stdc++.h>

#define itn int
#define all(x) (x).begin(), (x).end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())

#define random_shuffle(...) shuffle(__VA_ARGS__, rng)
#define rand() rng()

#ifdef OLBOEB
	#define return std::cerr << __FUNCTION__ << "\n"; return
#endif  // OLBOEB

using namespace std;

inline int nxt() {
	int x;
	scanf("%d", &x);
	return x;
}

const int N = 1010;
const int mod = 998244353;

long long dp[N][N];
int mn[N][N];

int main() {
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

	int n = nxt(), m = nxt();
	vector<int> a(m);
	for (int i = 0; i < m; ++i) {
		a[i] = nxt() - 1;
	}

	vector<int> le(n, m), ri(n);
	for (int i = 0; i < m; ++i) {
		le[a[i]] = min(le[a[i]], i);
		ri[a[i]] = max(ri[a[i]], i + 1);
	}
	for (int i = n - 1; i >= 0; --i) {
		for (int j = i + 1; j < n; ++j) {
			if (le[j] >= ri[i] || le[i] >= ri[j]) {
				continue;
			}
			if (!(le[j] > le[i] && ri[j] < ri[i])) {
				cout << "0\n";
				return 0;
			}
		}
	}

	vector<vector<int>> subs(n);
	{
		vector<int> st = {};
		for (int i = 0; i < m; ++i) {
			if (le[a[i]] == i) {
				// if (!st.empty()) {
				// 	subs[st.back()].push_back(a[i]);
				// }
				st.push_back(a[i]);
			}
			if (ri[a[i]] == i + 1) {
				assert(st.back() == a[i]);
				st.pop_back();
			}
			if (!st.empty() && !(le[st.back()] <= le[a[i]] && ri[st.back()] >= ri[a[i]])) {
				cout << "0\n";
				return 0;
			}
		}
	}

	vector<int> everything;
	for (int i = 0; i < n; ++i) {
		everything.push_back(le[i]);
		everything.push_back(ri[i]);
	}
	make_unique(everything);
	int sz = everything.size();
	for (int i = 0; i < n; ++i) {
		le[i] = lower_bound(all(everything), le[i]) - everything.begin();
		ri[i] = lower_bound(all(everything), ri[i]) - everything.begin();
	}

	memset(mn, -1, sizeof(mn));
	for (int i = n - 1; i >= 0; --i) {
		for (int l = 0; l <= le[i]; ++l) {
			for (int r = ri[i]; r <= sz; ++r) {
				mn[l][r] = i;
			}
		}
	}

	vector<vector<pair<int, int>>> subs(n);
	for (int i = 0; i < n; ++i) {
		vector<pair<int, int>> ev;
		for (int j = i + 1; j < n; ++j) {
			if (le[j] > le[i] && ri[j] < ri[i]) {
				ev.push_back({le[j], -1});
				ev.push_back({ri[j], 1});
			}
		}
		sort(all(ev));
		int bal = 0;
		for (auto [id, x] : ev) {
			if (bal == 0) {
				subs[i].push_back({id, 0});
			}
			if (x == -1) {
				++bal;
			} else {
				--bal;
			}
			if (bal == 0) {
				subs[i].back().second = id;
			}
		}
	}

	for (int i = 0; i <= sz; ++i) {
		dp[i][i] = 1;
	}
	for (int len = 1; len < sz; ++len) {
		for (int l = 0; l + len < sz; ++l) {
			int r = l + len;
			if (mn[l][r] == -1) {
				continue;
			}
			int idx = mn[l][r];

			long long t1 = 0, t2 = 0;
			for (int i = 0; i <= le[idx] - l; ++i) {
				t1 += dp[l][l + i] * dp[l + i][le[idx]] % mod;
			}
			for (int i = 0; i <= r - ri[idx]; ++i) {
				t2 += dp[ri[idx]][ri[idx] + i] * dp[ri[idx] + i][r] % mod;
			}
			t1 %= mod;
			t2 %= mod;
			dp[l][r] = t1 * t2 % mod;

			for (auto [ll, rr] : subs[idx]) {
				dp[l][r] = dp[l][r] * dp[ll][rr] % mod;
			}
			// cerr << l << " " << r << ": " << idx << ", " << dp[l][r] << "\n";
		}
	}

	// for (int i = 0; i < n; ++i) {
	// 	for (int j = i + 1; j <= n; ++j) {
	// 		cerr << dp[i][j] << " ";
	// 	}
	// 	cerr << "\n";
	// }
	cout << dp[0][sz - 1] << "\n";

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;
const int MAXN = 1e6 + 10;

map<int, int> dp[MAXN];
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp[L].count(R))
        return dp[L][R];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1, false), waysR = calc(reR + 1, R, false), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[L][R] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;
const int MAXN = 1e6 + 10;

map<int, int> dp[MAXN];
int precol[MAXN], col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp[L].count(R))
        return dp[L][R];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1, false), waysR = calc(reR + 1, R, false), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[L][R] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    int pt = 1;
    for(int i = 1; i <= m; i++)
        cin >> precol[i];
    for(int i = 2; i <= m + 1; i++)
        if(precol[i] != precol[i - 1])
            col[pt++] = precol[i - 1];
    m = pt - 1;
    for(int i = 1; i <= m; i++)
        positions[col[i]].push_back(i);
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad || m > 2*n) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;

map<ii, int> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1, false), waysR = calc(reR + 1, R, false), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[{L, R}] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;
const int MAXN = 1e6 + 10;

map<int, int> dp[MAXN];
int precol[MAXN], col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp[L].count(R))
        return dp[L][R];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1, false), waysR = calc(reR + 1, R, false), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[L][R] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    int pt = 1;
    for(int i = 1; i <= m; i++)
        cin >> precol[i];
    for(int i = 2; i <= m + 1; i++)
        if(precol[i] != precol[i - 1])
            col[pt++] = precol[i - 1];
    m = pt - 1;
    for(int i = 1; i <= m; i++)
        positions[col[i]].push_back(i);
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;
const int MAXN = 1e6 + 10;

int dp[1005][1005];
int precol[MAXN], col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    assert(L >= 0);
    assert(R >= 0);
    if(dp[L][R] != -1)
        return dp[L][R];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= n; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    if(color == n + 1)
        return dp[L][R] = 0;

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[L][R] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    int pt = 1;
    for(int i = 1; i <= m; i++)
        cin >> precol[i];
    for(int i = 2; i <= m + 1; i++)
        if(precol[i] != precol[i - 1])
            col[pt++] = precol[i - 1];
    m = pt - 1;
    if(m > 2*n) {
        cout << "0\n";
        return 0;
    }
    for(int i = 1; i <= m; i++)
        positions[col[i]].push_back(i);
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    for(int i = 0; i < 1005; i++)
        for(int j = 0; j < 1005; j++)
            dp[i][j] = -1;

    cout << endl;
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;

map<ii, int> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1, false), waysR = calc(reR + 1, R, false), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1, false) * calc(le[oc], reL - 1, (reL - 1 == ri[oc]))) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R, false) * calc(reR + 1, ri[oc], (reR + 1 == le[oc]))) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[{L, R}] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;

map<ii, int> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return dp[{L, R}] = 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[{L, R}] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;

const ll MOD = 998244353;

map<ii, ll> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return dp[{L, R}] = 1;

    int color = 1;
    for(; color <= n; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    if(color == n + 1)
        return dp[L][R] = 0;

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[{L, R}] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;

map<ii, int> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R, bool save = true) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1, false)) % MOD;
    }
    if(save)
        dp[{L, R}] = tot;
    return tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;

const ll MOD = 998244353;

map<ii, ll> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return dp[{L, R}] = 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[{L, R}] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;

const ll MOD = 998244353;
const int MAXN = 1e6 + 10;

int dp[1005][1005];
int precol[MAXN], col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    if(dp[L][R] != -1)
        return dp[L][R];
    if(L == R + 1)
        return 1;

    int color = 1;
    for(; color <= 500; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[L][R] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    int pt = 1;
    for(int i = 1; i <= m; i++)
        cin >> precol[i];
    for(int i = 2; i <= m + 1; i++)
        if(precol[i] != precol[i - 1])
            col[pt++] = precol[i - 1];
    m = pt - 1;
    if(m > 2*n) {
        cout << "0\n";
        return 0;
    }
    for(int i = 1; i <= m; i++)
        positions[col[i]].push_back(i);
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    for(int i = 0; i < 1005; i++)
        for(int j = 0; j < 1005; j++)
            dp[i][j] = -1;
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;

const ll MOD = 998244353;

map<ii, ll> dp;
const int MAXN = 1e6 + 10;
int col[MAXN], le[505], ri[505], n, m;
vector<int> positions[505];

ll calc(int L, int R) {
    if(dp.count({L, R}))
        return dp[{L, R}];
    if(L == R + 1)
        return dp[{L, R}] = 1;

    int color = 1;
    for(; color <= n; color++) {
        if(le[color] >= L && ri[color] <= R)
            break;
    }

    if(color == n + 1)
        return dp[{L, R}] = 0;

    int reL = le[color], reR = ri[color];

    ll waysL = calc(L, reL - 1), waysR = calc(reR + 1, R), tot = 1;
    for(int oc = 1; oc <= n; oc++) {
        if(ri[oc] <= reL && le[oc] >= L && oc != color)
            waysL = (waysL + calc(L, le[oc] - 1) * calc(le[oc], reL - 1)) % MOD;
    }
    for(int oc = 1; oc <= n; oc++) {
        if(le[oc] >= reR && ri[oc] <= R && oc != color)
            waysR = (waysR + calc(ri[oc] + 1, R) * calc(reR + 1, ri[oc])) % MOD;
    }
    tot = (waysL * waysR) % MOD;
    for(int i = 1; i < positions[color].size(); i++) {
        if(positions[color][i] > positions[color][i - 1] + 1)
            tot = (tot * calc(positions[color][i - 1] + 1, positions[color][i] - 1)) % MOD;
    }
    return dp[{L, R}] = tot;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        cin >> col[i];
        positions[col[i]].push_back(i);
    }
    for(int i = 1; i <= m; i++)
        ri[col[i]] = i;
    for(int i = m; i >= 1; i--)
        le[col[i]] = i;
    bool bad = false;
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(ri[i] <= ri[j] && ri[i] >= le[j])
                bad = true;
            if(le[i] <= ri[j] && le[i] >= le[j])
                bad = true;
        }
    }
    if(bad) {
        cout << "0\n";
        return 0;
    }
    cout << calc(1, m) << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;

const ll MOD = 998244353;

void bad() {
  cout << 0 << endl;
  exit(0);
}

#define sz(a) (a.size())
#define rep(i, a, b) for (int i = a; i < b; i++)

template <class T> struct RMQ {
  vector<vector<T>> jmp;
  RMQ() {}
  RMQ(const vector<T> &V) {
    int N = sz(V), on = 1, depth = 1;
    while (on < sz(V))
      on *= 2, depth++;
    jmp.assign(depth, V);
    rep(i, 0, depth - 1) rep(j, 0, N) jmp[i + 1][j] =
        min(jmp[i][j], jmp[i][min(N - 1, j + (1 << i))]);
  }

  T query(int a, int b) {
    assert(a < b);
    int dep = 31 - __builtin_clz(b - a);
    return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  }
};

int N, M;
vector<int> C;
vector<vector<int>> O;
RMQ<int> q;

ll mul(ll a, ll b) { return (a * b) % MOD; }
ll add(ll a, ll b) { return (a + b) % MOD; }

int DP[7005][7005];

int dp(int l, int r, int m = -1) {
  if (r - l <= 1) {
    return 1;
  }
  int a = DP[l][r];
  if (a != -1)
    return a;
  ll ans = 0;
  if (m == -1) {
    m = q.query(l, r);
  }
  int lb = O[m].front();
  ll sum1 = 0;
  for (int i = l; i <= lb; i++) {
    ll d1 = dp(l, i);
    ll d2 = dp(i, lb);
    sum1 = add(sum1, mul(d1, d2));
  }
  int rb = O[m].back();
  ll sum2 = 0;
  for (int i = rb + 1; i <= r; i++) {
    ll d1 = dp(rb + 1, i);
    ll d2 = dp(i, r);
    sum2 = add(sum2, mul(d1, d2));
  }
  ans = mul(sum1, sum2);
  for (int i = 0; i < O[m].size() - 1; i++) {
    ans = mul(ans, dp(O[m][i] + 1, O[m][i + 1]));
  }
  return DP[l][r] = ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> N >> M;
  C.resize(M);
  O.resize(N);
  for (int i = 0; i < M; i++) {
    cin >> C[i];
    C[i]--;
  }
  C.resize(unique(C.begin(), C.end()) - C.begin());
  M = C.size();
  for (int i = 0; i < M; i++) {
    O[C[i]].push_back(i);
  }

  q = RMQ(C);
  // Check if it is doable

  for (int i = 0; i < N; i++) {
    if (q.query(O[i].front(), O[i].back() + 1) < i)
      bad();
  }

  memset(DP, -1, sizeof(DP));

  cout << dp(0, M) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;

const ll MOD = 998244353;

void bad() {
  cout << 0 << endl;
  exit(0);
}

#define sz(a) (a.size())
#define rep(i, a, b) for (int i = a; i < b; i++)

template <class T> struct RMQ {
  vector<vector<T>> jmp;
  RMQ() {}
  RMQ(const vector<T> &V) {
    int N = sz(V), on = 1, depth = 1;
    while (on < sz(V))
      on *= 2, depth++;
    jmp.assign(depth, V);
    rep(i, 0, depth - 1) rep(j, 0, N) jmp[i + 1][j] =
        min(jmp[i][j], jmp[i][min(N - 1, j + (1 << i))]);
  }

  T query(int a, int b) {
    assert(a < b);
    int dep = 31 - __builtin_clz(b - a);
    return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  }
};

int N, M;
vector<int> C;
vector<vector<int>> O;
RMQ<int> q;

ll mul(ll a, ll b) { return (a * b) % MOD; }
ll add(ll a, ll b) { return (a + b) % MOD; }

int DP[7005][7005];

int dp(int l, int r, int m = -1) {
  if (r - l == 0) {
    return 1;
  }
  int a = DP[l][r];
  if (a != -1)
    return a;
  ll ans = 0;
  if (m == -1) {
    m = q.query(l, r);
  }
  if (O[m].front() < l || O[m].back() >= r) {
    return 0;
  }
  int lb = O[m].front();
  ll sum1 = 0;
  for (int i = l; i <= lb; i++) {
    ll d1 = dp(l, i);
    ll d2 = dp(i, lb);
    sum1 = add(sum1, mul(d1, d2));
  }
  int rb = O[m].back();
  ll sum2 = 0;
  for (int i = rb + 1; i <= r; i++) {
    ll d1 = dp(rb + 1, i);
    ll d2 = dp(i, r);
    sum2 = add(sum2, mul(d1, d2));
  }
  ans = mul(sum1, sum2);
  for (int i = 0; i < O[m].size() - 1; i++) {
    ans = mul(ans, dp(O[m][i] + 1, O[m][i + 1]));
  }
  return DP[l][r] = ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> N >> M;
  C.resize(M);
  O.resize(N);
  for (int i = 0; i < M; i++) {
    cin >> C[i];
    C[i]--;
  }
  C.resize(unique(C.begin(), C.end()) - C.begin());
  M = C.size();
  for (int i = 0; i < M; i++) {
    O[C[i]].push_back(i);
  }

  q = RMQ(C);
  // Check if it is doable

  for (int i = 0; i < N; i++) {
    if (q.query(O[i].front(), O[i].back() + 1) < i)
      bad();
  }

  memset(DP, -1, sizeof(DP));

  cout << dp(0, M) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;

const ll MOD = 998244353;

void bad() {
  cout << 0 << endl;
  exit(0);
}

#define sz(a) (a.size())
#define rep(i, a, b) for (int i = a; i < b; i++)

template <class T> struct RMQ {
  vector<vector<T>> jmp;
  RMQ() {}
  RMQ(const vector<T> &V) {
    int N = sz(V), on = 1, depth = 1;
    while (on < sz(V))
      on *= 2, depth++;
    jmp.assign(depth, V);
    rep(i, 0, depth - 1) rep(j, 0, N) jmp[i + 1][j] =
        min(jmp[i][j], jmp[i][min(N - 1, j + (1 << i))]);
  }

  T query(int a, int b) {
    assert(a < b);
    int dep = 31 - __builtin_clz(b - a);
    return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  }
};

int N, M;
vector<int> C;
vector<vector<int>> O;
RMQ<int> q;

ll mul(ll a, ll b) { return (a * b) % MOD; }
ll add(ll a, ll b) { return (a + b) % MOD; }

int DP[7005][7005];

int dp(int l, int r, int m = -1) {
  if (r - l <= 1) {
    return 1;
  }
  int a = DP[l][r];
  if (a != -1)
    return a;
  ll ans = 0;
  if (m == -1) {
    m = q.query(l, r);
  }
  if (O[m].front() < l || O[m].back() >= r) {
    return 0;
  }
  int lb = O[m].front();
  ll sum1 = 0;
  for (int i = l; i <= lb; i++) {
    ll d1 = dp(l, i);
    ll d2 = dp(i, lb);
    sum1 = add(sum1, mul(d1, d2));
  }
  int rb = O[m].back();
  ll sum2 = 0;
  for (int i = rb + 1; i <= r; i++) {
    ll d1 = dp(rb + 1, i);
    ll d2 = dp(i, r);
    sum2 = add(sum2, mul(d1, d2));
  }
  ans = mul(sum1, sum2);
  for (int i = 0; i < O[m].size() - 1; i++) {
    ans = mul(ans, dp(O[m][i] + 1, O[m][i + 1]));
  }
  return DP[l][r] = ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> N >> M;
  C.resize(M);
  O.resize(N);
  for (int i = 0; i < M; i++) {
    cin >> C[i];
    C[i]--;
  }
  C.resize(unique(C.begin(), C.end()) - C.begin());
  M = C.size();
  for (int i = 0; i < M; i++) {
    O[C[i]].push_back(i);
  }

  q = RMQ(C);
  // Check if it is doable

  for (int i = 0; i < N; i++) {
    if (q.query(O[i].front(), O[i].back() + 1) < i)
      bad();
  }

  memset(DP, -1, sizeof(DP));

  cout << dp(0, M) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;

const ll MOD = 998244353;

void bad() {
  cout << 0 << endl;
  exit(0);
}

#define sz(a) (a.size())
#define rep(i, a, b) for (int i = a; i < b; i++)

template <class T> struct RMQ {
  vector<vector<T>> jmp;
  RMQ() {}
  RMQ(const vector<T> &V) {
    int N = sz(V), on = 1, depth = 1;
    while (on < sz(V))
      on *= 2, depth++;
    jmp.assign(depth, V);
    rep(i, 0, depth - 1) rep(j, 0, N) jmp[i + 1][j] =
        min(jmp[i][j], jmp[i][min(N - 1, j + (1 << i))]);
  }

  T query(int a, int b) {
    assert(a < b);
    int dep = 31 - __builtin_clz(b - a);
    return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  }
};

int N, M;
vector<int> C;
vector<vector<int>> O;
RMQ<int> q;

ll mul(ll a, ll b) { return (a * b) % MOD; }
ll add(ll a, ll b) { return (a + b) % MOD; }

int DP[4005][4005];

int dp(int l, int r, int m = -1) {
  if (r - l == 0) {
    return 1;
  }
  int a = DP[l][r];
  if (a != -1)
    return a;
  ll ans = 0;
  if (m == -1) {
    m = q.query(l, r);
  }
  if (O[m].front() < l || O[m].back() >= r) {
    return 0;
  }
  int lb = O[m].front();
  ll sum1 = 0;
  for (int i = l; i <= lb; i++) {
    ll d1 = dp(l, i);
    ll d2 = dp(i, lb);
    sum1 = add(sum1, mul(d1, d2));
  }
  int rb = O[m].back();
  ll sum2 = 0;
  for (int i = rb + 1; i <= r; i++) {
    ll d1 = dp(rb + 1, i);
    ll d2 = dp(i, r);
    sum2 = add(sum2, mul(d1, d2));
  }
  ans = mul(sum1, sum2);
  for (int i = 0; i < O[m].size() - 1; i++) {
    ans = mul(ans, dp(O[m][i] + 1, O[m][i + 1]));
  }
  return DP[l][r] = ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> N >> M;
  C.resize(M);
  O.resize(N);
  for (int i = 0; i < M; i++) {
    cin >> C[i];
    C[i]--;
  }
  C.resize(unique(C.begin(), C.end()) - C.begin());
  M = C.size();
  for (int i = 0; i < M; i++) {
    O[C[i]].push_back(i);
  }

  if (C.size() > 2000)
    bad();

  q = RMQ(C);

  memset(DP, -1, sizeof(DP));

  cout << dp(0, M) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;

const ll MOD = 998244353;

void bad() {
  cout << 0 << endl;
  exit(0);
}

#define sz(a) (a.size())
#define rep(i, a, b) for (int i = a; i < b; i++)

template <class T> struct RMQ {
  vector<vector<T>> jmp;
  RMQ() {}
  RMQ(const vector<T> &V) {
    int N = sz(V), on = 1, depth = 1;
    while (on < sz(V))
      on *= 2, depth++;
    jmp.assign(depth, V);
    rep(i, 0, depth - 1) rep(j, 0, N) jmp[i + 1][j] =
        min(jmp[i][j], jmp[i][min(N - 1, j + (1 << i))]);
  }

  T query(int a, int b) {
    assert(a < b);
    int dep = 31 - __builtin_clz(b - a);
    return min(jmp[dep][a], jmp[dep][b - (1 << dep)]);
  }
};

int N, M;
vector<int> C;
vector<vector<int>> O;
RMQ<int> q;

ll mul(ll a, ll b) { return (a * b) % MOD; }
ll add(ll a, ll b) { return (a + b) % MOD; }

ll DP[4005][4005];

ll dp(int l, int r, int m = -1) {
  if (r - l <= 1) {
    return 1;
  }
  ll &ans = DP[l][r];
  if (ans != -1)
    return ans;
  ans = 0;
  if (m == -1) {
    m = q.query(l, r);
  }
  int lb = O[m].front();
  ll sum1 = 0;
  for (int i = l; i <= lb; i++) {
    ll d1 = dp(l, i);
    ll d2 = dp(i, lb);
    sum1 = add(sum1, mul(d1, d2));
  }
  int rb = O[m].back();
  ll sum2 = 0;
  for (int i = rb + 1; i <= r; i++) {
    ll d1 = dp(rb + 1, i);
    ll d2 = dp(i, r);
    sum2 = add(sum2, mul(d1, d2));
  }
  ans = mul(sum1, sum2);
  for (int i = 0; i < O[m].size() - 1; i++) {
    ans = mul(ans, dp(O[m][i] + 1, O[m][i + 1]));
  }
  return ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> N >> M;
  C.resize(M);
  O.resize(N);
  for (int i = 0; i < M; i++) {
    cin >> C[i];
    C[i]--;
  }
  C.resize(unique(C.begin(), C.end()) - C.begin());
  M = C.size();
  for (int i = 0; i < M; i++) {
    O[C[i]].push_back(i);
  }

  q = RMQ(C);
  // Check if it is doable

  for (int i = 0; i < N; i++) {
    if (q.query(O[i].front(), O[i].back() + 1) < i)
      bad();
  }

  memset(DP, -1, sizeof(DP));

  cout << dp(0, M) << endl;
}


#include <bits/stdc++.h>

using namespace std;

const long long MOD = 998244353;

typedef vector<int> Vi;
typedef vector<Vi> Vii;
typedef vector<long long> Vl;
typedef vector<Vl> Vll;

int n, m, x, y, a[1005];

int main() {
    //freopen("COLSTRIP.INP", "r", stdin);
    //freopen("COLSTRIP.OUT", "w", stdout);

    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m; int k = m, x, y = -1;

    m = 0;
    for (int i = 1; i <= k; ++i) {
        cin >> x;
        if (x != y) {
            a[++m] = x; y = x;
        }
    }

    if (m > 2 * n) {
        cout << 0; return 0;
    }

    Vii p (n + 2);
    for (int i = 1; i <= m; ++i) p[a[i]].push_back(i);

    Vll dp (m + 2, Vl (m + 2, 0));
    for (int i = 1; i <= m + 1; ++i) dp[i][i - 1] = 1;

    for (int len = 1; len <= m; ++len)
    for (int L = 1, R = len; R <= m; ++L, ++R) {
        int c = a[L];
        for (int i = L + 1; i <= R; ++i) c = min(c, a[i]);

        int ll = p[c][0], rr = p[c].back();
        if (ll < L || R < rr) { dp[L][R] = 0; continue; }

        long long sl = 0, sr = 0;
        for (int i = L; i <= ll; ++i) sl = (sl + dp[L][i - 1] * dp[i][ll - 1]) % MOD;
        for (int i = rr; i <= R; ++i) sr = (sr + dp[rr + 1][i] * dp[i + 1][R]) % MOD;

        dp[L][R] = sl * sr % MOD;
        for (int i = 1; i < p[c].size(); ++i)
            dp[L][R] = dp[L][R] * dp[p[c][i - 1] + 1][p[c][i] - 1] % MOD;

        //cout << L << " " << R << " " << dp[L][R] << "\n";
    }

    cout << dp[1][m];
}


#include <bits/stdc++.h>

using namespace std;

const long long MOD = 998244353;

typedef vector<int> Vi;
typedef vector<Vi> Vii;
typedef vector<long long> Vl;
typedef vector<Vl> Vll;

int n, m, x, y, a[1005];

int main() {
    //freopen("COLSTRIP.INP", "r", stdin);
    //freopen("COLSTRIP.OUT", "w", stdout);

    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m; int k = m, x, y = -1;

    m = 0;
    for (int i = 1; i <= k; ++i) {
        cin >> x;
        if (x != y) a[++m] = x;
    }

    if (m > 2 * n) {
        cout << 0; return 0;
    }

    Vii p (n + 2);
    for (int i = 1; i <= m; ++i) p[a[i]].push_back(i);

    Vll dp (m + 2, Vl (m + 2, 0));
    for (int i = 1; i <= m + 1; ++i) dp[i][i - 1] = 1;

    for (int len = 1; len <= m; ++len)
    for (int L = 1, R = len; R <= m; ++L, ++R) {
        int c = a[L];
        for (int i = L + 1; i <= R; ++i) c = min(c, a[i]);

        int ll = p[c][0], rr = p[c].back();
        if (ll < L || R < rr) { dp[L][R] = 0; continue; }

        long long sl = 0, sr = 0;
        for (int i = L; i <= ll; ++i) sl = (sl + dp[L][i - 1] * dp[i][ll - 1]) % MOD;
        for (int i = rr; i <= R; ++i) sr = (sr + dp[rr + 1][i] * dp[i + 1][R]) % MOD;

        dp[L][R] = sl * sr % MOD;
        for (int i = 1; i < p[c].size(); ++i)
            dp[L][R] = dp[L][R] * dp[p[c][i - 1] + 1][p[c][i] - 1] % MOD;

        //cout << L << " " << R << " " << dp[L][R] << "\n";
    }

    cout << dp[1][m];
}


#include <bits/stdc++.h>

using namespace std;

const long long MOD = 998244353;

typedef vector<int> Vi;
typedef vector<Vi> Vii;
typedef vector<long long> Vl;
typedef vector<Vl> Vll;

int n, m, k = 0, a[1005], b[1005];

int main() {
    //freopen("COLSTRIP.INP", "r", stdin);
    //freopen("COLSTRIP.OUT", "w", stdout);

    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;

    for (int i = 1; i <= m; ++i) cin >> b[i];

    for (int i = 1; i <= m; ++i)
        if (k == 0 || b[i] != a[k]) a[++k] = b[i];

    m = k;

    if (m > 2 * n) {
        cout << 0; return 0;
    }

    Vii p (n + 2);
    for (int i = 1; i <= m; ++i) p[a[i]].push_back(i);

    Vll dp (m + 2, Vl (m + 2, 0));
    for (int i = 1; i <= m + 1; ++i) dp[i][i - 1] = 1;

    for (int len = 1; len <= m; ++len)
    for (int L = 1, R = len; R <= m; ++L, ++R) {
        int c = a[L];
        for (int i = L + 1; i <= R; ++i) c = min(c, a[i]);

        int ll = p[c][0], rr = p[c].back();
        if (ll < L || R < rr) { dp[L][R] = 0; continue; }

        long long sl = 0, sr = 0;
        for (int i = L; i <= ll; ++i) sl = (sl + dp[L][i - 1] * dp[i][ll - 1]) % MOD;
        for (int i = rr; i <= R; ++i) sr = (sr + dp[rr + 1][i] * dp[i + 1][R]) % MOD;

        dp[L][R] = sl * sr % MOD;
        for (int i = 1; i < p[c].size(); ++i)
            dp[L][R] = dp[L][R] * dp[p[c][i - 1] + 1][p[c][i] - 1] % MOD;

        //cout << L << " " << R << " " << dp[L][R] << "\n";
    }

    cout << dp[1][m];
}


#include <bits/stdc++.h>

using namespace std;

const long long MOD = 998244353;

typedef vector<int> Vi;
typedef vector<Vi> Vii;
typedef vector<long long> Vl;
typedef vector<Vl> Vll;

int n, m, k = 0, a[1005], b[1005];

int main() {
    freopen("COLSTRIP.INP", "r", stdin);
    freopen("COLSTRIP.OUT", "w", stdout);

    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;

    for (int i = 1; i <= m; ++i) cin >> b[i];

    for (int i = 1; i <= m; ++i)
        if (k == 0 || b[i] != a[k]) a[++k] = b[i];

    m = k;

    if (m > 2 * n) {
        cout << 0; return 0;
    }

    Vii p (n + 2);
    for (int i = 1; i <= m; ++i) p[a[i]].push_back(i);

    Vll dp (m + 2, Vl (m + 2, 0));
    for (int i = 1; i <= m + 1; ++i) dp[i][i - 1] = 1;

    for (int len = 1; len <= m; ++len)
    for (int L = 1, R = len; R <= m; ++L, ++R) {
        int c = a[L];
        for (int i = L + 1; i <= R; ++i) c = min(c, a[i]);

        int ll = p[c][0], rr = p[c].back();
        if (ll < L || R < rr) { dp[L][R] = 0; continue; }

        long long sl = 0, sr = 0;
        for (int i = L; i <= ll; ++i) sl = (sl + dp[L][i - 1] * dp[i][ll - 1]) % MOD;
        for (int i = rr; i <= R; ++i) sr = (sr + dp[rr + 1][i] * dp[i + 1][R]) % MOD;

        dp[L][R] = sl * sr % MOD;
        for (int i = 1; i < p[c].size(); ++i)
            dp[L][R] = dp[L][R] * dp[p[c][i - 1] + 1][p[c][i] - 1] % MOD;

        //cout << L << " " << R << " " << dp[L][R] << "\n";
    }

    cout << dp[1][m];
}


#include <bits/stdc++.h>

using namespace std;

const int N = 305;
const int M = 1e6 + 7;
const long long MOD = 998244353;

int n, m, x, l[M], r[M];
long long f[N], fc[N];
bool flag[N];

bool AinB(int a, int b) {
    return (l[b] < l[a] && r[b] > r[a]);
}

int main() {
    //freopen("COLSTRIP.INP", "r", stdin);
    //freopen("COLSTRIP.OUT", "w", stdout);

    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;

    for (int i = 1; i <= m; ++i) {
        cin >> x;
        if (l[x] == 0) l[x] = i;
        r[x] = max(r[x], i);
    }

    for (int i = 2; i <= n; ++i)
        for (int j = i - 1; j > 0; --j)
            if ((l[i] < l[j] && r[i] > l[j]) || (l[i] < r[j] && r[i] > r[j])) {
                cout << 0; return 0;
            }

    fc[0] = fc[1] = 1; fc[2] = 2;
    for (int i = 3; i <= n; ++i) {
        fc[i] = fc[i - 1] + 1;
        for (int j = 1; j < i; ++j)
            fc[i] = (f[i] + fc[j] * fc[i - j] - 1) % MOD;
    }

    for (int i = 1; i <= n; ++i) f[i] = 1;

    int nn = n;

    memset(flag, true, sizeof flag);

    while (nn) {
        bool check = false;
        for (int i = n - 1; i > 0; --i) {
            long long cnt = 0, tmp = 1;
            if (flag[i]) for (int j = n; j > i; --j)
                if (flag[j] && AinB(j, i)) {
                    ++cnt; tmp *= f[j]; flag[j] = false;
                }
            f[i] = fc[cnt] * tmp % MOD;
            if (cnt > 0) check = true;
        }
        if (!check) break;
    }

    long long cnt = 0, tmp = 1;

    for (int i = 1; i <= n; ++i)
    if (flag[i]) {
        //cout << i << " " << f[i] << "\n";
        ++cnt; tmp *= f[i];
    }

    cout << tmp * fc[cnt] % MOD;
}


#include<bits/stdc++.h>
using namespace std;
//dengyaotriangle!

const int maxm=1000006;
const int maxn=505;
const int mdn=998244353;

int n,m,l;
int c[maxm];
int a[maxm];
long long dp[maxn<<1][maxn<<1];
vector<int> oc[maxn];

int main(){
    ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){cin>>c[i];}
    for(int i=1;i<=m;i++){
        if(i==1||c[i]!=c[i-1])a[++l]=c[i];
    }
    for(int i=1;i<=l;i++){
        oc[a[i]].push_back(i);
    }
    if(l>n+n){
        cout<<0;return 0;
    }
    for(int i=0;i<=l+1;i++){for(int j=0;j<=l+1;j++){dp[i][j]=1;}}
    for(int i=l;i>=1;i--){
        for(int j=i;j<=l;j++){
            int mi=a[i];
            for(int k=i;k<=j;k++){
                if(a[k]<mi)mi=a[k];
            }
            int fv=*oc[mi].begin(),ev=*(oc[mi].end()-1);
            if(fv<i||ev>j)dp[i][j]=0;
            else{
                long long mul=1;
                for(int i=1;i<oc[mi].size();i++){
                    mul=(mul*(dp[oc[mi][i-1]+1][oc[mi][i]-1]))%mdn;
                }
                long long sm0=0,sm1=0;
                for(int k=i;k<=fv;k++){sm0+=dp[k][fv-1]*dp[i][k-1];sm0%=mdn;}
                for(int k=j;k>=ev;k--){sm1+=dp[ev+1][k]*dp[k+1][j];sm0%=mdn;}
                cerr<<fv<<','<<ev<<endl;
                dp[i][j]=mul*sm0%mdn*sm1%mdn;
            }
            //cout<<i<<','<<j<<':'<<dp[i][j]<<endl;
        }
    }
    cout<<dp[1][l];
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
//dengyaotriangle!

const int maxm=1000006;
const int maxn=505;
const int mdn=998244353;

int n,m,l;
int c[maxm];
int a[maxm];
long long dp[maxn<<1][maxn<<1];
vector<int> oc[maxn];

int main(){
    ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){cin>>c[i];}
    for(int i=1;i<=m;i++){
        if(i==1||c[i]!=c[i-1])a[++l]=c[i];
    }
    for(int i=1;i<=l;i++){
        oc[a[i]].push_back(i);
    }
    if(l>n+n){
        cout<<0;return 0;
    }
    for(int i=0;i<=l+1;i++){for(int j=0;j<=l+1;j++){dp[i][j]=1;}}
    for(int i=l;i>=1;i--){
        for(int j=i;j<=l;j++){
            int mi=a[i];
            for(int k=i;k<=j;k++){
                if(a[k]<mi)mi=a[k];
            }
            int fv=*oc[mi].begin(),ev=*(oc[mi].end()-1);
            if(fv<i||ev>j)dp[i][j]=0;
            else{
                long long mul=1;
                for(int i=1;i<oc[mi].size();i++){
                    mul=(mul*(dp[oc[mi][i-1]+1][oc[mi][i]-1]))%mdn;
                }
                long long sm0=0,sm1=0;
                for(int k=i;k<=fv;k++){sm0+=dp[k][fv-1]*dp[i][k-1];sm0%=mdn;}
                for(int k=j;k>=ev;k--){sm1+=dp[ev+1][k]*dp[k+1][j];sm1%=mdn;}
                cerr<<fv<<','<<ev<<endl;
                dp[i][j]=mul*sm0%mdn*sm1%mdn;
            }
            //cout<<i<<','<<j<<':'<<dp[i][j]<<endl;
        }
    }
    cout<<dp[1][l];
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define y0 y12
#define y1 y22
#define INF 987654321
#define PI 3.141592653589793238462643383279502884
#define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
#define fdn(i,a,b,c) for(int (i)=(a);(i)>=(b);(i)-=(c))
#define MEM0(a) memset((a),0,sizeof(a));
#define MEM_1(a) memset((a),-1,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define SYNC ios_base::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;
typedef pair<ld, ld> Pd;
typedef vector<int> Vi;
typedef vector<ll> Vll;
typedef vector<ld> Vd;
typedef vector<Pi> VPi;
typedef vector<Pll> VPll;
typedef vector<Pd> VPd;
typedef tuple<int, int, int> iii;
typedef tuple<int, int, int, int> iiii;
typedef tuple<ll, ll, ll> LLL;
typedef vector<iii> Viii;
typedef vector<LLL> VLLL;
typedef complex<double> base;
const int MOD = 998244353;
ll POW(ll a, ll b, ll MMM = MOD) { ll ret = 1; for (; b; b >>= 1, a = (a*a) % MMM)if (b & 1)ret = (ret*a) % MMM; return ret; }
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
ll lcm(ll a, ll b) { if (a == 0 || b == 0)return a + b; return a*(b / gcd(a, b)); }
int dx[] = { 0,1,0,-1,1,1,-1,-1 }, dy[] = { 1,0,-1,0,1,-1,1,-1 };
int ddx[] = { -1,-2,1,-2,2,-1,2,1 }, ddy[] = { -2,-1,-2,1,-1,2,1,2 };

int n,k;
Vi a,v[501];
Pi p[501];
ll d[1005][1005];
int mn[1005][1005];
inline int l(int x){return v[x][0];}
inline int r(int x){return v[x].back();}
ll go(int L,int R)
{
	if(L>=R)return 1;
	ll &ret=d[L][R];
	if(~ret)return ret;
	ret=0;
	int t=mn[L][R];
	if(p[t].X<L || p[t].Y>R)return ret;
	ll t1=0,t2=0;
	fup(i,L,l(t),1)t1=(t1+go(L,i-1)*go(i,p[t].X-1))%MOD;
	fup(i,r(t),R,1)t2=(t2+go(p[t].Y+1,i)*go(i+1,R))%MOD;
	ret=(t1*t2)%MOD;
	fup(i,1,(int)v[t].size()-1,1)
	{
		ret=(ret*go(v[t][i-1]+1,v[t][i]-1))%MOD;
	}
	return ret;
}
int main(){
	MEM_1(d);
	scanf("%d%d",&k,&n);
	fup(i,1,n,1)
	{
		int x;
		scanf("%d",&x);
		a.pb(x);
	}
	a.resize(unique(ALL(a))-a.begin());
	n=a.size();
	if(n>2*k)return !printf("0");
	fup(i,0,n-1,1)
	{
		mn[i][i]=a[i];
		v[a[i]].pb(i);
		fup(j,i+1,n-1,1)
		{
			mn[i][j]=min(mn[i][j-1],a[j]);
		}
	}
	fup(i,1,k,1)
	{
		int L=l(i),R=r(i);
		fup(j,L+1,R-1,1)if(a[j]<i)return !printf("0");
	}
	fup(i,0,n-1,1)p[a[i]].Y=i;
	fdn(i,n-1,0,1)p[a[i]].X=i;
	printf("%lld",go(0,n-1));
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define y0 y12
#define y1 y22
#define INF 987654321
#define PI 3.141592653589793238462643383279502884
#define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
#define fdn(i,a,b,c) for(int (i)=(a);(i)>=(b);(i)-=(c))
#define MEM0(a) memset((a),0,sizeof(a));
#define MEM_1(a) memset((a),-1,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define SYNC ios_base::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;
typedef pair<ld, ld> Pd;
typedef vector<int> Vi;
typedef vector<ll> Vll;
typedef vector<ld> Vd;
typedef vector<Pi> VPi;
typedef vector<Pll> VPll;
typedef vector<Pd> VPd;
typedef tuple<int, int, int> iii;
typedef tuple<int, int, int, int> iiii;
typedef tuple<ll, ll, ll> LLL;
typedef vector<iii> Viii;
typedef vector<LLL> VLLL;
typedef complex<double> base;
const int MOD = 998244353;
ll POW(ll a, ll b, ll MMM = MOD) { ll ret = 1; for (; b; b >>= 1, a = (a*a) % MMM)if (b & 1)ret = (ret*a) % MMM; return ret; }
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
ll lcm(ll a, ll b) { if (a == 0 || b == 0)return a + b; return a*(b / gcd(a, b)); }
int dx[] = { 0,1,0,-1,1,1,-1,-1 }, dy[] = { 1,0,-1,0,1,-1,1,-1 };
int ddx[] = { -1,-2,1,-2,2,-1,2,1 }, ddy[] = { -2,-1,-2,1,-1,2,1,2 };

int n,k;
Vi a,v[501];
Pi p[501];
ll d[1005][1005];
int mn[1005][1005];
inline int l(int x){return v[x][0];}
inline int r(int x){return v[x].back();}
ll go(int L,int R)
{
	if(L>=R)return 1;
	ll &ret=d[L][R];
	if(~ret)return ret;
	ret=0;
	int t=mn[L][R];
	if(p[t].X<L || p[t].Y>R)return ret;
	ll t1=0,t2=0;
	fup(i,L,l(t),1)t1=(t1+go(L,i-1)*go(i,p[t].X-1))%MOD;
	fup(i,r(t),R,1)t2=(t2+go(p[t].Y+1,i)*go(i+1,R))%MOD;
	ret=(t1*t2)%MOD;
	fup(i,1,(int)v[t].size()-1,1)
	{
		ret=(ret*go(v[t][i-1]+1,v[t][i]-1))%MOD;
	}
	return ret;
}
int main(){
	MEM_1(d);
	scanf("%d%d",&k,&n);
	fup(i,1,n,1)
	{
		int x;
		scanf("%d",&x);
		a.pb(x);
	}
	a.resize(unique(ALL(a))-a.begin());
	n=a.size();
	if(n>2*k)return !printf("0");
	fup(i,0,n-1,1)
	{
		mn[i][i]=a[i];
		v[a[i]].pb(i);
		fup(j,i+1,n-1,1)
		{
			mn[i][j]=min(mn[i][j-1],a[j]);
		}
	}
	fup(i,0,n-1,1)p[a[i]].Y=i;
	fdn(i,n-1,0,1)p[a[i]].X=i;
	printf("%lld",go(0,n-1));
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define y0 y12
#define y1 y22
#define INF 987654321
#define PI 3.141592653589793238462643383279502884
#define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
#define fdn(i,a,b,c) for(int (i)=(a);(i)>=(b);(i)-=(c))
#define MEM0(a) memset((a),0,sizeof(a));
#define MEM_1(a) memset((a),-1,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define SYNC ios_base::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;
typedef pair<ld, ld> Pd;
typedef vector<int> Vi;
typedef vector<ll> Vll;
typedef vector<ld> Vd;
typedef vector<Pi> VPi;
typedef vector<Pll> VPll;
typedef vector<Pd> VPd;
typedef tuple<int, int, int> iii;
typedef tuple<int, int, int, int> iiii;
typedef tuple<ll, ll, ll> LLL;
typedef vector<iii> Viii;
typedef vector<LLL> VLLL;
typedef complex<double> base;
const int MOD = 998244353;
ll POW(ll a, ll b, ll MMM = MOD) { ll ret = 1; for (; b; b >>= 1, a = (a*a) % MMM)if (b & 1)ret = (ret*a) % MMM; return ret; }
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
ll lcm(ll a, ll b) { if (a == 0 || b == 0)return a + b; return a*(b / gcd(a, b)); }
int dx[] = { 0,1,0,-1,1,1,-1,-1 }, dy[] = { 1,0,-1,0,1,-1,1,-1 };
int ddx[] = { -1,-2,1,-2,2,-1,2,1 }, ddy[] = { -2,-1,-2,1,-1,2,1,2 };

int n,k;
Vi a,v[501];
Pi p[501];
ll d[1005][1005];
int mn[1005][1005];
inline int l(int x){return v[x][0];}
inline int r(int x){return v[x].back();}
ll go(int L,int R)
{
	if(L>R)return 1;
	ll &ret=d[L][R];
	if(~ret)return ret;
	ret=0;
	int t=mn[L][R];
	if(p[t].X<L || p[t].Y>R)return ret;
	if(L==R)return ret=1;
	ll t1=0,t2=0;
	fup(i,L,l(t),1)t1=(t1+go(L,i-1)*go(i,p[t].X-1))%MOD;
	fup(i,r(t),R,1)t2=(t2+go(p[t].Y+1,i)*go(i+1,R))%MOD;
	ret=(t1*t2)%MOD;
	fup(i,1,(int)v[t].size()-1,1)
	{
		ret=(ret*go(v[t][i-1]+1,v[t][i]-1))%MOD;
	}
	return ret;
}
int main(){
	MEM_1(d);
	scanf("%d%d",&k,&n);
	fup(i,1,n,1)
	{
		int x;
		scanf("%d",&x);
		a.pb(x);
	}
	a.resize(unique(ALL(a))-a.begin());
	n=a.size();
	if(n>2*k)return !printf("0");
	fup(i,0,n-1,1)
	{
		mn[i][i]=a[i];
		v[a[i]].pb(i);
		fup(j,i+1,n-1,1)
		{
			mn[i][j]=min(mn[i][j-1],a[j]);
		}
	}
	fup(i,1,k,1)
	{
		int L=l(i),R=r(i);
		fup(j,L+1,R-1,1)if(a[j]<i)return !printf("0");
	}
	fup(i,0,n-1,1)p[a[i]].Y=i;
	fdn(i,n-1,0,1)p[a[i]].X=i;
	printf("%lld",go(0,n-1));
}


#pragma GCC optimize("O3")
#ifdef ONLINE_JUDGE
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif
#pragma GCC optimize("unroll-loops")
#pragma comment(linker, "/stack:200000000")
#include <bits/stdc++.h>
#include <deque>
#include <type_traits>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
template<typename KeyType=int,typename Mapped=__gnu_pbds::null_type,typename Cmp_Fn=std::less<KeyType>,typename Tag=__gnu_pbds::rb_tree_tag,template<typename Const_Node_Iterator,typename Node_Iterator,typename Cmp_Fn_,typename Allocator_>class Node_Update=__gnu_pbds::tree_order_statistics_node_update,typename Allocator=std::allocator<char>>using ordered_set_t=__gnu_pbds::tree<KeyType,Mapped,Cmp_Fn,Tag,Node_Update,Allocator>;const int GRANDOM=std::chrono::high_resolution_clock::now().time_since_epoch().count();struct ghash{int operator()(int x){return std::hash<int>{}(x^GRANDOM);}};template<typename KeyType>using hash_table_t=__gnu_pbds::gp_hash_table<KeyType,int,ghash>;namespace ____{template<class T>struct like_array:is_array<T>{};template<class T,size_t N>struct like_array<array<T,N>>:true_type{};template<class T>struct like_array<vector<T>>:true_type{};template<class T>bool is_like_array(const T&a){return like_array<T>::value;}template<class T>void _R(T&x){std::cin>>x;}inline void _R(int&x){scanf("%d",&x);}inline void _R(int64_t&x){scanf("%" SCNd64,&x);}inline void _R(double&x){scanf("%lf",&x);}inline void _R(char&x){scanf(" %c",&x);}inline void _R(char*x){scanf("%s",x);}template<typename T>inline void _R(vector<T>&v,size_t ie){for(int i=0;i<ie;i++)_R(v[i]);}template<typename T>inline void _R(vector<T>&v){_R(v,v.size());}inline void R(){}template<class T,class... U>inline void R(T&head,U&... tail){_R(head);R(tail...);}template<class T>void _W(const T&x){cout<<x;}template<typename T>inline void _W(vector<T>&v,size_t ie){for(int i=0;i<ie;i++){if(i>0)_W(' ');_W(v[i]);}_W('\n');}template<typename T>inline void _W(vector<T>&v){_W(v,v.size());}template<class T>inline void _W(const vector<T>&x){for(auto i=x.begin();i!=x.end();_W(*i++))if(i!=x.cbegin())putchar(' ');}inline void W(){}template<class T,class... U>inline void W(const T&head,const U&... tail){_W(head);if(sizeof...(tail))putchar(' '),W(tail...);}template<class T,class... U>inline void WL(const T&head,const U&... tail){_W(head);putchar(sizeof...(tail)? ' ':'\n');W(tail...);}template<class T>void _RE(T&x){cin>>x;}template<class Arg,class... Args>void _RE(Arg&first,Args&... rest);void _RE(double&x){string t;_RE(t);x=stod(t);}void _RE(long double&x){string t;_RE(t);x=stold(t);}template<class T>void _RE(complex<T>&x);template<class T1,class T2>void _RE(pair<T1,T2>&p);template<class T>void _RE(vector<T>&a);template<class T,size_t SZ>void _RE(array<T,SZ>&a);template<class Arg,class... Args>void _RE(Arg&first,Args&... rest){_RE(first);_RE(rest...);}template<class T>void _RE(complex<T>&x){T a,b;_RE(a,b);x=cd(a,b);}template<class T1,class T2>void _RE(pair<T1,T2>&p){_RE(p.f,p.s);}template<class T>void _RE(vector<T>&a){for(int i=0,ie=sz(a);i<ie;i++)_RE(a[i]);}template<class T,size_t SZ>void _RE(array<T,SZ>&a){for(int i=0;i<SZ;i++)_RE(a[i]);}};
#define prec setprecision
namespace ____{typedef long long ll;typedef unsigned long long llu;template<typename T>T gcd(T m,T n){while(n){T t=m%n;m=n;n=t;};return m;}template<typename T>T exgcd(T a,T b,T&sa,T&ta){T q,r,sb=0,tb=1,sc,tc;sa=1,ta=0;if(b)do q=a/b,r=a-q*b,a=b,b=r,sc=sa-q*sb,sa=sb,sb=sc,tc=ta-q*tb,ta=tb,tb=tc;while(b);return a;}template<typename T>T mul_inv(T a,T b){T t1=a,t2=b,t3;T v1=1,v2=0,v3;T x;while(t2!=1)x=t1/t2,t3=t1-x*t2,v3=v1-x*v2,t1=t2,t2=t3,v1=v2,v2=v3;return(v2+b)%b;}template<typename T>T powmod(T a,T b,T MOD){if(b<0)return 0;T rv=1;while(b)(b%2)&&(rv=(rv*a)%MOD),a=a*a%MOD,b/=2;return rv;}template<typename T>inline T isqrt(T k){T r=sqrt((double)k)+1;while(r*r>k)r--;return r;}template<typename T>inline T icbrt(T k){T r=cbrt((double)k)+1;while(r*r*r>k)r--;return r;}template<typename T>bool mul_overflow(T&r,T a,T b){return __builtin_mul_overflow(a,b,&r);}template<ll n>struct BitSize{enum{Size=BitSize<n/2>::Size+1};};template<>struct BitSize<0>{enum{Size=1};};template<>struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define TREESIZE(n) ((1<<(BitSize<n>::Size + 1))+7)
#define BITMAX(n) (BitSize<n>::Size - 1)
#define DEBUG !defined(ONLINE_JUDGE)
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define RALL(x) (x).rbegin(),(x).rend()
template<typename TH>void _dbg(const char*sdbg,TH h){cerr<<sdbg<<"="<<h<<"\n";}template<typename TH,typename... TA>void _dbg(const char*sdbg,TH h,TA... t){while(*sdbg!=',')cerr<<*sdbg++;cerr<<"="<<h<<",";_dbg(sdbg+1,t...);}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; for(auto itt: x) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
}namespace ____{template<typename T>int min_rotation(vector<T>s){int a=0,N=s.size();for(int b=0;b<N;b++)for(int i=0;i<N;i++){if(a+i==b||s[(a+i)%N]<s[(b+i)%N]){b+=max(0,i-1);break;}if(s[(a+i)%N]>s[(b+i)%N]){a=b;break;}}return a;};template<typename T>class StackGuard{private:T x;public:StackGuard(T x):x(x){}~StackGuard(){x();}};}namespace ____{template<typename T>constexpr T vh__sqrt_helper(T x,T lo,T hi){if(lo==hi)return lo;const T mid=(lo+hi+1)/2;if(x/mid<mid)return vh__sqrt_helper<T>(x,lo,mid-1);else return vh__sqrt_helper(x,mid,hi);}template<typename T>constexpr T ct_sqrt(T x){return vh__sqrt_helper<T>(x,0,x/2+1);}template<const ll MOD,typename T=ll>class FiniteField{typedef FiniteField<MOD,T>self;enum{MOD_SQRT=ct_sqrt(MOD),};public:ll val;FiniteField(ll x=0):val(normalize(x)){}inline T normalize(T x){x%=MOD;return normalize2(x);}inline T normalize2(T x){if(x<0)x+=MOD;if(x>=MOD)x-=MOD;return x;}self&operator=(const self&o){val=o.val;return*this;}template<typename NT>self&operator=(const NT o){val=normalize(o);return*this;}self&operator+=(const self&o){val=normalize2(val+o.val);return*this;}template<typename NT>self&operator+=(const NT o){val=normalize(val+(o));return*this;}self&operator-=(const self&o){val=normalize2(val-o.val);return*this;}template<typename NT>self&operator-=(const NT o){val=normalize(val-(o));return*this;}self&operator*=(const self&o){return*this*=o.val;}template<typename NT>self&operator*=(const NT o){val=normalize(val*o);return*this;}self operator+(const self&o){return self(normalize2(val+o.val));}template<typename NT>self operator+(const NT o){return self(normalize2(val+(o)));}self operator-(const self&o){return self(normalize2(val-o.val));}template<typename NT>self operator-(const NT o){return self(normalize2(val-(o)));}self operator-(){return self(normalize(-val));}self operator*(const self&o){return self(normalize(val*o.val));}template<typename NT>self operator*(const NT o){return self(normalize(val*(o)));}self operator^(ll b){if(b<0)return 0;self a=*this;self rv=1;while(b)(b%2)&&(rv*=a),a*=a,b/=2;return rv;}operator T()const{return val;}template<typename NT,typename NT2>self log(NT base,NT2 base_inv){static const ll magic=MOD_SQRT+3;base=normalize(base);map<ll,ll>lg;ll x=1;for(int i=0;i<magic;i++)lg[x]=i,x=x*base%MOD;ll step=self(base_inv)^magic;x=val;for(int i=0;i<magic;i++){auto it=lg.find(x);if(it!=lg.end()){return self(magic*i+it->second);}x=(x*step)%MOD;}return-1;}};};namespace ____{};
namespace ____{
  const ll MOD=998244353;
  const int maxn=505;
  const int maxm=maxn*10;
  int n,m;
  int c[maxm];
  int d[maxm];
  typedef FiniteField<MOD,ll>number_t;
  ll dp[maxm][maxm];
  number_t solve(int a,int b){
    if(a>=b)return 1;
    ll&_r=dp[a][b];
    if(_r>=0)return _r;
    vector<int>vmi;
    int miv=c[a];
    vmi.push_back(a);
    for(int i=a;i<=b;i++)
      if(c[i]<miv)miv=c[i],vmi.clear(),vmi.push_back(i);
      else if(c[i]==miv)vmi.push_back(i);
    map<int,set<int>>mz;
    int lx=a-1;
    for(int i=a;i<=b;i++){
      if(c[i]>miv)mz[c[i]].insert(lx);
      else lx=i;
    }
    for(auto&[p,q]:mz){
      if(q.size()>1)return _r=0;
    }
    number_t rm=1;
    for(int i=1,ie=vmi.size();i<ie;i++)rm*=solve(vmi[i-1]+1,vmi[i]-1);
    int mifr=*vmi.begin();
    int mito=*vmi.rbegin();
    number_t rl=solve(a,mifr-1),rr=solve(mito+1,b);
    for(int i=a;i<mifr;i++)rl+=solve(a,i)*solve(i+1,mifr-1);
    for(int i=mito;i<b;i++)rr+=solve(mito+1,i)*solve(i+1,b);
    return _r=rm*rl*rr;
  }
  int main(){
    srand(GRANDOM);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
      cin>>c[i];
    }
    int m2=0;
    for(int i=1;i<=m;){
      c[++m2]=c[i];
      int&dd=d[m2];
      dd=1;
      for(int cc=c[i++];i<=m&&c[i]==cc;i++)dd++;
    }
    memset(dp,-1,sizeof(dp));
    cout<<solve(1,m2)<<endl;
    return 0;
  }
};
int main(int argc,char*argv[]){
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  return ____::main();
}


#pragma GCC optimize("O3")
#ifdef ONLINE_JUDGE
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif
#pragma GCC optimize("unroll-loops")
#pragma comment(linker, "/stack:200000000")
#include <bits/stdc++.h>
#include <deque>
#include <type_traits>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
template<typename KeyType=int,typename Mapped=__gnu_pbds::null_type,typename Cmp_Fn=std::less<KeyType>,typename Tag=__gnu_pbds::rb_tree_tag,template<typename Const_Node_Iterator,typename Node_Iterator,typename Cmp_Fn_,typename Allocator_>class Node_Update=__gnu_pbds::tree_order_statistics_node_update,typename Allocator=std::allocator<char>>using ordered_set_t=__gnu_pbds::tree<KeyType,Mapped,Cmp_Fn,Tag,Node_Update,Allocator>;const int GRANDOM=std::chrono::high_resolution_clock::now().time_since_epoch().count();struct ghash{int operator()(int x){return std::hash<int>{}(x^GRANDOM);}};template<typename KeyType>using hash_table_t=__gnu_pbds::gp_hash_table<KeyType,int,ghash>;namespace ____{template<class T>struct like_array:is_array<T>{};template<class T,size_t N>struct like_array<array<T,N>>:true_type{};template<class T>struct like_array<vector<T>>:true_type{};template<class T>bool is_like_array(const T&a){return like_array<T>::value;}template<class T>void _R(T&x){std::cin>>x;}inline void _R(int&x){scanf("%d",&x);}inline void _R(int64_t&x){scanf("%" SCNd64,&x);}inline void _R(double&x){scanf("%lf",&x);}inline void _R(char&x){scanf(" %c",&x);}inline void _R(char*x){scanf("%s",x);}template<typename T>inline void _R(vector<T>&v,size_t ie){for(int i=0;i<ie;i++)_R(v[i]);}template<typename T>inline void _R(vector<T>&v){_R(v,v.size());}inline void R(){}template<class T,class... U>inline void R(T&head,U&... tail){_R(head);R(tail...);}template<class T>void _W(const T&x){cout<<x;}template<typename T>inline void _W(vector<T>&v,size_t ie){for(int i=0;i<ie;i++){if(i>0)_W(' ');_W(v[i]);}_W('\n');}template<typename T>inline void _W(vector<T>&v){_W(v,v.size());}template<class T>inline void _W(const vector<T>&x){for(auto i=x.begin();i!=x.end();_W(*i++))if(i!=x.cbegin())putchar(' ');}inline void W(){}template<class T,class... U>inline void W(const T&head,const U&... tail){_W(head);if(sizeof...(tail))putchar(' '),W(tail...);}template<class T,class... U>inline void WL(const T&head,const U&... tail){_W(head);putchar(sizeof...(tail)? ' ':'\n');W(tail...);}template<class T>void _RE(T&x){cin>>x;}template<class Arg,class... Args>void _RE(Arg&first,Args&... rest);void _RE(double&x){string t;_RE(t);x=stod(t);}void _RE(long double&x){string t;_RE(t);x=stold(t);}template<class T>void _RE(complex<T>&x);template<class T1,class T2>void _RE(pair<T1,T2>&p);template<class T>void _RE(vector<T>&a);template<class T,size_t SZ>void _RE(array<T,SZ>&a);template<class Arg,class... Args>void _RE(Arg&first,Args&... rest){_RE(first);_RE(rest...);}template<class T>void _RE(complex<T>&x){T a,b;_RE(a,b);x=cd(a,b);}template<class T1,class T2>void _RE(pair<T1,T2>&p){_RE(p.f,p.s);}template<class T>void _RE(vector<T>&a){for(int i=0,ie=sz(a);i<ie;i++)_RE(a[i]);}template<class T,size_t SZ>void _RE(array<T,SZ>&a){for(int i=0;i<SZ;i++)_RE(a[i]);}};
#define prec setprecision
namespace ____{typedef long long ll;typedef unsigned long long llu;template<typename T>T gcd(T m,T n){while(n){T t=m%n;m=n;n=t;};return m;}template<typename T>T exgcd(T a,T b,T&sa,T&ta){T q,r,sb=0,tb=1,sc,tc;sa=1,ta=0;if(b)do q=a/b,r=a-q*b,a=b,b=r,sc=sa-q*sb,sa=sb,sb=sc,tc=ta-q*tb,ta=tb,tb=tc;while(b);return a;}template<typename T>T mul_inv(T a,T b){T t1=a,t2=b,t3;T v1=1,v2=0,v3;T x;while(t2!=1)x=t1/t2,t3=t1-x*t2,v3=v1-x*v2,t1=t2,t2=t3,v1=v2,v2=v3;return(v2+b)%b;}template<typename T>T powmod(T a,T b,T MOD){if(b<0)return 0;T rv=1;while(b)(b%2)&&(rv=(rv*a)%MOD),a=a*a%MOD,b/=2;return rv;}template<typename T>inline T isqrt(T k){T r=sqrt((double)k)+1;while(r*r>k)r--;return r;}template<typename T>inline T icbrt(T k){T r=cbrt((double)k)+1;while(r*r*r>k)r--;return r;}template<typename T>bool mul_overflow(T&r,T a,T b){return __builtin_mul_overflow(a,b,&r);}template<ll n>struct BitSize{enum{Size=BitSize<n/2>::Size+1};};template<>struct BitSize<0>{enum{Size=1};};template<>struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define TREESIZE(n) ((1<<(BitSize<n>::Size + 1))+7)
#define BITMAX(n) (BitSize<n>::Size - 1)
#define DEBUG !defined(ONLINE_JUDGE)
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define RALL(x) (x).rbegin(),(x).rend()
template<typename TH>void _dbg(const char*sdbg,TH h){cerr<<sdbg<<"="<<h<<"\n";}template<typename TH,typename... TA>void _dbg(const char*sdbg,TH h,TA... t){while(*sdbg!=',')cerr<<*sdbg++;cerr<<"="<<h<<",";_dbg(sdbg+1,t...);}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; for(auto itt: x) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
}namespace ____{template<typename T>int min_rotation(vector<T>s){int a=0,N=s.size();for(int b=0;b<N;b++)for(int i=0;i<N;i++){if(a+i==b||s[(a+i)%N]<s[(b+i)%N]){b+=max(0,i-1);break;}if(s[(a+i)%N]>s[(b+i)%N]){a=b;break;}}return a;};template<typename T>class StackGuard{private:T x;public:StackGuard(T x):x(x){}~StackGuard(){x();}};}namespace ____{template<typename T>constexpr T vh__sqrt_helper(T x,T lo,T hi){if(lo==hi)return lo;const T mid=(lo+hi+1)/2;if(x/mid<mid)return vh__sqrt_helper<T>(x,lo,mid-1);else return vh__sqrt_helper(x,mid,hi);}template<typename T>constexpr T ct_sqrt(T x){return vh__sqrt_helper<T>(x,0,x/2+1);}template<const ll MOD,typename T=ll>class FiniteField{typedef FiniteField<MOD,T>self;enum{MOD_SQRT=ct_sqrt(MOD),};public:ll val;FiniteField(ll x=0):val(normalize(x)){}inline T normalize(T x){x%=MOD;return normalize2(x);}inline T normalize2(T x){if(x<0)x+=MOD;if(x>=MOD)x-=MOD;return x;}self&operator=(const self&o){val=o.val;return*this;}template<typename NT>self&operator=(const NT o){val=normalize(o);return*this;}self&operator+=(const self&o){val=normalize2(val+o.val);return*this;}template<typename NT>self&operator+=(const NT o){val=normalize(val+(o));return*this;}self&operator-=(const self&o){val=normalize2(val-o.val);return*this;}template<typename NT>self&operator-=(const NT o){val=normalize(val-(o));return*this;}self&operator*=(const self&o){return*this*=o.val;}template<typename NT>self&operator*=(const NT o){val=normalize(val*o);return*this;}self operator+(const self&o){return self(normalize2(val+o.val));}template<typename NT>self operator+(const NT o){return self(normalize2(val+(o)));}self operator-(const self&o){return self(normalize2(val-o.val));}template<typename NT>self operator-(const NT o){return self(normalize2(val-(o)));}self operator-(){return self(normalize(-val));}self operator*(const self&o){return self(normalize(val*o.val));}template<typename NT>self operator*(const NT o){return self(normalize(val*(o)));}self operator^(ll b){if(b<0)return 0;self a=*this;self rv=1;while(b)(b%2)&&(rv*=a),a*=a,b/=2;return rv;}operator T()const{return val;}template<typename NT,typename NT2>self log(NT base,NT2 base_inv){static const ll magic=MOD_SQRT+3;base=normalize(base);map<ll,ll>lg;ll x=1;for(int i=0;i<magic;i++)lg[x]=i,x=x*base%MOD;ll step=self(base_inv)^magic;x=val;for(int i=0;i<magic;i++){auto it=lg.find(x);if(it!=lg.end()){return self(magic*i+it->second);}x=(x*step)%MOD;}return-1;}};};namespace ____{};
namespace ____{
  const ll MOD=998244353;
  const int maxn=505;
  const int maxm=maxn*4;
  int n,m;
  int c[maxm];
  typedef FiniteField<MOD,ll>number_t;
  ll dp[maxm][maxm];
  number_t solve(int a,int b){
    if(a>=b)return 1;
    ll&_r=dp[a][b];
    if(_r>=0)return _r;
    vector<int>vmi;
    int miv=c[a];
    for(int i=a;i<=b;i++)
      if(c[i]<miv)miv=c[i];
    static int mz[maxm];
    memset(mz,-1,sizeof(mz));
    int lx=a-1;
    for(int i=a;i<=b;i++){
      if(c[i]>miv){
        if(mz[c[i]]>=0&&mz[c[i]]!=lx)return _r=0;
        mz[c[i]]=lx;
      }else lx=i,vmi.push_back(i);
    }
    number_t rm=1;
    for(int i=1,ie=vmi.size();i<ie;i++)rm*=solve(vmi[i-1]+1,vmi[i]-1);
    int mifr=*vmi.begin();
    int mito=*vmi.rbegin();
    number_t rl=solve(a,mifr-1),rr=solve(mito+1,b);
    {
      int ml[maxm],mr[maxm],mx[maxm];
      memset(ml,0,sizeof(ml));
      memset(mr,0,sizeof(mr));
      memset(mx,0,sizeof(mx));
      int n2=0;
      for(int i=a;i<=b;i++)if(c[i]>miv)mr[c[i]]++,mx[c[i]]=1;
      for(int i=a,ie=mifr;i<ie;i++){
        if(!ml[c[i]]++)if(++mx[c[i]]==2)n2++;
        if(!--mr[c[i]])if(--mx[c[i]]==1)n2--;
        if(!n2)rl+=solve(a,i)*solve(i+1,mifr-1);
      }
    }
    {
      int ml[maxm],mr[maxm],mx[maxm];
      memset(ml,0,sizeof(ml));
      memset(mr,0,sizeof(mr));
      memset(mx,0,sizeof(mx));
      int n2=0;
      for(int i=a;i<=b;i++)if(c[i]>miv)ml[c[i]]++,mx[c[i]]=1;
      for(int i=b,ie=mito;i>mito;i--){
        if(!mr[c[i]]++)if(++mx[c[i]]==2)n2++;
        if(!--ml[c[i]])if(--mx[c[i]]==1)n2--;
        if(!n2)rr+=solve(mito+1,i-1)*solve(i,b);
      }
    }
    return _r=rm*rl*rr;
  }
  int mi[maxn],ma[maxn];
  int main(){
    srand(GRANDOM);
    cin>>n>>m;
    int x,xl=-1;
    int m2=0;
    for(int i=1;i<=n;i++)mi[i]=m+1,ma[i]=0;
    for(int i=1;i<=m;i++){
      cin>>x;
      if(x!=xl){
        c[++m2]=x;
        mi[x]=min(mi[x],m2);
        ma[x]=max(ma[x],m2);
      }
      xl=x;
    }
    for(int i=1;i<=n;i++){
      for(int j=i+1;j<=n;j++){
        if(mi[i]>=mi[j]&&mi[i]<=ma[j]){
          cout<<0<<endl;
          return 0;
        }
      }
    }
    memset(dp,-1,sizeof(dp));
    cout<<solve(1,m2)<<endl;
    return 0;
  }
};
int main(int argc,char*argv[]){
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  return ____::main();
}