#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
int f[5001];
int inv[5001], fact[5001], invfact[5001];
int C(int a, int b) {
	return 1ll*fact[a]*invfact[b]%mod*invfact[a-b]%mod;
}
int main() {
	int n, m;
	cin >> n >> m;
	inv[1] = 1;
	for (int i = 2; i <= n; i++) inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;
	fact[0] = invfact[0] = 1;
	for (int i = 1; i <= n; i++) fact[i] = 1ll*fact[i-1]*i%mod;
	for (int i = 1; i <= n; i++) invfact[i] = 1ll*invfact[i-1]*inv[i]%mod;
	f[0] = 1;
	if (m & 1) {
		cout << 0 << endl;
		return 0;
	}
	while (m) {
		for (int i = m; i >= 0; i--)
			for (int j = 2; j <= n && j <= i; j += 2)
				f[i] = (f[i] + 1ll*C(n,j)*f[i-j])%mod;
		for (int i = 0; i * 2 <= m; i++) f[i] = f[i*2+(m&2)];
		m >>= 2, m <<= 1;
	}
	cout << f[0] << endl;
}
#include <bits/stdc++.h>
#define _overload3(_1,_2,_3,name,...)name
#define _rep(i,n)repi(i,0,n)
#define repi(i,a,b)for(int i=int(a),i##_len=(b);i<i##_len;++i)
#define MSVC_UNKO(x)x
#define rep(...)MSVC_UNKO(_overload3(__VA_ARGS__,repi,_rep,_rep)(__VA_ARGS__))
#define all(c)c.begin(),c.end()
#define write(x)cout<<(x)<<'\n'
using namespace std; using ll = long long; template<class T>using vv = vector<vector<T>>;
template<class T>auto vvec(int n, int m, T v) { return vv<T>(n, vector<T>(m, v)); }
constexpr int INF = 1 << 29, MOD = int(1e9) + 7; constexpr ll LINF = 1LL << 60;
struct aaa { aaa() { cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(10); }; }aaaa;

int main() {
    int N, M;
    cin >> N >> M;
    vector<pair<int, int>> XY(M);
    rep(i, M) cin >> XY[i].first >> XY[i].second;
    XY.emplace_back(0, N);

    sort(all(XY));

    map<int, vector<pair<int, int>>> mp;
    rep(i, M + 1) {
        mp[XY[i].second].emplace_back(XY[i].first, i);
    }

    vv<int> graph(M + 1);
    rep(i, M + 1) {
        auto [x, y] = XY[i];
        int z;
        if (mp[y].back().second == i) {
            z = 2 * N + 1;
        }
        else {
            auto ub = lower_bound(all(mp[y]), make_pair(x + 1, 0));
            z = ub->first;
        }

        if (mp.find(y - 1) != mp.end()) {
            auto lb = lower_bound(all(mp[y - 1]), make_pair(x + 1, 0));
            auto ub = lower_bound(all(mp[y - 1]), make_pair(z + 1, 0));
            for (auto it = lb; it != ub; ++it) {
                graph[i].push_back(it->second);
            }
        }
        if (mp.find(y + 1) != mp.end()) {
            auto lb = lower_bound(all(mp[y + 1]), make_pair(x + 1, 0));
            auto ub = lower_bound(all(mp[y + 1]), make_pair(z + 1, 0));
            for (auto it = lb; it != ub; ++it) {
                graph[i].push_back(it->second);
            }
        }
    }

    vector<bool> can_visit(M + 1);
    can_visit[0] = true;
    auto dfs = [&](auto self, int u) -> void {
        for (int v : graph[u]) {
            if (can_visit[v]) continue;
            can_visit[v] = true;
            self(self, v);
        }
    };
    dfs(dfs, 0);

    set<int> ans;
    rep(i, M + 1) {
        auto [x, y] = XY[i];
        if (can_visit[i] && i == mp[y].back().second) {
            ans.insert(y);
        }
    }
    write((int)ans.size());
}