#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 10;
const int MOD = 998244353;
struct seg {
  int sum, lz;
} tree[maxn * 4];
struct node {
  int l, r;
};
node p[maxn];
int l[maxn], r[maxn];
int a[maxn], b[maxn];
int n, m;
long long frac[maxn], ifrac[maxn];
long long sum[maxn][45];
long long ans;
void init();
long long fpow(long long a, long long b);
void update(int o, int L, int R, int ql, int qr, int v);
int query(int o, int L, int R, int pos);
int bitcount(int x);
int countw(int s);
void pushdown(int o, int L, int R);
long long C(int nn, int k);
int main() {
  scanf("%d%d", &n, &m);
  init();
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &l[i], &r[i]);
    update(1, 1, n, l[i], r[i], 1);
  }
  ans = 0;
  for (int i = 1; i <= n; i++) {
    ans = (ans + C(query(1, 1, n, i), i)) % MOD;
    for (int j = 0; j <= 40; j++)
      sum[i][j] = (sum[i - 1][j] + C(query(1, 1, n, i) - j, i - j)) % MOD;
  }
  for (int i = 0; i < m; i++) scanf("%d%d", &a[i], &b[i]);
  p[0].l = 1;
  p[0].r = n;
  for (int i = 1; i < (1 << m); i++) {
    int f = (bitcount(i) & 1) ? -1 : 1;
    int sz = countw(i);
    for (int j = 0; j < m; j++) {
      if (i & (1 << j)) {
        int t = i ^ (1 << j);
        p[i] = p[t];
        p[i].l = max(p[i].l, l[a[j]]);
        p[i].l = max(p[i].l, l[b[j]]);
        p[i].r = min(p[i].r, r[a[j]]);
        p[i].r = min(p[i].r, r[b[j]]);
        if (p[i].l > p[i].r) break;
        ans = (ans +
               (long long)f * (sum[p[i].r][sz] - sum[p[i].l - 1][sz] + MOD) %
                   MOD +
               MOD) %
              MOD;
        break;
      }
    }
  }
  printf("%lld\n", ans);
  return 0;
}
void init() {
  frac[0] = 1;
  for (int i = 1; i <= n; i++) frac[i] = (frac[i - 1] * i) % MOD;
  ifrac[n] = fpow(frac[n], MOD - 2);
  for (int i = n - 1; i >= 0; i--)
    ifrac[i] = (long long)(i + 1) * ifrac[i + 1] % MOD;
  return;
}
long long fpow(long long a, long long b) {
  long long ret = 1;
  while (b) {
    if (b & 1) ret = (ret * a) % MOD;
    a = (a * a) % MOD;
    b >>= 1;
  }
  return ret;
}
void update(int o, int L, int R, int ql, int qr, int v) {
  int lch = o * 2, rch = o * 2 + 1;
  if (ql <= L && R <= qr) {
    tree[o].lz += v;
    tree[o].sum += (R - L + 1) * v;
    return;
  }
  pushdown(o, L, R);
  int mid = (L + R) / 2;
  if (ql <= mid) update(lch, L, mid, ql, qr, v);
  if (qr > mid) update(rch, mid + 1, R, ql, qr, v);
  tree[o].sum = tree[lch].sum + tree[rch].sum;
}
void pushdown(int o, int L, int R) {
  if (!tree[o].lz) return;
  int lch = o * 2, rch = o * 2 + 1, mid = (L + R) / 2;
  ;
  tree[lch].sum += tree[o].lz * (mid - L + 1);
  tree[lch].lz += tree[o].lz;
  tree[rch].sum += tree[o].lz * (R - mid);
  tree[rch].lz += tree[o].lz;
  tree[o].lz = 0;
  return;
}
int query(int o, int L, int R, int pos) {
  int lch = o * 2, rch = o * 2 + 1;
  if (L == R) {
    return tree[o].sum;
  }
  pushdown(o, L, R);
  int mid = (L + R) / 2;
  if (pos <= mid) return query(lch, L, mid, pos);
  return query(rch, mid + 1, R, pos);
}
long long C(int nn, int k) {
  if (nn < k || k < 0) return 0;
  return frac[nn] * ifrac[k] % MOD * ifrac[nn - k] % MOD;
}
int bitcount(int x) { return x ? (x & 1) + bitcount(x >> 1) : 0; }
int countw(int s) {
  map<int, int> mp;
  int ret = 0;
  for (int i = 0; i < m; i++) {
    if (s & (1 << i)) {
      if (!mp[a[i]]) {
        ++ret;
        mp[a[i]] = 1;
      }
      if (!mp[b[i]]) {
        ++ret;
        mp[b[i]] = 1;
      }
    }
  }
  return ret;
}
