#include <bits/stdc++.h>
using namespace std;
template <class T>
ostream& operator<<(ostream& os, vector<T> V) {
  os << "[ ";
  for (auto v : V) os << v << " ";
  return os << "]";
}
template <class T>
ostream& operator<<(ostream& os, set<T> S) {
  os << "{ ";
  for (auto s : S) os << s << " ";
  return os << "}";
}
template <class L, class R>
ostream& operator<<(ostream& os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R>
ostream& operator<<(ostream& os, map<L, R> M) {
  os << "{ ";
  for (auto m : M) os << "(" << m.first << ":" << m.second << ")";
  return os << "}";
}
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cout.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
const int N = 3e5 + 100;
const int MX = 22;
const int mod = 998244353;
inline int add(int a, int b) {
  a += b;
  if (a >= mod) a -= mod;
  return a;
}
inline int mul(int a, int b) { return a * 1ll * b % mod; }
inline int power(int a, int b) {
  int res = 1;
  while (b) {
    if (b & 1) res = mul(res, a);
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}
int n, m;
int L[N], R[N];
set<int> G[N];
int comp[N];
vector<int> ele[N];
int pre[N];
vector<pair<int, int> > info[MX][MX];
void dfs(int s, int c) {
  comp[s] = c;
  ele[c].push_back(s);
  for (auto it : G[s]) {
    if (comp[it] == 0) {
      dfs(it, c);
    }
  }
}
void get_inter(pair<int, int>& a, pair<int, int> p) {
  if (a.first == -1) return;
  if (a.first > p.first) {
    swap(a, p);
  }
  if (a.second < p.first) {
    a = make_pair(-1, -1);
    return;
  } else if (a.second > p.second) {
    a = p;
    return;
  } else {
    a.first = p.first;
    return;
  }
}
int delta_prime;
void brute(int comp_no) {
  ++delta_prime;
  int no = ele[comp_no].size();
  info[delta_prime][0].push_back(make_pair(1, n));
  for (int i = 1; i < (1 << no); ++i) {
    set<int> st;
    pair<int, int> p = make_pair(1, n);
    bool ok = 1;
    for (int j = 0; j < no; ++j) {
      if (i & (1 << j)) {
        for (auto it : G[ele[comp_no][j]]) {
          if (st.find(it) != st.end()) {
            ok = 0;
            break;
          }
        }
        if (!ok) break;
        st.insert(ele[comp_no][j]);
        get_inter(p, make_pair(L[ele[comp_no][j]], R[ele[comp_no][j]]));
      }
    }
    if (!ok) continue;
    info[delta_prime][st.size()].push_back(p);
  }
  for (int i = 0; i < MX; ++i) {
    if (info[delta_prime][i].size() == 0) break;
    sort((info[delta_prime][i]).begin(), (info[delta_prime][i]).end());
  }
}
priority_queue<int, vector<int>, greater<int> > Q[MX][MX];
int cntr[MX][MX];
int ptr[MX][MX];
int fac[N], inv[N];
void transition(int cord) {
  for (int i = 1; i <= delta_prime; ++i) {
    for (int j = 0; j < MX; ++j) {
      while (Q[i][j].size() && Q[i][j].top() < cord) {
        cntr[i][j]--;
        Q[i][j].pop();
      }
      while (ptr[i][j] < info[i][j].size() &&
             info[i][j][ptr[i][j]].first <= cord) {
        Q[i][j].push(info[i][j][ptr[i][j]].second);
        ++ptr[i][j];
        ++cntr[i][j];
      }
    }
  }
}
int nCr(int n, int r) {
  if (n < r) return 0;
  assert(r <= n && r >= 0);
  return mul(fac[n], mul(inv[n - r], inv[r]));
}
int dp[MX][MX * MX];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout << fixed << setprecision(25);
  fac[0] = 1;
  for (int i = 1; i < N; ++i) fac[i] = mul(fac[i - 1], i);
  inv[N - 1] = power(fac[N - 1], mod - 2);
  for (int i = N - 2; i >= 0; --i) inv[i] = mul(inv[i + 1], i + 1);
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    cin >> L[i] >> R[i];
  }
  int u, v;
  for (int i = 1; i <= m; ++i) {
    cin >> u >> v;
    G[u].insert(v);
    G[v].insert(u);
  }
  int curr = 0;
  for (int i = 1; i <= n; ++i) {
    if (comp[i] == 0) dfs(i, ++curr);
  }
  for (int i = 1; i <= curr; ++i) {
    if (ele[i].size() == 1) {
      pre[L[ele[i][0]]]++;
      pre[R[ele[i][0]] + 1]--;
    } else {
      brute(i);
    }
  }
  for (int i = 1; i <= n; ++i) pre[i] += pre[i - 1];
  long long f_ans = 0;
  for (int i = 1; i <= n; ++i) {
    transition(i);
    int sm_all = 0;
    for (int j = 1; j <= delta_prime; ++j) {
      int mx = 0;
      for (int k = 0; k < MX; ++k)
        if (cntr[j][k]) mx = k;
      sm_all += mx;
    }
    dp[0][0] = 1;
    sm_all = min(sm_all, i);
    for (int k = 1; k <= delta_prime; ++k) {
      for (int tot = 0; tot <= sm_all; ++tot) dp[k][tot] = 0;
      for (int l = 0; l < MX; ++l) {
        if (cntr[k][l] == 0) break;
        for (int tot = l; tot <= sm_all; ++tot) {
          dp[k][tot] = add(dp[k][tot], mul(dp[k - 1][tot - l], cntr[k][l]));
        }
      }
    }
    if (i > sm_all + pre[i]) continue;
    for (int j = 0; j <= sm_all; ++j) {
      f_ans = add(f_ans, mul(dp[delta_prime][j], nCr(pre[i], i - j)));
    }
  }
  cout << f_ans << "\n";
  return 0;
}
