#include <bits/stdc++.h>
using namespace std;
const int md = 1e9 + 7;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
vector<pair<int, int>> leqs, geqs;
vector<vector<int>> lints(n), gints(n);
for (int i = 0, a, b; i < m; ++i) {
cin >> a >> b;
--a, --b;
if (a <= b) {
leqs.push_back({a, b});
lints[a].push_back(b - 1);
} else {
geqs.push_back({b, a});
gints[b].push_back(a - 1);
}
}
sort(leqs.begin(), leqs.end());
sort(geqs.begin(), geqs.end());
vector<int> firstl(n), firstg(n); // first interval such that l > i
auto populate = [&](vector<int> &first, vector<pair<int, int>> ints) {
for (int i = n - 1; i >= 0; --i) {
while (!ints.empty() && ints.back().first > i) {
ints.pop_back();
}
first[i] = ints.size();
}
};
populate(firstl, leqs);
populate(firstg, geqs);
auto pow = [&](int64_t a, int b) {
int64_t ans = 1, cur = a;
while (b) {
if (b & 1) {
ans = (ans * cur) % md;
}
cur = (cur * cur) % md;
b >>= 1;
}
return ans;
};
// dp[i][ch] = answer if we're at i, constraints behind i are all satisfied, and s[i] = ch
vector dp(n, vector<int64_t>(26));
array<set<int>, 26> unowned, lt, gt, eq; // to maintain
array<int64_t, 26> unowned_sum{}, lt_sum{}, gt_sum{};
auto get_unowned = [&](int j) {
int64_t ans = 0;
for (int nch = 0; nch < 26; ++nch) {
ans = (ans + dp[j + 1][nch]) % md;
}
return ans;
};
auto insert_unowned = [&](int ch, int i) {
unowned_sum[ch] += get_unowned(i);
unowned[ch].insert(i);
};
auto erase_unowned = [&](int ch, int i) {
unowned_sum[ch] -= get_unowned(i);
unowned[ch].erase(i);
};
auto get_lt_gt = [&](int ch, int j, int force_leq) {
int64_t ans = 0;
int constrl = firstl[j] == leqs.size() ? n : leqs[firstl[j]].first;
int constrg = firstg[j] == geqs.size() ? n : geqs[firstg[j]].first;
int constr = min(constrl, constrg);
int del = constr - j - 2;
// travel to the next point where we have a constraint
if (del == -1) {
for (int nch = force_leq ? 0 : ch; nch <= (force_leq ? ch : 25); ++nch) {
if (ch != nch) {
ans = (ans + dp[constr][nch]) % md;
}
}
} else {
int mult = force_leq ? (ch * pow(26, del)) % md : ((25 - ch) * pow(26, del)) % md;
if (constr == n) {
ans = (ans + mult) % md;
} else {
for (int nch = 0; nch < 26; ++nch) {
ans = (ans + (mult * dp[constr][nch]) % md) % md;
}
}
}
return ans;
};
auto insert_lt = [&](int ch, int j) {
lt_sum[ch] += get_lt_gt(ch, j, 1);
lt[ch].insert(j);
};
auto erase_lt = [&](int ch, int j) {
lt_sum[ch] -= get_lt_gt(ch, j, 1);
lt[ch].erase(j);
};
auto insert_gt = [&](int ch, int j) {
gt_sum[ch] += get_lt_gt(ch, j, 0);
gt[ch].insert(j);
};
auto erase_gt = [&](int ch, int j) {
gt_sum[ch] -= get_lt_gt(ch, j, 0);
gt[ch].erase(j);
};
auto add_interval = [&](int ch, int l, int r, bool is_l) {
auto next1 = [&](int i) { return unowned[ch].lower_bound(i); };
for (auto it = next1(l); it != unowned[ch].end() && *it <= r; it = next1(l)) {
if (is_l) {
insert_lt(ch, *it);
} else {
insert_gt(ch, *it);
}
erase_unowned(ch, *it);
}
auto &st = (is_l ? gt : lt)[ch];
auto next2 = [&](int i) { return st.lower_bound(i); };
for (auto it = next2(l); it != st.end() && *it <= r; it = next2(l)) {
eq[ch].insert(*it);
if (is_l) {
erase_gt(ch, *it);
} else {
erase_lt(ch, *it);
}
}
};
for (int i = n - 1; i >= 0; --i) {
for (int ch = 0; ch < 26; ++ch) {
dp[i][ch] = 1;
if (i == n - 1) {
continue;
}
insert_unowned(ch, i);
for (auto &r : lints[i]) {
add_interval(ch, i, r, 1);
}
for (auto &r : gints[i]) {
add_interval(ch, i, r, 0);
}
dp[i][ch] = (dp[i][ch] + unowned_sum[ch]) % md;
dp[i][ch] = (dp[i][ch] + lt_sum[ch]) % md;
dp[i][ch] = (dp[i][ch] + gt_sum[ch]) % md;
}
}
int64_t ans = 0;
for (int ch = 0; ch < 26; ++ch) {
ans = (ans + dp[0][ch]) % md;
}
cout << ans << '\n';
}