#include <iostream>
#include <istream>
#include <ratio>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
// 算法不复杂,但是测试过程很长,一直有不通过的
// 主要的原因是,自己写的求交集,并集的函数有很多小问题
// 一定要测试自定义函数,确保正确,不然这种题查错非常难受
struct Line {
int s;
int e;
};
istream& operator>> (istream& in, Line& v) {
return in >> v.s >> v.e;
}
// 交集
Line* Intersection(const Line& l, const Line& r) {
auto s = max(l.s, r.s);
auto e = min(l.e, r.e);
if(s > e) {
return nullptr;
} else {
return new Line{s,e};
}
}
unordered_map<int,unordered_map<int,Line*>> gInter;
Line* GetInter(int i, int j) {
if(i > j) {
swap(i,j);
}
auto it = gInter.find(i);
if(it == gInter.end()) {
return nullptr;;
} else {
auto& dict = it->second;
auto sit = dict.find(j);
if(sit != dict.end()) {
return sit->second;
} else {
return nullptr;
}
}
}
void InitInter(const vector<Line>& lines) {
for(auto i = 0; i < lines.size(); i++) {
auto& l = lines[i];
for(auto j = i + 1; j < lines.size(); j++) {
auto inter = Intersection(l, lines[j]);
if(inter) {
gInter[i][j] = inter;
}
}
}
}
// 并集
bool Union(Line& l, const Line* r) {
if(l.e + 1 < r->s) {
return false;
}
if(r->e > l.e) {
l.e = r->e;
}
return true;
}
// 交集是否覆盖1~n
bool IsUnionConver(vector<const Line*>& lines, int n) {
if(lines.size() == 0) {
return false;
}
sort(lines.begin(), lines.end(), [](const Line*& l, const Line*& r) {
return l->s < r->s;
});
Line all = *lines[0];
if(all.s != 1) {
return false;
}
if(all.e == n) {
return true;
}
for(auto i = 1; i < lines.size(); i++) {
auto l = lines[i];
if(!Union(all, l)) {
return false;
}
if(all.e == n) {
return true;
}
}
return false;
}
bool Check(vector<int>& pick, int n) {
if(pick.size() < 2) {
return false;
}
vector<const Line*> unions;
for(auto i = 0; i < pick.size(); i++) {
for(auto j = i+1; j < pick.size(); j++) {
auto inter = GetInter(pick[i],pick[j]);
if(inter) {
unions.push_back(inter);
}
}
}
return IsUnionConver(unions, n);
}
int64_t valid = 0;
void Dfs(int cnt, int i, vector<int>& pick, int n) {
if(i == cnt) {
if(Check(pick, n)) {
valid++;
const int p = 998244353;
valid %= p;
}
return;
}
pick.push_back(i);
Dfs(cnt, i+1, pick, n);
pick.pop_back();
Dfs(cnt, i+1, pick, n);
}
int main() {
int n, m;
cin >>n >> m;
vector<Line> l(m);
for(auto& v : l) {
cin >> v;
}
InitInter(l);
vector<int> pick;
Dfs(m, 0, pick, n);
cout << valid << endl;
}
// 64 位输出请用 printf("%lld")