#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

const int mod = 998244353;

int exgcd(int a, int b, int &x, int &y) {
	if (b == 0) { x = 1; y = 0; return a; }
	else { int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; }
}

int inv(int a) {
	int x, y;
	exgcd(a, mod, x, y);
	return (x % mod + mod) % mod;
}

const int mxn = 3e5 + 5, mxm = 25;
int n, m, l[mxn], r[mxn], e[mxm][2], c[mxn], s[mxm * 2][mxn], fac[mxn], ifac[mxn];

int comb(int n, int m) {
	if (m < 0 || m > n) return 0;
	return 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main() {
	scanf("%d %d", &n, &m);
	rep(i, n) scanf("%d %d", &l[i], &r[i]), c[l[i]] ++, c[r[i] + 1] --;
	rep(i, mxn) if (i) c[i] += c[i - 1];
	rep(i, m) scanf("%d %d", &e[i][0], &e[i][1]), -- e[i][0], -- e[i][1];
	rep(i, mxn) fac[i] = i ? 1LL * i * fac[i - 1] % mod : 1;
	ifac[mxn - 1] = inv(fac[mxn - 1]);
	for (int i = mxn - 1; i; -- i) ifac[i - 1] = 1LL * i * ifac[i] % mod;
	rep(sz, mxm * 2) rep(i, mxn) s[sz][i] = ((i ? s[sz][i - 1] : 0) + comb(c[i] - sz, i - sz)) % mod;
	int ans = 0;
	rep(S, 1 << m) {
		set <int> used;
		rep(i, m) if (S >> i & 1) used.insert(e[i][0]), used.insert(e[i][1]);
		int sz = used.size();
		int L = 1, R = n;
		set <int>::iterator it;
		for (it = used.begin(); it != used.end(); ++ it) {
			L = max(L, l[*it]);
			R = min(R, r[*it]);
		}
		int cur = 0;
		if (L <= R) {
			cur = s[sz][R];
			if (L - 1 >= 0) (cur += mod - s[sz][L - 1]) %= mod;
		}
		if (__builtin_popcount(S) & 1) (ans += mod - cur) %= mod;
		else (ans += cur) %= mod;
	}
	printf("%d\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

const int mod = 998244353;

int qp(int x, int n) { return n ? 1LL * qp(1LL * x * x % mod, n >> 1) * (n & 1 ? x : 1) % mod : 1; }
int inv(int x) { return qp(x, mod - 2); }

const int mxn = 3e5 + 5;
int n, m, l[mxn], r[mxn], c[mxn], e[mxn][2], id[mxn];
int fac[mxn], ifac[mxn], f[1 << 20][45];

int comb(int n, int m) {
	if (m < 0 || m > n) return 0;
	return 1LL * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

#define cntbits __builtin_popcountll

int main() {
	rep(i, mxn) fac[i] = i ? 1LL * i * fac[i - 1] % mod : 1;
	ifac[mxn - 1] = inv(fac[mxn - 1]);
	for (int i = mxn - 1; i; -- i) ifac[i - 1] = 1LL * i * ifac[i] % mod;
	scanf("%d %d", &n, &m);
	rep(i, n) scanf("%d %d", &l[i], &r[i]);
	vector <int> ve;
	rep(i, m) {
		scanf("%d %d", &e[i][0], &e[i][1]);
		-- e[i][0]; -- e[i][1];
		ve.pb(e[i][0]); ve.pb(e[i][1]);
	}
	sort(ve.begin(), ve.end());
	ve.erase(unique(ve.begin(), ve.end()), ve.end());
	vector <int> sepr; sepr.pb(1); sepr.pb(n + 1);
	rep(i, m) sepr.pb(l[e[i][0]]), sepr.pb(r[e[i][0]] + 1), sepr.pb(l[e[i][1]]), sepr.pb(r[e[i][1]] + 1);
	sort(sepr.begin(), sepr.end()); sepr.erase(unique(sepr.begin(), sepr.end()), sepr.end());
	memset(id, -1, sizeof(id));
	rep(i, ve.size()) id[ve[i]] = i;
	rep(i, m) e[i][0] = id[e[i][0]], e[i][1] = id[e[i][1]];
	rep(i, n) c[l[i]] ++, c[r[i] + 1] --;
	rep(i, mxn) if (i) c[i] += c[i - 1];
	f[0][0] = 1;
	rep(i, m) {
		rep(S, 1 << i) {
			int nS = S | 1 << i;
			rep(k, 2) {
				int rS = 0;
				ll fre = (1LL << e[i][0]) | (1LL << e[i][1]);
				rep(j, i) if (S >> j & 1) fre |= (1LL << e[j][0]) | (1LL << e[j][1]);
				fre &= ~(1LL << e[i][k]);
				rep(j, i) if (S >> j & 1) {
					if (e[j][0] == e[i][k] || e[j][1] == e[i][k]) ;
					else rS |= 1 << j, fre &= ~((1LL << e[j][0]) | (1LL << e[j][1]));
				}
				int cfre = cntbits(fre);
				for (int a = 0; a <= cfre; ++ a)
					for (int b = 0; f[rS][b]; ++ b)
						(f[nS][a + b] += 1LL * comb(cfre, a) * f[rS][b] % mod) %= mod;
			}
			// both not
			int rS = 0;
			ll fre = 0;
			rep(j, i) if (S >> j & 1) fre |= (1LL << e[j][0]) | (1LL << e[j][1]);
			fre &= ~((1LL << e[i][0]) | (1LL << e[i][1]));
			rep(j, i) if (S >> j & 1) {
				if (e[j][0] == e[i][0] || e[j][1] == e[i][0]) ;
				else if (e[j][0] == e[i][1] || e[j][1] == e[i][1]) ;
				else rS |= 1 << j, fre &= ~((1LL << e[j][0]) | (1LL << e[j][1]));
			}
			int cfre = cntbits(fre);
			for (int a = 0; a <= cfre; ++ a)
				for (int b = 0; f[rS][b]; ++ b)
					(f[nS][a + b] += mod - 1LL * comb(cfre, a) * f[rS][b] % mod) %= mod;
		}
	}
	int ans = 0;
	rep(i, sepr.size() - 1) {
		int L = sepr[i], R = sepr[i + 1] - 1;
		int O = 0;
		ll iO = 0;
		rep(j, m) if (l[ve[e[j][0]]] <= L && R <= r[ve[e[j][0]]] && l[ve[e[j][1]]] <= L && R <= r[ve[e[j][1]]])
			O |= 1 << j, iO |= (1LL << e[j][0]) | (1LL << e[j][1]);
		for (int j = L; j <= R; ++ j) if (c[j] >= j) {
			rep(a, cntbits(iO) + 1) {
				(ans += 1LL * comb(c[j] - cntbits(iO), j - a) * f[O][a] % mod) %= mod;
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define erorp(x) cout<<#x<<"={"<<(x.F)<<" , "<<x.S<<"}"<<endl;
#define print(v,r) f(i,0,r) cout<<v[i]<<" "; cout<<endl;
#define is_bit(x,y) (x%(1<<(y+1))>=(1<<y))
#define eror(x) cout<<#x<<'='<<(x)<<endl;
#define f_(i,a,b) for(int i=a;i>=b;i--)
#define Gett(x,y) scanf("%d%d",&x,&y);
#define f(i,a,b) for(int i=a;i<b;i++)
#define get(x) scanf("%I64d",&x);
#define All(x) x.begin(),x.end()
#define gett(x) scanf("%d",&x);
#define Add(x,y) x=(x+y)%mod
#define maxm(a,b) a=max(a,b)
#define minm(a,b) a=min(a,b)
#define lst(x) x[x.size()-1]
#define sz(x) int(x.size())
#define mp make_pair
#define ll long long
#define pb push_back
#define S second
#define F first

const int N=3e5+99,mod=998244353;

int n,m,t,u,x,n1,res,ans,li[N],ri[N],mv[N],mark[N],sc[42][N];
vector<pair<int,int> > edge;
vector<int> v,vl;

ll fac[N],ifac[N];
ll pow(ll x,ll y,ll mod){if(y==0) return 1; ll p=pow(x,y/2,mod);return ((p*p%mod)*(1+(y%2)*(x-1)))%mod;}
void make_fac(){fac[0]=1; f(i,1,N) fac[i]=fac[i-1]*i%mod; ifac[N-1]=pow(fac[N-1],mod-2,mod);f_(i,N-2,0) ifac[i]=1ll*ifac[i+1]*(i+1ll)%mod;}
ll C(int k,int n){if(k>n) return 0; return fac[n]*ifac[n-k]%mod*ifac[k]%mod;}

void make_sc(){
    f(i,0,3){
        sc[i][0]=1;
        f(j,1,n+1){
            sc[i][j]=sc[i][j-1];
            if(i<=j) Add(sc[i][j],C(j-i,mv[j]-i));
        }
    }
}
int solve(int mask){
    int l=0,r=n;
    n1=0;
    vl=v;
    v.clear();
    f(i,0,m)
        if(mask&(1<<i)){
            n1++;
            u=edge[i].F,x=edge[i].S;
            if(!mark[u]) mark[u]=1,t++,v.pb(u);
            if(!mark[x]) mark[x]=1,t++,v.pb(x);
        }
    f(i,0,m)
        if(mask&(1<<i)){
            u=edge[i].F,x=edge[i].S;
            mark[u]=0;
            mark[x]=0;
        }
    f(i,0,v.size()){
        maxm(l,li[v[i]]);
        minm(r,ri[v[i]]);
    }
    res=0;
    if(l<=r){
        res=sc[t][r];
        if(l) Add(res,mod-sc[t][l-1]);
    }
}
void calc(){
    int t,ans=0;
    f(mask,0,(1<<sz(edge))){
        solve(mask);
        if(n1&1) Add(ans,mod-res);
        else Add(ans,res);
    }
    Add(ans,mod-1);
    cout<<ans;
}

int main(){
    make_fac();
    cin>>n>>m;
    f(i,1,n+1){
        Gett(li[i],ri[i])
        mv[li[i]]++;
        mv[ri[i]+1]--;
    }
    f(i,1,n+1){
        mv[i]+=mv[i-1];
        Add(res,C(mv[i],i));
    }
    make_sc();
    f(i,0,m){
        Gett(u,x);
        edge.pb(mp(u,x));
    }
    calc();
}


#include <bits/stdc++.h>
using namespace std;
#define erorp(x) cout<<#x<<"={"<<(x.F)<<" , "<<x.S<<"}"<<endl;
#define print(v,r) f(i,0,r) cout<<v[i]<<" "; cout<<endl;
#define is_bit(x,y) (x%(1<<(y+1))>=(1<<y))
#define eror(x) cout<<#x<<'='<<(x)<<endl;
#define f_(i,a,b) for(int i=a;i>=b;i--)
#define Gett(x,y) scanf("%d%d",&x,&y);
#define f(i,a,b) for(int i=a;i<b;i++)
#define get(x) scanf("%I64d",&x);
#define All(x) x.begin(),x.end()
#define gett(x) scanf("%d",&x);
#define Add(x,y) x=(x+y)%mod
#define maxm(a,b) a=max(a,b)
#define minm(a,b) a=min(a,b)
#define lst(x) x[x.size()-1]
#define sz(x) int(x.size())
#define mp make_pair
#define ll long long
#define pb push_back
#define S second
#define F first

const int N=3e5+99,M=80,mod=998244353;

int n,m,t,u,x,n1,res,ans,li[N],ri[N],mv[N],mark[N],sc[M][N];
vector<pair<int,int> > edge;
vector<int> v,vl;

ll fac[N],ifac[N];
ll pow(ll x,ll y,ll mod){if(y==0) return 1; ll p=pow(x,y/2,mod);return ((p*p%mod)*(1+(y%2)*(x-1)))%mod;}
void make_fac(){fac[0]=1; f(i,1,N) fac[i]=fac[i-1]*i%mod; ifac[N-1]=pow(fac[N-1],mod-2,mod);f_(i,N-2,0) ifac[i]=1ll*ifac[i+1]*(i+1ll)%mod;}
ll C(int k,int n){if(k>n) return 0; return fac[n]*ifac[n-k]%mod*ifac[k]%mod;}

void make_sc(){
    f(i,0,M){
        sc[i][0]=1;
        f(j,1,n+1){
            sc[i][j]=sc[i][j-1];
            if(i<=j) Add(sc[i][j],C(j-i,mv[j]-i));
        }
    }
}
int solve(int mask){
    int l=0,r=n;
    n1=0;
    vl=v;
    t=0;
    v.clear();
    f(i,0,m)
        if(mask&(1<<i)){
            n1++;
            u=edge[i].F,x=edge[i].S;
            if(!mark[u]) mark[u]=1,t++,v.pb(u);
            if(!mark[x]) mark[x]=1,t++,v.pb(x);
        }
    f(i,0,m)
        if(mask&(1<<i)){
            u=edge[i].F,x=edge[i].S;
            mark[u]=0;
            mark[x]=0;
        }
    f(i,0,v.size()){
        maxm(l,li[v[i]]);
        minm(r,ri[v[i]]);
    }
    res=0;
    if(l<=r){
        res=sc[t][r];
        if(l) Add(res,mod-sc[t][l-1]);
    }
}
void calc(){
    int t,ans=0;
    f(mask,0,(1<<sz(edge))){
        solve(mask);
        if(n1&1) Add(ans,mod-res);
        else Add(ans,res);
    }
    Add(ans,mod-1);
    cout<<ans;
}

int main(){
    make_fac();
    cin>>n>>m;
    f(i,1,n+1){
        Gett(li[i],ri[i]);
        mv[li[i]]++;
        mv[ri[i]+1]--;
    }
    f(i,1,n+1)
        mv[i]+=mv[i-1];
    make_sc();
    f(i,0,m){
        Gett(u,x);
        edge.pb(mp(u,x));
    }
    calc();
}


#include <bits/stdc++.h>
using namespace std;
#define erorp(x) cout<<#x<<"={"<<(x.F)<<" , "<<x.S<<"}"<<endl;
#define print(v,r) f(i,0,r) cout<<v[i]<<" "; cout<<endl;
#define is_bit(x,y) (x%(1<<(y+1))>=(1<<y))
#define eror(x) cout<<#x<<'='<<(x)<<endl;
#define f_(i,a,b) for(int i=a;i>=b;i--)
#define Gett(x,y) scanf("%d%d",&x,&y);
#define f(i,a,b) for(int i=a;i<b;i++)
#define get(x) scanf("%I64d",&x);
#define All(x) x.begin(),x.end()
#define gett(x) scanf("%d",&x);
#define Add(x,y) x=(x+y)%mod
#define maxm(a,b) a=max(a,b)
#define minm(a,b) a=min(a,b)
#define lst(x) x[x.size()-1]
#define sz(x) int(x.size())
#define mp make_pair
#define ll long long
#define pb push_back
#define S second
#define F first

const int N=3e5+99,M=80,mod=998244353;

int n,m,t,u,x,n1,res,ans,li[N],ri[N],mv[N],mark[N],sc[M][N];
vector<pair<int,int> > edge;
vector<int> v,vl;

ll fac[N],ifac[N];
ll pow(ll x,ll y,ll mod){if(y==0) return 1; ll p=pow(x,y/2,mod);return ((p*p%mod)*(1+(y%2)*(x-1)))%mod;}
void make_fac(){fac[0]=1; f(i,1,N) fac[i]=fac[i-1]*i%mod; ifac[N-1]=pow(fac[N-1],mod-2,mod);f_(i,N-2,0) ifac[i]=1ll*ifac[i+1]*(i+1ll)%mod;}
ll C(int k,int n){if(k>n) return 0; return fac[n]*ifac[n-k]%mod*ifac[k]%mod;}

void make_sc(){
    f(i,0,M){
        sc[i][0]=1;
        f(j,1,n+1){
            sc[i][j]=sc[i][j-1];
            if(i<=j) Add(sc[i][j],C(j-i,mv[j]-i));
        }
    }
}
int solve(int mask){
    int l=0,r=n;
    n1=0;
    vl=v;
    v.clear();
    f(i,0,m)
        if(mask&(1<<i)){
            n1++;
            u=edge[i].F,x=edge[i].S;
            if(!mark[u]) mark[u]=1,t++,v.pb(u);
            if(!mark[x]) mark[x]=1,t++,v.pb(x);
        }
    f(i,0,m)
        if(mask&(1<<i)){
            u=edge[i].F,x=edge[i].S;
            mark[u]=0;
            mark[x]=0;
        }
    f(i,0,v.size()){
        maxm(l,li[v[i]]);
        minm(r,ri[v[i]]);
    }
    res=0;
    if(l<=r){
        res=sc[t][r];
        if(l) Add(res,mod-sc[t][l-1]);
    }
}
void calc(){
    int t,ans=0;
    f(mask,0,(1<<sz(edge))){
        solve(mask);
        if(n1&1) Add(ans,mod-res);
        else Add(ans,res);
    }
    Add(ans,mod-1);
    cout<<ans;
}

int main(){
    make_fac();
    cin>>n>>m;
    f(i,1,n+1){
        Gett(li[i],ri[i])
        mv[li[i]]++;
        mv[ri[i]+1]--;
    }
    f(i,1,n+1){
        mv[i]+=mv[i-1];
        Add(res,C(mv[i],i));
    }
    make_sc();
    f(i,0,m){
        Gett(u,x);
        edge.pb(mp(u,x));
    }
    calc();
}


#include<bits/stdc++.h>

using namespace std;

const int N = 300043;
const int MOD = 998244353;

int add(int x, int y)
{
    return ((x + y) % MOD + MOD) % MOD;
}

int mul(int x, int y)
{
    return (x * 1ll * y) % MOD;
}

int binpow(int x, int y)
{
    int z = 1;
    while(y > 0)
    {
        if(y % 2 == 1)
            z = mul(z, x);
        x = mul(x, x);
        y /= 2;
    }
    return z;
}

int inv(int x)
{
    return binpow(x, MOD - 2);
}

int fact[N];
int rfact[N];

void prepare_fact()
{
    fact[0] = 1;
    for(int i = 1; i < N; i++)
        fact[i] = mul(i, fact[i - 1]);
    for(int i = 0; i < N; i++)
        rfact[i] = inv(fact[i]);
}

int c(int n, int k)
{
    if(n < 0 || n < k || k < 0)
        return 0;
    return mul(fact[n], mul(rfact[k], rfact[n - k]));
}

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    vector<int> l(n), r(n), a(m), b(m);
    for(int i = 0; i < n; i++)
        scanf("%d %d", &l[i], &r[i]);
    for(int i = 0; i < m; i++)
        scanf("%d %d", &a[i], &b[i]);
    vector<int> cnt(n + 2);
    for(int i = 0; i < n; i++)
    {
        cnt[l[i]]++;
        cnt[r[i] + 1]--;
    }
    for(int i = 0; i < n + 1; i++)
        cnt[i + 1] += cnt[i];
    prepare_fact();
    vector<vector<int> > p(2 * m + 1, vector<int>(n + 1));
    for(int i = 1; i <= n; i++)
        for(int j = 0; j <= 2 * m; j++)
            p[j][i] = add(p[j][i - 1], c(cnt[i] - j, i - j));
    int ans = 0;
    for(int mask = 0; mask < (1 << m); mask++)
    {
        int sign = 1;
        set<int> used;
        for(int i = 0; i < m; i++)
            if(mask & (1 << i))
            {
                sign = mul(sign, MOD - 1);
                used.insert(a[i] - 1);
                used.insert(b[i] - 1);
            }
        int L = 1, R = n;
        for(auto x : used)
        {
            L = max(L, l[x]);
            R = min(R, r[x]);
        }
        if(R < L) continue;
        ans = add(ans, mul(sign, add(p[used.size()][R], -p[used.size()][L - 1])));
    }
    printf("%d\n", ans);
}


// #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//
// #include <immintrin.h>
// #include <emmintrin.h>

#include <bits/stdc++.h>
#pragma GCC optimize("O2")
#define vi vector<int>
#define vpii vector<pii>
#define pii pair<int, int >
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define LL long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define all(x) (x).begin(), (x).end()
#define aal(x,n) (x+1), (x+1+n)
#define sz(x) ((int)(x).size())
#define mod(x) ((x)%MOD)
#define eb emplace_back
#define o(X) (1<<(X))
#define oL(X) (1LL<<(X))
#define ppt(x) __builtin_popcount(x)
using namespace std;
const int INF=0x3f3f3f3f,N=1e6+5,M=4e5+5,MOD=998244353;
const LL INF_LL=0x3f3f3f3f3f3f3f3fLL;
template<typename T>
inline int getplc(T x,int y) { return (x>>y)&1; }
template<typename T>
T square(T x) {return x*x;}
LL qpow(LL a,LL b=MOD-2,LL _MOD=MOD){
  LL res=1;
  for(;b;b>>=1,a=a*a%_MOD){
    if(b&1)res=res*a%_MOD;
  }
  return res;
}
template <typename T>
T Smax(T x) { return x; }
template<typename T, typename... Args>
T Smax(T a, Args... args) { return max(a, Smax(args...)); }
template <typename T>
T Smin(T x) { return x; }
template<typename T, typename... Args>
T Smin(T a, Args... args) { return min(a, Smin(args...)); }
template <typename T>
#define errorl(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); errl(_it, args); }
void errl(istream_iterator<string> it) {}
template<typename T, typename... Args>
void errl(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << endl;
  errl(++it, args...);
}
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr<<endl;}
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << "=" << a << " # ";
  err(++it, args...);
}

int fac[N],inv[N];
void init(int n){
	fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++)fac[i]=(LL)fac[i-1]*i%MOD;
	for(int i=1;i<=n;i++)inv[i]=qpow(fac[i],MOD-2,MOD);
}
LL Comb(int n,int m){
	if(n-m>=0&&m>=0) return 1ll*fac[n]*inv[n-m]%MOD*inv[m]%MOD;
	else return 0;
}

vector<pii>lim;
int l[N],r[N],sum[42][(int)3e5+5],c[N];
void Solve(){
  int n,m;
  cin>>n>>m;
  init(max(105,n));
  for(int i=1;i<=n;i++){
    cin>>l[i]>>r[i];
    c[l[i]]++,c[r[i]+1]--;
  }
  for(int i=1;i<=n;i++)c[i]+=c[i-1];
  for(int i=1;i<=n;i++){
    for(int j=0;j<=40;j++){
      sum[j][i]=(sum[j][i-1]+Comb(c[i]-j,i-j))%MOD;
    }
  }
  for(int i=1;i<=m;i++){
    int a,b;
    cin>>a>>b;
    lim.eb(a,b);
  }
  int all=o(m)-1;
  LL ans=0;
  for(int i=0;i<=all;i++){
    int ll=1,rr=n;
    set<int>st;
    for(int j=0;j<m;j++)if(getplc(i,j)){
      ll=max(ll,l[lim[j].fi]),rr=min(rr,r[lim[j].fi]);
      ll=max(ll,l[lim[j].se]),rr=min(rr,r[lim[j].se]);
      st.insert(lim[j].fi);
      st.insert(lim[j].se);
    }
    if(ll>rr)continue;
    ans=(ans+(LL)(ppt(i)&1?-1:1)*(sum[sz(st)][rr]-sum[sz(st)][ll-1])%MOD+MOD)%MOD;
  }
  cout<<ans<<endl;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.txt","r",stdin);
//  freopen("o1.txt","w",stdout);
#endif
  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
  Solve();
  return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 998244353;
const int N = 3e5 + 5, M = 22;
int n, m, l[N], r[N], c[N], a[M], b[M];
int s[N][M << 1], fac[N], invfac[N], ans;
int Qpow(int x, int y)
{
	int res = 1;
	while(y)
	{
		if(y & 1) res = res * x % MOD;
		x = x * x % MOD;
		y >>= 1;
	}
	return res;
}
int Binom(int x, int y)
{
	if(x < 0 || y < 0 || y > x) return 0;
	return fac[x] * invfac[y] % MOD * invfac[x - y] % MOD;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m;
	fac[0] = invfac[0] = 1;
	for(int i = 1; i <= n; i++)
	{
		fac[i] = fac[i - 1] * i % MOD;
		invfac[i] = Qpow(fac[i], MOD - 2);
	}
	for(int i = 1; i <= n; i++)
	{
		cin >> l[i] >> r[i];
		c[l[i]]++; c[r[i] + 1]--;
	}
	for(int i = 1; i <= n; i++) c[i] += c[i - 1];
	for(int i = 1; i <= n; i++)
		for(int j = 0; j <= m * 2; j++)
			s[i][j] = (s[i - 1][j] + Binom(c[i] - j, i - j)) % MOD;
	for(int i = 1; i <= m; i++) cin >> a[i] >> b[i];
	for(int S = 0; S < (1 << m); S++)
	{
		int L = 1, R = n, popcount = 0;
		set<int> cnt;
		for(int i = 1; i <= m; i++)
		{
			if(S >> i - 1 & 1)
			{
				popcount++;
				cnt.insert(a[i]);
				cnt.insert(b[i]);
				L = max(L, max(l[a[i]], l[b[i]]));
				R = min(R, min(r[a[i]], r[b[i]]));
			}
		}
		if(L > R) continue;
		int sz = cnt.size();
		int res = (s[R][sz] - s[L - 1][sz] + MOD) % MOD;
		if(popcount & 1) ans = (ans - res + MOD) % MOD;
		else ans = (ans + res) % MOD;
	}
	cout << ans << endl;
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=3e5+1;
const int p=998244353;
#define int long long
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
int fac[maxn],inv[maxn],pre[maxn],n,l[maxn],r[maxn],m,a[21],b[21],Ans,all,nl,nr,cnt,x,vis[maxn],Cnt[maxn],WS,sum[maxn][41];
inline int min(int a,int b) { return a<b?a:b; }
inline int max(int a,int b) { return a>b?a:b; }
inline int ksm(int a,int b) { int ans=1,tmp=a; for(;b;b>>=1,tmp*=tmp,tmp%=p) if(b&1) ans=(ans*tmp)%p; return ans; }
inline int C(int a,int b) { return (((fac[a]*inv[b])%p)*inv[a-b])%p; }
inline void upd(int &x,int y) { x=(((x+y)%p)+p)%p; }
inline void add(int idx) {
	if(vis[idx]) return;
	cnt++;
	vis[idx]=1;
	nl=max(nl,l[idx]);
	nr=min(nr,r[idx]);
}
signed main() {
	scanf("%lld %lld",&n,&m);
	fac[0]=1; inv[0]=1;
	rep(i,1,n) (fac[i]=(fac[i-1]*i)%p),inv[i]=ksm(fac[i],p-2);
	rep(i,1,n) {
		scanf("%lld %lld",&l[i],&r[i]);
		pre[l[i]]++; pre[r[i]+1]--;
	}
	rep(i,1,m) scanf("%lld %lld",&a[i],&b[i]);
	rep(i,1,n) pre[i]+=pre[i-1];
	rep(i,0,40)
	rep(pos,1,n) {
		if(pos>=i&&pre[pos]>=i&&pre[pos]>=pos) sum[pos][i]=(sum[pos-1][i]+C(pre[pos]-i,pos-i))%p;
		else sum[pos][i]=sum[pos-1][i];
	}
	all=(1<<m)-1;
	rep(k,0,all) {
		cnt=0; nl=1; nr=n; WS=0;
		rep(i,1,m) vis[a[i]]=0,vis[b[i]]=0;
		rep(i,1,m) if((k>>(i-1))&1) {
			add(a[i]); add(b[i]);
			WS++;
		}
		x=0;
		if(nl>nr) continue;
		x=(sum[nr][cnt]-sum[nl-1][cnt]); (x+=p)%=p;
		if(WS&1) upd(Ans,-x);
		else upd(Ans,x);
	}
	printf("%lld\n",Ans);
}


// #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//
// #include <immintrin.h>
// #include <emmintrin.h>

#include <bits/stdc++.h>
#pragma GCC optimize("O2")
#define vi vector<int>
#define vpii vector<pii>
#define pii pair<int, int >
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define LL long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define all(x) (x).begin(), (x).end()
#define aal(x,n) (x+1), (x+1+n)
#define sz(x) ((int)(x).size())
#define mod(x) ((x)%MOD)
#define eb emplace_back
#define o(X) (1<<(X))
#define oL(X) (1LL<<(X))
#define ppt(x) __builtin_popcount(x)
using namespace std;
const int INF=0x3f3f3f3f,N=1e6+5,M=4e5+5,MOD=998244353;
const LL INF_LL=0x3f3f3f3f3f3f3f3fLL;
template<typename T>
inline int getplc(T x,int y) { return (x>>y)&1; }
template<typename T>
T square(T x) {return x*x;}
LL qpow(LL a,LL b=MOD-2,LL _MOD=MOD){
  LL res=1;
  for(;b;b>>=1,a=a*a%_MOD){
    if(b&1)res=res*a%_MOD;
  }
  return res;
}
template <typename T>
T Smax(T x) { return x; }
template<typename T, typename... Args>
T Smax(T a, Args... args) { return max(a, Smax(args...)); }
template <typename T>
T Smin(T x) { return x; }
template<typename T, typename... Args>
T Smin(T a, Args... args) { return min(a, Smin(args...)); }
template <typename T>
#define errorl(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); errl(_it, args); }
void errl(istream_iterator<string> it) {}
template<typename T, typename... Args>
void errl(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << endl;
  errl(++it, args...);
}
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); cerr<<endl;}
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << "=" << a << " # ";
  err(++it, args...);
}

int fac[N],inv[N];
void init(int n){
	fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++)fac[i]=(LL)fac[i-1]*i%MOD;
	for(int i=1;i<=n;i++)inv[i]=qpow(fac[i],MOD-2,MOD);
}
LL Comb(int n,int m){
	if(n-m>=0&&m>=0) return 1ll*fac[n]*inv[n-m]%MOD*inv[m]%MOD;
	else return 0;
}

vector<pii>lim;
int l[N],r[N],sum[42][(int)3e5+5],c[N];
void Solve(){
  int n,m;
  cin>>n>>m;
  init(n);
  for(int i=1;i<=n;i++){
    cin>>l[i]>>r[i];
    c[l[i]]++,c[r[i]+1]--;
  }
  for(int i=1;i<=n;i++)c[i]+=c[i-1];
  for(int i=1;i<=n;i++){
    for(int j=0;j<=40;j++){
      sum[j][i]=(sum[j][i-1]+Comb(c[i]-j,i-j))%MOD;
    }
  }
  for(int i=1;i<=m;i++){
    int a,b;
    cin>>a>>b;
    lim.eb(a,b);
  }
  int all=o(m)-1;
  LL ans=0;
  for(int i=0;i<=all;i++){
    int ll=1,rr=n;
    set<int>st;
    for(int j=0;j<m;j++)if(getplc(i,j)){
      ll=max(ll,l[lim[j].fi]),rr=min(rr,r[lim[j].fi]);
      ll=max(ll,l[lim[j].se]),rr=min(rr,r[lim[j].se]);
      st.insert(lim[j].fi);
      st.insert(lim[j].se);
    }
    if(ll>rr)continue;
    ans=(ans+(LL)(ppt(i)?-1:1)*(sum[sz(st)][rr]-sum[sz(st)][ll-1]))%MOD;
  }
  cout<<ans<<endl;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.txt","r",stdin);
//  freopen("o1.txt","w",stdout);
#endif
  ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
  Solve();
  return 0;
}


#include<bits/stdc++.h>
#define rg register
#define fp( i , x , y ) for( rg int i=(x); i<=(y); ++i )
#define fq( i , x , y ) for( rg int i=(y); i>=(x); --i )
using namespace std ;
const int N = 3e5+10 , hgs = 998244353 , M = 40 ;
int s[N][M] , n , xi[N] , yi[N] , m ;
struct node { int l , r ; } a[N] ;
int fac[N] , inv_f[N] ;
bool vis[N] ;
int qpow( int A , int B ) {
  int C = 1 ;
  for( ; B ; B>>=1 , A=1ll*A*A%hgs )
   if( B&1 ) C = 1ll*A*C%hgs ;
  return C ;
}
int C( int A , int B ) {
  if( A < 0 || B < 0 || A > B ) return 0 ;
  return 1ll * fac[B] * inv_f[A] % hgs * inv_f[B-A] % hgs ;
}
int calc( int S ) {
  int l=1 , r=n , x , y , tot=0 , f=1 ;
  fp( i , 1 , m ) {
    if( !(S&(1<<i-1)) ) continue ;
    x = xi[i] ; y = yi[i] ; f = -f ;
    if( !vis[x] ) tot ++ , vis[x] = 1 ;
    if( !vis[y] ) tot ++ , vis[y] = 1 ;
    l = max( l , a[x].l ) ; l = max( l , a[y].l ) ;
	r = min( r , a[x].r ) ; r = min( r , a[y].r ) ;
  }
  fp( i , 1 , m )
   if( S&(1<<i-1) )
    vis[xi[i]] = vis[yi[i]] = 0 ;
  if( l > r ) return 0 ;
  //printf( "%d %d %d %d\n" , l , r , tot , f ) ;
  return ( s[r][tot] - s[l-1][tot] ) * f ;
}
signed main( ) {
  scanf( "%d %d" , &n , &m ) ;
  inv_f[0] = fac[0] = 1 ;
  fp( i , 1 , n )
    fac[i] = 1ll * fac[i-1] * i % hgs ,
    inv_f[i] = qpow( fac[i] , hgs-2 ) ;
  fp( i , 1 , n )
    scanf( "%d %d" , &a[i].l , &a[i].r ) ,
    s[a[i].l][0] ++ , s[a[i].r+1][0] -- ;
  fp( i , 1 , m )
    scanf( "%d %d" , &xi[i] , &yi[i] ) ;
  fp( i , 1 , n ) {
//	printf( "%d %d\n" , i , s[i][0]  ) ;
    s[i][0] += s[i-1][0] ;
	fp( j , 1 , 2*m )
	  s[i][j] = C( i-j , s[i][0]-j  ) ,
	  s[i][j] += s[i-1][j] , s[i][j] %= hgs ;
  }
  fp( i , 1 , n )
    s[i][0] = C( i , s[i][0] ) ,
	s[i][0] += s[i-1][0] , s[i][0] %= hgs ;
  int S = (1<<m)-1 ;
  int ans = s[n][0] ;
//  printf( "%d\n" , ans ) ;
  fp( i , 1 , S )
    ans = ( ans + calc( i ) % hgs ) % hgs ,
	ans = ( ans + hgs ) % hgs ;
  printf( "%d\n" , ans ) ;
  return 0 ;
}


#include<bits/stdc++.h>
#define rg register
#define fp( i , x , y ) for( rg int i=(x); i<=(y); ++i )
#define fq( i , x , y ) for( rg int i=(y); i>=(x); --i )
using namespace std ;
const int N = 3e5+10 , hgs = 998244353 , M = 45 ;
int s[N][M] , n , xi[N] , yi[N] , m ;
struct node { int l , r ; } a[N] ;
int fac[N] , inv_f[N] ;
bool vis[N] ;
int qpow( int A , int B ) {
  int C = 1 ;
  for( ; B ; B>>=1 , A=1ll*A*A%hgs )
   if( B&1 ) C = 1ll*A*C%hgs ;
  return C ;
}
int C( int A , int B ) {
  if( A < 0 || B < 0 || A > B ) return 0 ;
  return 1ll * fac[B] * inv_f[A] % hgs * inv_f[B-A] % hgs ;
}
int calc( int S ) {
  int l=1 , r=n , x , y , tot=0 , f=1 ;
  fp( i , 1 , m ) {
    if( !(S&(1<<i-1)) ) continue ;
    x = xi[i] ; y = yi[i] ; f = -f ;
    if( !vis[x] ) tot ++ , vis[x] = 1 ;
    if( !vis[y] ) tot ++ , vis[y] = 1 ;
    l = max( l , a[x].l ) ; l = max( l , a[y].l ) ;
	r = min( r , a[x].r ) ; r = min( r , a[y].r ) ;
  }
  fp( i , 1 , m )
   if( S&(1<<i-1) )
    vis[xi[i]] = vis[yi[i]] = 0 ;
  if( l > r ) return 0 ;
  //printf( "%d %d %d %d\n" , l , r , tot , f ) ;
  return ( s[r][tot] - s[l-1][tot] ) * f ;
}
signed main( ) {
  scanf( "%d %d" , &n , &m ) ;
  inv_f[0] = fac[0] = 1 ;
  fp( i , 1 , n )
    fac[i] = 1ll * fac[i-1] * i % hgs ,
    inv_f[i] = qpow( fac[i] , hgs-2 ) ;
  fp( i , 1 , n )
    scanf( "%d %d" , &a[i].l , &a[i].r ) ,
    s[a[i].l][0] ++ , s[a[i].r+1][0] -- ;
  fp( i , 1 , m )
    scanf( "%d %d" , &xi[i] , &yi[i] ) ;
  fp( i , 1 , n ) {
//	printf( "%d %d\n" , i , s[i][0]  ) ;
    s[i][0] += s[i-1][0] ;
	fp( j , 1 , 2*m )
	  s[i][j] = C( i-j , s[i][0]-j  ) ,
	  s[i][j] += s[i-1][j] , s[i][j] %= hgs ;
  }
  fp( i , 1 , n )
    s[i][0] = C( i , s[i][0] ) ,
	s[i][0] += s[i-1][0] , s[i][0] %= hgs ;
  int S = (1<<m)-1 ;
  int ans = s[n][0] ;
//  printf( "%d\n" , ans ) ;
  fp( i , 1 , S )
    ans = ( ans + calc( i ) % hgs ) % hgs ,
	ans = ( ans + hgs ) % hgs ;
  printf( "%d\n" , ans ) ;
  return 0 ;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+9, M=29, mod=998244353;

int n,m,l[N],r[N],u[N],v[N];

int fac[N],inv[N],ifac[N];
void pre() {
	inv[0]=inv[1]=fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
	for(int i=2;i<=n;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
	for(int i=1;i<=n;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
}
int C(int x,int y) {
	if(x<0||y<0||x<y) return 0;
	else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

int cf[N],p[N],s[N][49];
void cal_p() {
	for(int i=1;i<=n;i++) cf[l[i]]++, cf[r[i]+1]--;
	int ssum=0;
	for(int i=1;i<=n;i++) ssum+=cf[i], p[i]=ssum;
	for(int j=0;j<=2*m;j++) for(int i=1;i<=n;i++) {
		s[i][j]=(s[i-1][j]+C(p[i]-j,i-j))%mod;
	}
}

struct hset {
	bool vst[N];
	int ar[N], size;
	void clear() {
		for(int i=1;i<=size;i++) vst[ar[i]]=0;
		size=0;
	}
	void add(int x) {if(!vst[x]) ar[++size]=x, vst[x]=1;}
}st;

#define bit(S,i) (bool)((1<<i-1)&S)
int ans;
void in_ex() {
	for(int S=0;S<(1<<m);S++) {
		int L=1, R=n, pop=0;
		for(int j=1;j<=m;j++) if(bit(S,j)) {
			L=max(L,l[u[j]]), R=min(R,r[u[j]]), st.add(u[j]);
			L=max(L,l[v[j]]), R=min(R,r[v[j]]), st.add(v[j]);
			pop++;
		}
		if(L>R) continue;
		int res=(s[R][st.size]-s[L-1][st.size]+mod)%mod;
		ans=(ans+res*(pop&1 ? -1 : 1)+mod)%mod;
		st.clear();
	}
}

int main() {
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld%lld",&l[i],&r[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld",&u[i],&v[i]);
	pre();
	cal_p();
	in_ex();
	printf("%lld",(ans%mod+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+9, M=29, mod=998244353;

int n,m,l[N],r[N],u[N],v[N];

int fac[N],inv[N],ifac[N];
void pre() {
	inv[0]=inv[1]=fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
	for(int i=2;i<=n;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
	for(int i=1;i<=n;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
}
int C(int x,int y) {
	if(x<0||y<0||x<y) return 0;
	else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

int cf[N],p[N],s[N][49];
void cal_p() {
	for(int i=1;i<=n;i++) cf[l[i]]++, cf[r[i]+1]--;
	int ssum=0;
	for(int i=1;i<=n;i++) ssum+=cf[i], p[i]=ssum;
	for(int j=0;j<=2*m;j++) for(int i=1;i<=n;i++) {
		s[i][j]=(s[i-1][j]+C(p[i]-j,i-j))%mod;
	}
}

struct hset {
	bool vst[N];
	int ar[N], size;
	void clear() {
		for(int i=1;i<=size;i++) vst[ar[i]]=0;
		size=0;
	}
	void add(int x) {if(!vst[x]) ar[++size]=x, vst[x]=1;}
}st;

#define bit(S,i) (bool)((1<<i-1)&S)
int ans;
void in_ex() {
	for(int S=0;S<(1<<m);S++) {
		int L=1, R=n, pop=0;
		for(int j=1;j<=m;j++) if(bit(S,j)) {
			L=max(L,l[u[j]]), R=min(R,r[u[j]]), st.add(u[j]);
			L=max(L,l[v[j]]), R=min(R,r[v[j]]), st.add(v[j]);
			pop++;
		}
		if(L>R) continue;
		int res=(s[R][st.size]-s[L-1][st.size]+mod)%mod;
		ans=(ans+res*(pop&1 ? -1 : 1)+mod)%mod;
		st.clear();
	}
}

signed main() {
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld%lld",&l[i],&r[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld",&u[i],&v[i]);
	pre();
	cal_p();
	in_ex();
	printf("%lld",(ans%mod+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+9, M=29, mod=998244353;

int n,m,l[N],r[N],u[N],v[N];

int fac[N],inv[N],ifac[N];
void pre() {
	inv[0]=inv[1]=fac[0]=ifac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
	for(int i=2;i<=n;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
	for(int i=1;i<=n;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
}
int C(int x,int y) {
	if(x<0||y<0||x<y) return 0;
	else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

int cf[N],p[N],s[N][49];
void cal_p() {
	for(int i=1;i<=n;i++) cf[l[i]]++, cf[r[i]+1]--;
	int ssum=0;
	for(int i=1;i<=n;i++) ssum+=cf[i], p[i]=ssum;
	for(int j=0;j<=2*m;j++) for(int i=1;i<=n;i++) {
		s[i][j]=(s[i-1][j]+C(p[i]-j,i-j))%mod;
	}
}

struct hset {
	bool vst[N];
	int ar[N], size;
	void clear() {
		for(int i=1;i<=size;i++) vst[ar[i]]=0;
		size=0;
	}
	void add(int x) {if(!vst[x]) ar[++size]=x, vst[x]=1;}
}st;

#define bit(S,i) (bool)((1<<i-1)&S)
int ans;
void in_ex() {
	for(int S=0;S<(1<<m);S++) {
		int L=1, R=n, pop=0;
		for(int j=1;j<=m;j++) if(bit(S,j)) {
			L=max(L,l[u[j]]), R=min(R,r[u[j]]), st.add(u[j]);
			L=max(L,l[v[j]]), R=min(R,r[v[j]]), st.add(v[j]);
			pop++;
		}
		if(L>R) {st.clear();continue;}
		//cout<<st.size<<" "<<pop<<endl;
		int res=(s[R][st.size]-s[L-1][st.size]+mod)%mod;
		//if(res) cout<<ans<<" "<<(pop&1 ? '-' : '+')<<" "<<res<<" = ";
		ans=(ans+res*(pop&1 ? -1 : 1)+mod)%mod;
		//if(res) cout<<ans<<endl;
		st.clear();
	}
}

signed main() {
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld%lld",&l[i],&r[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld",&u[i],&v[i]);
	pre();
	cal_p();
	in_ex();
	printf("%lld",(ans+mod)%mod);
	return 0;
}


#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mkp make_pair
#define rint register int
#define INF ((1 << 30) - 1)
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Pair pair < int, int >
#define mst(a,b) memset(a,b,sizeof(a))
#define foR(i, k, j) for(rint i = (k); i >= (j); i--)
#define For(i, k, j) for(rint i = (k); i <= (j); i++)
#define Foe(i, u) for(rint i = lst[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define file(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout)
#define int long long
const int P = 998244353; //
using namespace std;
inline void ckmax(int &a, int b) {a = max(a, b);}
inline void ckmin(int &a, int b) {a = min(a, b);}
inline void mul(int &a, int b) {a = 1ll * a * b % P;}
inline void addmod(int &a, int b) {int t = a + b; a = (t >= P ? t - P : t); }
inline int ksm(int a, int b) {int ans=1; for(;b;b>>=1) {if(b&1) ans=1ll*ans*a%P;a=1ll*a*a%P;}return ans;}
inline int inv(int a) {return ksm(a, P-2);}
inline void printarray(int *a, int n) {For(i, 1, n) fprintf(stderr, "%d ", a[i]); fprintf(stderr, "\n");}
namespace FastIO {
    const int SIZE=1<<16; char buf[SIZE], obuf[SIZE], str[64]; int bi=SIZE, bn=SIZE, opt;
    int read(char *s) {
        while (bn) {for (;bi<bn&&buf[bi]<=' ';bi++);if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}
        int sn=0;while (bn) {for (;bi<bn&&buf[bi]>' ';bi++) s[sn++]=buf[bi];if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}s[sn]=0;return sn;
    }
    bool read(int& x) {if(x)x=0;int bf=0,n=read(str); if(!n)return 0; int i=0; if (str[i]=='-') bf=1,i=1; for(x=0;i<n;i++) x=x*10+str[i]-'0'; if(bf) x=-x; return 1;}
    void write(int x) {
        if(!x) obuf[opt++] = '0'; else {if(x<0) obuf[opt++]='-',x=-x;int sn=0; while(x)str[sn++]=x%10+'0',x/=10;for (int i=sn-1;i>=0;i--) obuf[opt++]=str[i];}
        if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}
    }
    void write(char x) {obuf[opt++]=x;if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}}
    void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt=0;}
};
const int MAXN = 3e5 + 5;
const int MAXM = 25;
int n, m, l[MAXN], r[MAXN], u[MAXM], v[MAXM], s[MAXN];
int fac[MAXN], ifac[MAXN], sum[MAXN][55];

bool used[MAXN];
inline int C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

signed main()
{
	#ifndef ONLINE_JUDGE
		file("pro");
	#endif
	FI(n), FI(m);
	fac[0] = ifac[0] = 1;
	For(i, 1, n) fac[i] = 1ll * fac[i-1] * i % P;
	For(i, 1, n) ifac[i] = inv(fac[i]);
	For(i, 1, n) FI(l[i]), FI(r[i]), s[l[i]]++, s[r[i] + 1]--;
	For(i, 1, n) s[i] += s[i-1];
	For(i, 0, m - 1) FI(u[i]), FI(v[i]);
	int res = 0;

	For(i, 1, n) addmod(res, C(s[i], i));
	For(i, 1, n) For(j, 1, m * 2)
		sum[i][j] = sum[i-1][j] + C(s[i] - j, i - j);
//	cerr << "?";
	For(st, 1, (1 << m) - 1) {
//		cerr << st << endl;
		int L = -1, R = INF, o = (__builtin_popcount(st) & 1) ? -1 : 1, cnt = 0;
		For(i, 0, m - 1) {
			if((st >> i) & 1) {
				ckmax(L, l[u[i]]), ckmin(R, r[u[i]]), cnt += (!used[u[i]]), used[u[i]] = 1;
				ckmax(L, l[v[i]]), ckmin(R, r[v[i]]), cnt += (!used[v[i]]), used[v[i]] = 1;
			}
		}
		if(L <= R) addmod(res, (o * (sum[R][cnt] - sum[L - 1][cnt]) % P + P) % P);
		For(i, 0, m - 1) used[u[i]] = used[v[i]] = 0;
	}
	cout << res << endl;
    return FastIO::Fflush(), 0;
}
/*
tot - illegal

*/


#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mkp make_pair
#define rint register int
#define INF ((1 << 30) - 1)
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Pair pair < int, int >
#define mst(a,b) memset(a,b,sizeof(a))
#define foR(i, k, j) for(rint i = (k); i >= (j); i--)
#define For(i, k, j) for(rint i = (k); i <= (j); i++)
#define Foe(i, u) for(rint i = lst[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define file(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout)
//#define int long long
const int P = 998244353; //
using namespace std;
inline void ckmax(int &a, int b) {a = max(a, b);}
inline void ckmin(int &a, int b) {a = min(a, b);}
inline void mul(int &a, int b) {a = 1ll * a * b % P;}
inline void addmod(int &a, int b) {int t = a + b; a = (t >= P ? t - P : t); }
inline int ksm(int a, int b) {int ans=1; for(;b;b>>=1) {if(b&1) ans=1ll*ans*a%P;a=1ll*a*a%P;}return ans;}
inline int inv(int a) {return ksm(a, P-2);}
inline void printarray(int *a, int n) {For(i, 1, n) fprintf(stderr, "%d ", a[i]); fprintf(stderr, "\n");}
namespace FastIO {
    const int SIZE=1<<16; char buf[SIZE], obuf[SIZE], str[64]; int bi=SIZE, bn=SIZE, opt;
    int read(char *s) {
        while (bn) {for (;bi<bn&&buf[bi]<=' ';bi++);if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}
        int sn=0;while (bn) {for (;bi<bn&&buf[bi]>' ';bi++) s[sn++]=buf[bi];if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}s[sn]=0;return sn;
    }
    bool read(int& x) {if(x)x=0;int bf=0,n=read(str); if(!n)return 0; int i=0; if (str[i]=='-') bf=1,i=1; for(x=0;i<n;i++) x=x*10+str[i]-'0'; if(bf) x=-x; return 1;}
    void write(int x) {
        if(!x) obuf[opt++] = '0'; else {if(x<0) obuf[opt++]='-',x=-x;int sn=0; while(x)str[sn++]=x%10+'0',x/=10;for (int i=sn-1;i>=0;i--) obuf[opt++]=str[i];}
        if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}
    }
    void write(char x) {obuf[opt++]=x;if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}}
    void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt=0;}
};
const int MAXN = 3e5 + 5;
const int MAXM = 25;
int n, m, l[MAXN], r[MAXN], u[MAXM], v[MAXM], s[MAXN];
int fac[MAXN], ifac[MAXN], sum[MAXN][45];

bool used[MAXN];
inline int C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

signed main()
{
	#ifndef ONLINE_JUDGE
		file("pro");
	#endif
	FI(n), FI(m);
	fac[0] = ifac[0] = 1;
	For(i, 1, n) fac[i] = 1ll * fac[i-1] * i % P;
	For(i, 1, n) ifac[i] = inv(fac[i]);
	For(i, 1, n) FI(l[i]), FI(r[i]), s[l[i]]++, s[r[i] + 1]--;
	For(i, 1, n) s[i] += s[i-1];
	For(i, 0, m - 1) FI(u[i]), FI(v[i]);
	int res = 0;

	For(i, 1, n) addmod(res, C(s[i], i));
	For(i, 1, n) For(j, 1, m * 2)
		sum[i][j] = sum[i-1][j] + C(s[i] - j, i - j);
//	cerr << "?";
	For(st, 1, (1 << m) - 1) {
//		cerr << st << endl;
		int L = -1, R = INF, o = (__builtin_popcount(st) & 1) ? -1 : 1, cnt = 0;
		For(i, 0, m - 1) {
			if((st >> i) & 1) {
				ckmax(L, l[u[i]]), ckmin(R, r[u[i]]), cnt += (!used[u[i]]), used[u[i]] = 1;
				ckmax(L, l[v[i]]), ckmin(R, r[v[i]]), cnt += (!used[v[i]]), used[v[i]] = 1;
			}
		}
		if(L <= R)
			addmod(res, (o * (sum[R][cnt] - sum[L - 1][cnt]) % P + P) % P);
	}
	cout << res << endl;
    return FastIO::Fflush(), 0;
}
/*
tot - illegal

*/


#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mkp make_pair
#define rint register int
#define INF ((1 << 30) - 1)
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Pair pair < int, int >
#define mst(a,b) memset(a,b,sizeof(a))
#define foR(i, k, j) for(rint i = (k); i >= (j); i--)
#define For(i, k, j) for(rint i = (k); i <= (j); i++)
#define Foe(i, u) for(rint i = lst[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define file(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout)
//#define int long long
const int P = 998244353; //
using namespace std;
inline void ckmax(int &a, int b) {a = max(a, b);}
inline void ckmin(int &a, int b) {a = min(a, b);}
inline void mul(int &a, int b) {a = 1ll * a * b % P;}
inline void addmod(int &a, int b) {int t = a + b; a = (t >= P ? t - P : t); }
inline int ksm(int a, int b) {int ans=1; for(;b;b>>=1) {if(b&1) ans=1ll*ans*a%P;a=1ll*a*a%P;}return ans;}
inline int inv(int a) {return ksm(a, P-2);}
inline void printarray(int *a, int n) {For(i, 1, n) fprintf(stderr, "%d ", a[i]); fprintf(stderr, "\n");}
namespace FastIO {
    const int SIZE=1<<16; char buf[SIZE], obuf[SIZE], str[64]; int bi=SIZE, bn=SIZE, opt;
    int read(char *s) {
        while (bn) {for (;bi<bn&&buf[bi]<=' ';bi++);if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}
        int sn=0;while (bn) {for (;bi<bn&&buf[bi]>' ';bi++) s[sn++]=buf[bi];if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}s[sn]=0;return sn;
    }
    bool read(int& x) {if(x)x=0;int bf=0,n=read(str); if(!n)return 0; int i=0; if (str[i]=='-') bf=1,i=1; for(x=0;i<n;i++) x=x*10+str[i]-'0'; if(bf) x=-x; return 1;}
    void write(int x) {
        if(!x) obuf[opt++] = '0'; else {if(x<0) obuf[opt++]='-',x=-x;int sn=0; while(x)str[sn++]=x%10+'0',x/=10;for (int i=sn-1;i>=0;i--) obuf[opt++]=str[i];}
        if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}
    }
    void write(char x) {obuf[opt++]=x;if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}}
    void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt=0;}
};
const int MAXN = 3e5 + 5;
const int MAXM = 25;
int n, m, l[MAXN], r[MAXN], u[MAXM], v[MAXM], s[MAXN];
int fac[MAXN], ifac[MAXN], sum[MAXN][55];

bool used[MAXN];
inline int C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

signed main()
{
	#ifndef ONLINE_JUDGE
		file("pro");
	#endif
	FI(n), FI(m);
	fac[0] = ifac[0] = 1;
	For(i, 1, n) fac[i] = 1ll * fac[i-1] * i % P;
	For(i, 1, n) ifac[i] = inv(fac[i]);
	For(i, 1, n) FI(l[i]), FI(r[i]), s[l[i]]++, s[r[i] + 1]--;
	For(i, 1, n) s[i] += s[i-1];
	For(i, 0, m - 1) FI(u[i]), FI(v[i]);
	int res = 0;

	For(i, 1, n) addmod(res, C(s[i], i));
	For(i, 1, n) For(j, 1, m * 2)
		addmod(sum[i][j], sum[i-1][j] + C(s[i] - j, i - j));
//	cerr << "?";
	For(st, 1, (1 << m) - 1) {
//		cerr << st << endl;
		int L = -1, R = INF, o = (__builtin_popcount(st) & 1) ? -1 : 1, cnt = 0;
		For(i, 0, m - 1) {
			if((st >> i) & 1) {
				ckmax(L, l[u[i]]), ckmin(R, r[u[i]]), cnt += (!used[u[i]]), used[u[i]] = 1;
				ckmax(L, l[v[i]]), ckmin(R, r[v[i]]), cnt += (!used[v[i]]), used[v[i]] = 1;
			}
		}
		if(L <= R) addmod(res, (o * (sum[R][cnt] - sum[L - 1][cnt]) % P + P) % P);
		For(i, 0, m - 1) used[u[i]] = used[v[i]] = 0;
	}
	cout << res << endl;
    return FastIO::Fflush(), 0;
}
/*
tot - illegal

*/


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mkp make_pair
#define rint register int
#define INF ((1 << 30) - 1)
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Pair pair < int, int >
#define mst(a,b) memset(a,b,sizeof(a))
#define foR(i, k, j) for(rint i = (k); i >= (j); i--)
#define For(i, k, j) for(rint i = (k); i <= (j); i++)
#define Foe(i, u) for(rint i = lst[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define file(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout)
//#define int long long
const int P = 998244353; //
using namespace std;
inline void ckmax(int &a, int b) {a = max(a, b);}
inline void ckmin(int &a, int b) {a = min(a, b);}
inline void mul(int &a, int b) {a = 1ll * a * b % P;}
inline void addmod(int &a, int b) {int t = a + b; a = (t >= P ? t - P : t); }
inline int ksm(int a, int b) {int ans=1; for(;b;b>>=1) {if(b&1) ans=1ll*ans*a%P;a=1ll*a*a%P;}return ans;}
inline int inv(int a) {return ksm(a, P-2);}
inline void printarray(int *a, int n) {For(i, 1, n) fprintf(stderr, "%d ", a[i]); fprintf(stderr, "\n");}
namespace FastIO {
    const int SIZE=1<<16; char buf[SIZE], obuf[SIZE], str[64]; int bi=SIZE, bn=SIZE, opt;
    int read(char *s) {
        while (bn) {for (;bi<bn&&buf[bi]<=' ';bi++);if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}
        int sn=0;while (bn) {for (;bi<bn&&buf[bi]>' ';bi++) s[sn++]=buf[bi];if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}s[sn]=0;return sn;
    }
    bool read(int& x) {if(x)x=0;int bf=0,n=read(str); if(!n)return 0; int i=0; if (str[i]=='-') bf=1,i=1; for(x=0;i<n;i++) x=x*10+str[i]-'0'; if(bf) x=-x; return 1;}
    void write(int x) {
        if(!x) obuf[opt++] = '0'; else {if(x<0) obuf[opt++]='-',x=-x;int sn=0; while(x)str[sn++]=x%10+'0',x/=10;for (int i=sn-1;i>=0;i--) obuf[opt++]=str[i];}
        if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}
    }
    void write(char x) {obuf[opt++]=x;if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}}
    void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt=0;}
};
const int MAXN = 3e5 + 5;
const int MAXM = 25;
int n, m, l[MAXN], r[MAXN], u[MAXM], v[MAXM], s[MAXN];
int fac[MAXN], ifac[MAXN], sum[MAXN][45];

bool used[MAXN];
inline int C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

signed main()
{
	#ifndef ONLINE_JUDGE
		file("pro");
	#endif
	FI(n), FI(m);
	fac[0] = ifac[0] = 1;
	For(i, 1, n) fac[i] = 1ll * fac[i-1] * i % P;
	For(i, 1, n) ifac[i] = inv(fac[i]);
	For(i, 1, n) FI(l[i]), FI(r[i]), s[l[i]]++, s[r[i] + 1]--;
	For(i, 1, n) s[i] += s[i-1];
	For(i, 0, m - 1) FI(u[i]), FI(v[i]);
	int res = 0;

	For(i, 1, n) addmod(res, C(s[i], i));
	For(i, 1, n) For(j, 1, m * 2)
		sum[i][j] = sum[i-1][j] + C(s[i] - j, i - j);
//	cerr << "?";
	For(st, 1, (1 << m) - 1) {
//		cerr << st << endl;
		int L = -1, R = INF, o = (__builtin_popcount(st) & 1) ? -1 : 1, cnt = 0;
		For(i, 0, m - 1) {
			if((st >> i) & 1) {
				ckmax(L, l[u[i]]), ckmin(R, r[u[i]]), cnt += (!used[u[i]]), used[u[i]] = 1;
				ckmax(L, l[v[i]]), ckmin(R, r[v[i]]), cnt += (!used[v[i]]), used[v[i]] = 1;
			}
		}
		if(L <= R) addmod(res, (o * (sum[R][cnt] - sum[L - 1][cnt]) % P + P) % P);
		For(i, 0, m - 1) used[u[i]] = used[v[i]] = 0;
	}
	cout << res << endl;
    return FastIO::Fflush(), 0;
}
/*
tot - illegal

*/


#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mkp make_pair
#define rint register int
#define INF ((1 << 30) - 1)
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Pair pair < int, int >
#define mst(a,b) memset(a,b,sizeof(a))
#define foR(i, k, j) for(rint i = (k); i >= (j); i--)
#define For(i, k, j) for(rint i = (k); i <= (j); i++)
#define Foe(i, u) for(rint i = lst[u], v = e[i].v; i; i = e[i].nxt, v = e[i].v)
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define file(s) freopen(s".in", "r", stdin); freopen(s".out", "w", stdout)
//#define int long long
const int P = 998244353; //
using namespace std;
inline void ckmax(int &a, int b) {a = max(a, b);}
inline void ckmin(int &a, int b) {a = min(a, b);}
inline void mul(int &a, int b) {a = 1ll * a * b % P;}
inline void addmod(int &a, int b) {int t = a + b; a = (t >= P ? t - P : t); }
inline int ksm(int a, int b) {int ans=1; for(;b;b>>=1) {if(b&1) ans=1ll*ans*a%P;a=1ll*a*a%P;}return ans;}
inline int inv(int a) {return ksm(a, P-2);}
inline void printarray(int *a, int n) {For(i, 1, n) fprintf(stderr, "%d ", a[i]); fprintf(stderr, "\n");}
namespace FastIO {
    const int SIZE=1<<16; char buf[SIZE], obuf[SIZE], str[64]; int bi=SIZE, bn=SIZE, opt;
    int read(char *s) {
        while (bn) {for (;bi<bn&&buf[bi]<=' ';bi++);if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}
        int sn=0;while (bn) {for (;bi<bn&&buf[bi]>' ';bi++) s[sn++]=buf[bi];if (bi<bn) break; bn=fread(buf,1,SIZE,stdin),bi=0;}s[sn]=0;return sn;
    }
    bool read(int& x) {if(x)x=0;int bf=0,n=read(str); if(!n)return 0; int i=0; if (str[i]=='-') bf=1,i=1; for(x=0;i<n;i++) x=x*10+str[i]-'0'; if(bf) x=-x; return 1;}
    void write(int x) {
        if(!x) obuf[opt++] = '0'; else {if(x<0) obuf[opt++]='-',x=-x;int sn=0; while(x)str[sn++]=x%10+'0',x/=10;for (int i=sn-1;i>=0;i--) obuf[opt++]=str[i];}
        if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}
    }
    void write(char x) {obuf[opt++]=x;if (opt>=(SIZE>>1)){fwrite(obuf, 1, opt, stdout); opt=0;}}
    void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt=0;}
};
const int MAXN = 3e5 + 5;
const int MAXM = 25;
int n, m, l[MAXN], r[MAXN], u[MAXM], v[MAXM], s[MAXN];
int fac[MAXN], ifac[MAXN], sum[MAXN][45];

bool used[MAXN];
inline int C(int n, int m) {
	if(n < m || n < 0 || m < 0) return 0;
	return 1ll * fac[n] * ifac[m] % P * ifac[n - m] % P;
}

signed main()
{
	#ifndef ONLINE_JUDGE
		file("pro");
	#endif
	FI(n), FI(m);
	fac[0] = ifac[0] = 1;
	For(i, 1, n) fac[i] = 1ll * fac[i-1] * i % P;
	For(i, 1, n) ifac[i] = inv(fac[i]);
	For(i, 1, n) FI(l[i]), FI(r[i]), s[l[i]]++, s[r[i] + 1]--;
	For(i, 1, n) s[i] += s[i-1];
	For(i, 0, m - 1) FI(u[i]), FI(v[i]);
	int res = 0;

	For(i, 1, n) addmod(res, C(s[i], i));
	For(i, 1, n) For(j, 1, m * 2)
		sum[i][j] = sum[i-1][j] + C(s[i] - j, i - j);
//	cerr << "?";
	For(st, 1, (1 << m) - 1) {
//		cerr << st << endl;
		int L = -1, R = INF, o = (__builtin_popcount(st) & 1) ? -1 : 1, cnt = 0;
		For(i, 0, m - 1) {
			if((st >> i) & 1) {
				ckmax(L, l[u[i]]), ckmin(R, r[u[i]]), cnt += (!used[u[i]]), used[u[i]] = 1;
				ckmax(L, l[v[i]]), ckmin(R, r[v[i]]), cnt += (!used[v[i]]), used[v[i]] = 1;
			}
		}
		if(L <= R) addmod(res, (o * (sum[R][cnt] - sum[L - 1][cnt]) % P + P) % P);
		For(i, 0, m - 1) used[u[i]] = used[v[i]] = 0;
	}
	cout << res << endl;
    return FastIO::Fflush(), 0;
}
/*
tot - illegal

*/


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=300300,mod=998244353,inf=0x3f3f3f3f;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while('0'<=ch&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
ll power(ll base,ll b){
	ll ret=1;
	while(b){
		if(b&1)ret=ret*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ret;
}
int n,m,l[N],r[N],a[N],b[N];
ll fac[N],facinv[N];
void prework(){
	int maxn=300005;
	fac[0]=facinv[0]=1;
	for(int i=1;i<=maxn;++i)fac[i]=fac[i-1]*(ll)i%mod;
	facinv[maxn]=power(fac[maxn],mod-2);
	for(int i=maxn-1;i>=1;--i)facinv[i]=facinv[i+1]*(ll)(i+1)%mod;
}
ll C(int n,int m){
	if(n<m||n<0||m<0)return 0;//注意特殊情况
	return fac[n]*facinv[m]%mod*facinv[n-m]%mod;
}
int d[N],cnt[N];
ll sum[45][N];//sum[i][j]表示强制选i个后,1<=|S|<=j的组合数C(cnt[|S|]-i,|S|-i)前缀和
int main(){
//	freopen("t.in","r",stdin);
	prework();
	n=read(),m=read();
	for(int i=1;i<=n;++i){
		l[i]=read(),r[i]=read();
		d[l[i]]++,d[r[i]+1]--;
	}
	int num=0;
	for(int i=1;i<=n;++i){
		num+=d[i];
		cnt[i]=num;
		//差分计算|S|中包含的人数
	}
	for(int i=1;i<=m;++i)a[i]=read(),b[i]=read();
	for(int i=0;i<=40;++i){
		for(int j=1;j<=n;++j){
			sum[j][i]=(sum[j-1][i]+C(cnt[j]-i,j-i))%mod;//这句多想一下
			//枚举选i个,实际可以选cnt[j]个
		}
	}
	int S=1<<m;
	ll ans=0;
	for(int s=0;s<S;++s){
		set<int>st;//一开始是空的
		int L=1,R=n;//s=0
		for(int j=1;j<=m;++j){
			if(s&(1<<(j-1))){
				L=max(L,max(l[a[j]],l[b[j]]));
				R=min(R,min(r[a[j]],r[b[j]]));
				st.insert(a[j]);
				st.insert(b[j]);
				//重复加一个元素不报错,但set里只有一个元素
			}
		}
		if(L>R)continue;
		ll cur=(sum[R][st.size()]-sum[L-1][st.size()]+mod)%mod;
		//注意是强制选产生敌对关系的那几个人,而不一定是枚举的s的1的个数
		num=__builtin_popcount(s);
		if(num&1)ans=(ans+mod-cur)%mod;
		else ans=(ans+cur)%mod;
	}
	printf("%lld\n",(ans+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=303000,mod=998244353;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while('0'<=ch&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
ll power(ll base,ll b){
	ll ret=1;
	while(b){
		if(b&1)ret=ret*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ret;
}
int n,m,l[N],r[N],a[N],b[N];
ll fac[N],facinv[N];
void prework(){
	int maxn=300005;
	fac[0]=facinv[0]=1;
	for(int i=1;i<=maxn;++i)fac[i]=fac[i-1]*(ll)i%mod;
	facinv[maxn]=power(fac[maxn],mod-2);
	for(int i=maxn-1;i>=1;--i)facinv[i]=facinv[i+1]*(ll)(i+1)%mod;
}
ll C(int n,int m){
	if(n<m||n<0||m<0)return 0;//注意特殊情况
	return fac[n]*facinv[m]%mod*facinv[n-m]%mod;
}
int d[N],cnt[N];
ll sum[N][45];//sum[j][i]表示强制选i个后,1<=|S|<=j的组合数C(cnt[|S|]-i,|S|-i)前缀和
int main(){
//	freopen("t.in","r",stdin);
	prework();
	n=read(),m=read();
	for(int i=1;i<=n;++i){
		l[i]=read(),r[i]=read();
		d[l[i]]++,d[r[i]+1]--;
	}
	int num=0;
	for(int i=1;i<=n;++i){
		num+=d[i];
		cnt[i]=num;
		//差分计算|S|中包含的人数
	}
	for(int i=1;i<=m;++i)a[i]=read(),b[i]=read();
	for(int i=0;i<=40;++i){
		for(int j=1;j<=n;++j){
			sum[j][i]=(sum[j-1][i]+C(cnt[j]-i,j-i))%mod;//这句多想一下
			//枚举选i个,实际可以选cnt[j]个
		}
	}
	int S=1<<m;
	ll ans=0;
	for(int s=0;s<S;++s){
		set<int>st;//一开始是空的
		int L=1,R=n;//s=0
		for(int j=1;j<=m;++j){
			if(s&(1<<(j-1))){
				L=max(L,max(l[a[j]],l[b[j]]));
				R=min(R,min(r[a[j]],r[b[j]]));
				st.insert(a[j]);
				st.insert(b[j]);
				//重复加一个元素不报错,但set里只有一个元素
			}
		}
		if(L>R)continue;
		ll cur=(sum[R][st.size()]-sum[L-1][st.size()]+mod)%mod;
		//注意是强制选产生敌对关系的那几个人,而不一定是枚举的s的1的个数
		num=__builtin_popcount(s);
		if(num&1)ans=(ans+mod-cur)%mod;
		else ans=(ans+cur)%mod;
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <functional>
#include <set>

template<typename T> bool ckmax(T& a, const T& b) {return a<b?a=b,1:0;}
template<typename T> bool ckmin(T& a, const T& b) {return b<a?a=b,1:0;}

using ll = long long;

const int MOD = 998244353;

struct mint
{
	public:
		int v;
		mint(int _v=0):v(_v){}

		explicit operator int() const {return v;}

		mint& operator += (const mint& o) {if((v+=o.v)>=MOD) v-=MOD; return *this;}
		mint& operator -= (const mint& o) {if((v-=o.v)<0) v+=MOD; return *this;}
		mint& operator *= (const mint& o) {return v=(ll)v*o.v%MOD, *this;}

		friend mint operator + (mint a, const mint& b) {return a+=b;}
		friend mint operator - (mint a, const mint& b) {return a-=b;}
		friend mint operator * (mint a, const mint& b) {return a*=b;}
};

const int MN = 3e5+10;
const int MM = 22;

int N, M, l[MN], r[MN], a[MN], b[MN], p[MN], min, max;
mint v[MN][MM*2], fact[2][MN], inv[MN], f;
std::set<int> ctr;

mint choose(int n, int k)
{
	if(k < 0 || n < k) return mint(0);
	return fact[0][n]*fact[1][k]*fact[1][n-k];
}

int main()
{
	inv[0]=0, inv[1]=1;
	fact[0][0]=fact[1][0]=fact[0][1]=fact[1][1]=1;
	for(int i=2;i<MN;++i)
	{
		inv[i]=inv[MOD%i]*mint(MOD-MOD/i);
		fact[0][i]=fact[0][i-1]*mint(i);
		fact[1][i]=fact[1][i-1]*inv[i];
	}
	scanf("%d%d", &N, &M);
	for(int i=0;i<N;++i) scanf("%d%d", l+i, r+i), --l[i], ++p[l[i]], --p[r[i]];
	for(int i=0;i<M;++i) scanf("%d%d", a+i, b+i), --a[i], --b[i];
	for(int i=0,c=0;i<N;++i)
	{
		c+=p[i];
		memcpy(v[i+1], v[i], sizeof*v);
		if(i+1<=c)
			for(int j=0;j<MM*2 && j<=i+1;++j)
				v[i+1][j]+=choose(c-j, i+1-j);
	}
	for(int i=0;i<1<<M;++i)
	{
		min=0, max=N;
		auto add=[&](int x)
		{
			ckmax(min, l[x]);
			ckmin(max, r[x]);
			ctr.insert(x);
		};
		int w=1;
		for(int j=0;j<M;++j)
			if(i>>j&1)
			{
				add(a[j]);
				add(b[j]);
				w*=-1;
			}
		int cnt=ctr.size();
		//printf("%d %d %d\n", cnt, min, max);
		if(max>min)
		{
			if(w>0)
				f += v[max][cnt]-v[min][cnt];
			else
				f -= v[max][cnt]-v[min][cnt];
		}
		ctr.clear();
	}
	printf("%d\n", f);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int,int>::iterator
#define sit set<int>::iterator
#define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
#define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
#define ltype int
#define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
#define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
#define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
#define pii pair<int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf=0x3f3f3f3f,mod=998244353;
const double pi=3.1415926535897932,eps=1e-6;
void chmax(int &x,int y){if(x < y) x = y;}
void chmin(int &x,int y){if(x > y) x = y;}
int n,m;
int l[300005],r[300005];
int st[300005],ed[300005];
int fac[300005],inv[300005];
int ans;
int qpow(int x,int y){
    int res = 1;
    while(y) {
        if(y & 1) res = (ll)res * x % mod;
        x = (ll)x * x % mod;
        y >>= 1;
    }
    return res;
}
int C(int x,int y){
    if(x < y || x < 0 || y < 0) return 0;
    return (ll)fac[x] * inv[y] % mod * inv[x - y] % mod;
}
int u[25],v[25],rel[45];
map<int,int> mp;int cnt;
int max_l,min_r;
bool cover[45];
int pre[300005][45];

int dif[45];
int main()
{
    fac[0] = 1;
    rep(i,1,300000) fac[i] = (ll)fac[i - 1] * i % mod;
    inv[300000] = qpow(fac[300000], mod - 2);
    per(i,299999,0) inv[i] = (ll)inv[i + 1] * (i + 1) % mod;
    scanf("%d%d",&n,&m);
    rep(i,1,n) scanf("%d%d",l+i,r+i);
    rap(i,0,m) {scanf("%d%d",u+i,v+i);mp[u[i]] = mp[v[i]] = 0;}
    itrm(it,mp) {it->se = ++cnt;rel[cnt] = it->fi;}
    rap(i,0,m) u[i] = mp[u[i]], v[i] = mp[v[i]];

    rep(i,1,n) st[l[i]]++, ed[r[i]+1]++;
    int cur = 0;
    rep(i,1,n) {
        cur += st[i];
        cur -= ed[i];
        //ans += C(cur, i);
        //if(ans >= mod) ans -= mod;
        rep(j,0,cnt) pre[i][j] = C(cur - j,i - j);
    }
    rep(i,1,n) rep(j,0,cnt) {pre[i][j] += pre[i-1][j];if(pre[i][j] >= mod) pre[i][j] -= mod;}

    rap(i,0,1<<m){
        //reset
        min_r = n;max_l = 1;
        rep(j,1,cnt) cover[j] = 0;
        //unite
        rap(j,0,m) if(i & (1<<j)) {
            cover[u[j]] = 1;
            cover[v[j]] = 1;
        }
        int tot = 0;
        rep(j,1,cnt) {
            tot += cover[j];
            if(cover[j]) {
                chmax(max_l, l[rel[j]]);
                chmin(min_r, r[rel[j]]);
            }
        }
        if(min_r < max_l) continue;
        if(__builtin_popcount(i) & 1) {
            ans = ((ll)ans - pre[min_r][tot] + pre[max_l - 1][tot] + mod) % mod;
        }
        else {
            ans = ((ll)ans + pre[min_r][tot] - pre[max_l - 1][tot] + mod) % mod;
        }
    }
    printf("%d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int,int>::iterator
#define sit set<int>::iterator
#define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
#define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
#define ltype int
#define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
#define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
#define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
#define pii pair<int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf=0x3f3f3f3f,mod=998244353;
const double pi=3.1415926535897932,eps=1e-6;
void chmax(int &x,int y){if(x < y) x = y;}
void chmin(int &x,int y){if(x > y) x = y;}
int n,m;
int l[300005],r[300005];
int st[300005],ed[300005];
int fac[300005],inv[300005];
int ans;
int qpow(int x,int y){
    int res = 1;
    while(y) {
        if(y & 1) res = (ll)res * x % mod;
        x = (ll)x * x % mod;
        y >>= 1;
    }
    return res;
}
int C(int x,int y){
    if(x < y || x < 0 || y < 0) return 0;
    return (ll)fac[x] * inv[y] % mod * inv[x - y] % mod;
}
int u[25],v[25],rel[45];
map<int,int> mp;int cnt;
int max_l,min_r;
bool cover[45];
int pre[100005][45];

int dif[45];
int main()
{
    fac[0] = 1;
    rep(i,1,300000) fac[i] = (ll)fac[i - 1] * i % mod;
    inv[300000] = qpow(fac[300000], mod - 2);
    per(i,299999,0) inv[i] = (ll)inv[i + 1] * (i + 1) % mod;
    scanf("%d%d",&n,&m);
    rep(i,1,n) scanf("%d%d",l+i,r+i);
    rap(i,0,m) {scanf("%d%d",u+i,v+i);mp[u[i]] = mp[v[i]] = 0;}
    itrm(it,mp) {it->se = ++cnt;rel[cnt] = it->fi;}
    rap(i,0,m) u[i] = mp[u[i]], v[i] = mp[v[i]];

    rep(i,1,n) st[l[i]]++, ed[r[i]+1]++;
    int cur = 0;
    rep(i,1,n) {
        cur += st[i];
        cur -= ed[i];
        //ans += C(cur, i);
        //if(ans >= mod) ans -= mod;
        rep(j,0,cnt) pre[i][j] = C(cur - j,i - j);
    }
    rep(i,1,n) rep(j,0,cnt) {pre[i][j] += pre[i-1][j];if(pre[i][j] >= mod) pre[i][j] -= mod;}

    rap(i,0,1<<m){
        //reset
        min_r = n;max_l = 1;
        rep(j,1,cnt) cover[j] = 0;
        //unite
        rap(j,0,m) if(i & (1<<j)) {
            cover[u[j]] = 1;
            cover[v[j]] = 1;
        }
        int tot = 0;
        rep(j,1,cnt) {
            tot += cover[j];
            if(cover[j]) {
                chmax(max_l, l[rel[j]]);
                chmin(min_r, r[rel[j]]);
            }
        }
        if(min_r < max_l) continue;
        if(__builtin_popcount(i) & 1) {
            ans = ((ll)ans - pre[min_r][tot] + pre[max_l - 1][tot] + mod) % mod;
        }
        else {
            ans = ((ll)ans + pre[min_r][tot] - pre[max_l - 1][tot] + mod) % mod;
        }
    }
    printf("%d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define int long long
#define N 300015
#define mod 998244353
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define lowbit(i) ((i)&(-i))
#define VI vector<int>
using namespace std;
int n,m,inv[N],fac[N],a[25],b[25],dp[45][N],l[N],r[N],d[N];
bool vis[N];
int qpow(int a,int b){
	int res = 1;
	while(b){
		if(b&1) res = (res*a)%mod;
		a = a*a%mod;
		b>>=1;
	}
	return res%mod;
}
int C(int n,int m){
	if(n<0||m<0||n>m) return 0;
	return (fac[m]%mod*inv[n]%mod)*inv[m-n]%mod;
}
signed main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
 	cin>>n>>m;
 	fac[0] = inv[0] = 1;
 	rep(i,1,n) fac[i] = fac[i-1]*i%mod;
 	rep(i,1,n) inv[i] = qpow(fac[i],mod-2);
 	rep(i,1,n){
 		cin>>l[i]>>r[i];
 		d[l[i]]++,d[r[i]+1]--;
 	}
 	rep(i,1,m) cin>>a[i]>>b[i];
 	rep(i,1,n) d[i] += d[i-1];
 	rep(i,1,n){
 		rep(j,0,m*2){
 			dp[j][i] = (dp[j][i-1] + C(i-j,d[i]-j))%mod;
 		}
 	}
 	set<int> S;
 	int top = (1<<m)-1;
 	int ans = 0;
 	rep(i,0,top){
 		S.clear();
 		int le = 1,ri = n;
 		rep(j,1,m){
 			if((1<<(j-1))&i){
 				S.insert(a[i]);S.insert(b[i]);
 				le = max({le,l[a[i]],l[b[i]]});
 				ri = min({ri,r[a[i]],r[b[i]]});
 			}
 		}
 		int sum = S.size(),res = (le <= ri)?(dp[sum][ri]-dp[sum][le-1]+mod)%mod:0;
 		if(__builtin_popcount(i) & 1) ans = (ans-res+mod)%mod;
 		else ans = (ans+res)%mod;
 	}
 	cout << ans << endl;
	return 0;
}


#include<bits/stdc++.h>
#define int long long
#define N 300015
#define mod 998244353
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define lowbit(i) ((i)&(-i))
#define VI vector<int>
using namespace std;
int n,m,inv[N],fac[N],a[25],b[25],dp[45][N],l[N],r[N],d[N];
bool vis[N];
int qpow(int a,int b){
	int res = 1;
	while(b){
		if(b&1) res = (res*a)%mod;
		a = a*a%mod;
		b>>=1;
	}
	return res%mod;
}
int C(int n,int m){
	if(n<0||m<0||n>m) return 0;
	return (fac[m]%mod*inv[n]%mod)*inv[m-n]%mod;
}
signed main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
 	cin>>n>>m;
 	fac[0] = inv[0] = 1;
 	rep(i,1,n) fac[i] = fac[i-1]*i%mod;
 	rep(i,1,n) inv[i] = qpow(fac[i],mod-2);
 	rep(i,1,n){
 		cin>>l[i]>>r[i];
 		d[l[i]]++,d[r[i]+1]--;
 	}
 	rep(i,1,m) cin>>a[i]>>b[i];
 	rep(i,1,n) d[i] += d[i-1];
 	rep(i,1,n){
 		rep(j,0,m*2){
 			dp[j][i] = (dp[j][i-1] + C(i-j,d[i]-j))%mod;
 		}
 	}
 	set<int> S;
 	int top = (1<<m)-1;
 	int ans = 0;
 	rep(i,0,top){
 		S.clear();
 		int le = 1,ri = n;
 		rep(j,1,m){
 			if((1<<(j-1))&i){
 				S.insert(a[j]);S.insert(b[j]);
 				le = max({le,l[a[j]],l[b[j]]});
 				ri = min({ri,r[a[j]],r[b[j]]});
 			}
 		}
 		int sum = S.size(),res = (le <= ri)?(dp[sum][ri]-dp[sum][le-1]+mod)%mod:0;
 		if(__builtin_popcount(i) & 1) ans = (ans-res+mod)%mod;
 		else ans = (ans+res)%mod;
 	}
 	cout << ans << endl;
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

typedef long long LL;

const int N = 300005, P = 998244353, S = 21;

int n, m, L[N], R[N], a[N], b[N], g[1 << S][S + 1], c[N], d[N], e[N];
int fact[N], infact[N], f[N][S * 2], tot, fa[N], sz[N], Log[1 << S], now[N], ans;

bool vis[N], ins[N];
vector<int> col[N];

int inline power(int a, int b) {
	int res = 1;
	while (b) {
		if (b & 1) res = (LL)res * a % P;
		a = (LL)a * a % P;
		b >>= 1;
	}
	return res;
}

int inline C(int a, int b) {
	if (a < b || a < 0 || b < 0) return 0;
	return (LL)fact[a] * infact[b] % P * infact[a - b] % P;
}

int find(int x) {
	return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int main() {
	scanf("%d%d", &n, &m);

	fact[0] = infact[0] = 1;
	for (int i = 1; i <= n; i++)
		fact[i] = (LL)fact[i - 1] * i % P;
	infact[n] = power(fact[n], P - 2);
	for (int i = n - 1; i; i--)
		infact[i] = (LL)infact[i + 1] * (i + 1) % P;

	for (int i = 0; i <= 20; i++) Log[1 << i] = i;
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", L + i, R + i);
		f[i][0] = 1, fa[i] = i, sz[i] = 1;
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", a + i, b + i);
		fa[find(a[i])] = find(b[i]);
		ins[a[i]] = ins[b[i]] = true;
	}
	for (int i = 1; i <= n; i++) {
		if (!ins[i]) c[L[i]]++, c[R[i] + 1]--;
	}
	for (int i = 1; i <= n; i++) col[find(i)].push_back(i), c[i] += c[i - 1];
	for (int t = 1; t <= n; t++) {
		if (find(t) != t || col[t].size() == 1) continue;
		int k = col[t].size();
		for (int i = 1; i < (1 << k); i++)
			for (int j = 0; j <= k; j++) g[i][j] = 0;
		for (int i = 1; i < (1 << k); i++) {
			bool ok = true; int cnt = 0;
			for (int j = 0; j < k; j++)
				if (i >> j & 1) vis[col[t][j]] = true, cnt++;
			for (int j = 1; j <= m; j++)
				if (vis[a[j]] && vis[b[j]]) { ok = false; break; }
			for (int j = 0; j < k; j++)
				if (i >> j & 1) vis[col[t][j]] = false;
			if (ok) g[i][cnt] = 1;
		}
		for (int v = 0; v < k; v++) {
			for (int i = 1; i + 1 < (1 << k); i++) {
				for (int j = 1; j <= k; j++) {
					if (!g[i][j] || i >> v & 1) continue;
					(g[i + (1 << v)][j] += g[i][j]) %= P;
				}
			}
		}
		for (int i = 1; i <= n; i++) d[i] = 0, e[i] = 0;
		for (int i = 0; i < k; i++) {
			d[L[col[t][i]]] += 1 << i, d[R[col[t][i]] + 1] -= 1 << i;
			e[L[col[t][i]]] ++, e[R[col[t][i]] + 1]--;
		}
		for (int i = 1; i <= n; i++) {
			d[i] += d[i - 1], e[i] += e[i - 1];
			now[i] += e[i];
			for (int j = now[i]; j; j--) {
				for (int v = 1; v <= min(j, e[i]); v++) {
					if (!f[i][j - v] || !g[d[i]][v]) continue;
					f[i][j] = (f[i][j] + (LL)f[i][j - v] * g[d[i]][v]) % P;
				}
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= now[i]; j++) {
			ans = (ans + (LL)f[i][j] * C(c[i], i - j)) % P;
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

typedef long long LL;

const int N = 300005, P = 998244353, S = 21;

int n, m, L[N], R[N], a[N], b[N], g[1 << S][S + 1], c[N], d[N], e[N];
int fact[N], infact[N], f[N][S * 2], tot, fa[N], sz[N], Log[1 << S], now[N], ans;

bool vis[N], ins[N];
vector<int> col[N];

int inline power(int a, int b) {
	int res = 1;
	while (b) {
		if (b & 1) res = (LL)res * a % P;
		a = (LL)a * a % P;
		b >>= 1;
	}
	return res;
}

int inline C(int a, int b) {
	if (a < b || a < 0 || b < 0) return 0;
	return (LL)fact[a] * infact[b] % P * infact[a - b] % P;
}

int find(int x) {
	return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int main() {
	scanf("%d%d", &n, &m);

	fact[0] = infact[0] = 1;
	for (int i = 1; i <= n; i++)
		fact[i] = (LL)fact[i - 1] * i % P;
	infact[n] = power(fact[n], P - 2);
	for (int i = n - 1; i; i--)
		infact[i] = (LL)infact[i + 1] * (i + 1) % P;

	for (int i = 0; i <= 20; i++) Log[1 << i] = i;
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", L + i, R + i);
		f[i][0] = 1, fa[i] = i, sz[i] = 1;
	}
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", a + i, b + i);
		fa[find(a[i])] = find(b[i]);
		ins[a[i]] = ins[b[i]] = true;
	}
	for (int i = 1; i <= n; i++) {
		if (!ins[i]) c[L[i]]++, c[R[i] + 1]--;
	}
	for (int i = 1; i <= n; i++) col[find(i)].push_back(i), c[i] += c[i - 1];
	for (int t = 1; t <= n; t++) {
		if (find(t) != t || col[t].size() == 1) continue;
		int k = col[t].size();
		for (int i = 1; i < (1 << k); i++)
			for (int j = 0; j <= k; j++) g[i][j] = 0;
		for (int i = 1; i < (1 << k); i++) {
			bool ok = true; int cnt = 0;
			for (int j = 0; j < k; j++)
				if (i >> j & 1) vis[col[t][j]] = true, cnt++;
			for (int j = 1; j <= m; j++)
				if (vis[a[j]] && vis[b[j]]) { ok = false; break; }
			for (int j = 0; j < k; j++)
				if (i >> j & 1) vis[col[t][j]] = false;
			if (ok) g[i][cnt] = 1;
		}
		for (int i = 1; i + 1 < (1 << k); i++) {
			for (int j = 1; j <= k; j++) {
				if (!g[i][j]) continue;
				int w = Log[(~i) & -(~i)];
				(g[i + (1 << w)][j] += g[i][j]) %= P;
			}
		}
		for (int i = 1; i <= n; i++) d[i] = 0;
		for (int i = 0; i < k; i++) {
			d[L[col[t][i]]] += 1 << i, d[R[col[t][i]] + 1] -= 1 << i;
			e[L[col[t][i]]] ++, e[R[col[t][i]] + 1]--;
		}
		for (int i = 1; i <= n; i++) {
			d[i] += d[i - 1], e[i] += e[i - 1];
			int maxS = now[i];
			for (int j = 0; j <= now[i]; j++) {
				for (int v = 1; v <= min(n - j, e[i]); v++) {
					if (!f[i][j] || !g[d[i]][v]) continue;
					f[i][j + v] = (f[i][j + v] + (LL)f[i][j] * g[d[i]][v]) % P;
					maxS = max(maxS, j + v);
				}
			}
			now[i] = maxS;
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= now[i]; j++) {
			ans = (ans + (LL)f[i][j] * C(c[i], i - j)) % P;
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(auto i=(a); i < (b); ++i)
#define pb push_back
#define fs first
#define sc second
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ii> vii;
typedef vector<vii> vvii;

const double EPS = 1e-9;

int mod = 998244353;

struct unionfind { vi p; int c;
  unionfind(int n) : p(n, -1), c(n) { }
  int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); }
  bool united(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) { int a = find(x), b = find(y);
    if(a == b) return; if(p[a] > p[b]) swap(a, b);
    p[a] += p[b]; p[b] = a; c--; return; }
  int size(int x) { return -p[find(x)]; } };

template <class T>
T mod_pow(T b, T e, T m) {
  T res = T(1);
  while (e) {
    if (e & T(1)) res = (res*b%m+m)%m;
    b = b*b%m, e >>= T(1); }
  return res; }

ll egcd(ll a, ll b, ll& x, ll& y) {
  if (b == 0) { x = 1; y = 0; return a; }
  ll d = egcd(b, a % b, x, y);
  x -= a / b * y; swap(x, y); return d; }

ll mod_inv(ll a, ll m) {
  ll x, y, d = egcd(a, m, x, y);
  return d == 1 ? (x%m+m)%m : -1; }

vector<ll> subs(set<int>& active, set<ii> &e) {
    if(active.empty()) {
        vector<ll> res(50, 0);
        res[0] = 1;
        return res;
    }
    map<int,int> ind;
    for(int x : active) {
        if(ind.find(x) == ind.end()) {
            int y = ind.size();
            ind[x] = y;
        }
    }
    int n = ind.size();
    unionfind uf(n);
    vii nwe;
    for(ii p : e) {
        if(ind.find(p.fs) == ind.end()) continue;
        if(ind.find(p.sc) == ind.end()) continue;
        nwe.pb(ii(ind[p.fs], ind[p.sc]));
        uf.unite(ind[p.fs], ind[p.sc]);
    }
    if(uf.c != 1) {
        set<int> p1, p2;
        for(int x : active) {
            if(uf.united(ind[x], 0)) p1.insert(x);
            else p2.insert(x);
        }
        vector<ll> res1 = subs(p1, e), res2 = subs(p2, e), res(50, 0);
        rep(i,0,50) {
            rep(j,0,i+1) {
                res[i] += res1[j] * res2[i - j] % mod;
            }
            res[i] %= mod;
        }
        return res;
    }
    vector<ll> res(50, 0);
    rep(i,0,1<<n) {
        bool valid = true;
        for(ii p : nwe) {
            if((i & (1 << p.fs)) && (i & (1 << p.sc))) valid = false;
        }
        if(!valid) continue;
        res[__builtin_popcount(i)]++;
    }
    return res;
}

vector<ll> nfact;

void factcalc(int n) {
    nfact.resize(n + 1);
    nfact[0] = 1;
    rep(i,1,n+1) {
        nfact[i] = (i * nfact[i - 1]) % mod;
    }
}

ll nck(ll n, ll k) {
    if(k < 0 || k > n) return 0;
    ll res = nfact[n];
    res *= mod_inv(nfact[k], mod);
    res %= mod;
    res *= mod_inv(nfact[n - k], mod);
    res %= mod;
    return res;
}

int main() {
    cin.sync_with_stdio(false);
    int n, m, li, ri, ai, bi;
    cin >> n >> m;
    factcalc(n);
    set<int> ingraph;
    priority_queue<ii> l, r;
    rep(i,0,n) {
        cin >> li >> ri;
        l.push(ii(-li, i));
        r.push(ii(-ri, i));
    }
    set<ii> e;
    rep(i,0,m) {
        cin >> ai >> bi;
        ai--; bi--;
        ingraph.insert(ai);
        ingraph.insert(bi);
        e.insert(ii(ai, bi));
    }
    ll res = 0, nographcnt = 0;
    set<int> graphin;
    vector<ll> graphsol = subs(graphin, e);
    rep(i,1,n+1) {
        bool recalc = false;
        // subs of size i
        while(!l.empty() && -l.top().fs <= i) {
            if(ingraph.count(l.top().sc)) graphin.insert(l.top().sc), recalc = true;
            else nographcnt++;
            l.pop();
        }
        while(!r.empty() && -r.top().fs < i) {
            if(ingraph.count(r.top().sc)) graphin.erase(r.top().sc), recalc = true;
            else nographcnt--;
            r.pop();
        }
        if(recalc) {
            graphsol = subs(graphin, e);
        }
        rep(j,0,graphin.size()+1) {
            // j of the i are in graph
            res += (graphsol[j] * nck(nographcnt, i - j)) % mod;
            res %= mod;
        }
    }
    cout << res << '\n';
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 1e9 + 7;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N], c[N];
LL ans, fac[N], inv[N], sum[N][40];
bool vis[N];

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < 0 || k < 0 || n < k) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
		cin>>l[i]>>r[i];
		c[l[i]]++;
		c[r[i] + 1]--;
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) c[i] += c[i - 1];
	rep(i, 1, n)
	    rep(j, 0, 40) sum[i][j] = (sum[i - 1][j] + cal(c[i] - j, i - j))%mod;
	rep(i, 0, m - 1) cin>>a[i]>>b[i];
	for(int s = 0; s < (1<<m); s++) {
		int tot = 0, f = 1, L = 1, R = n;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) {
		    	f *= -1;
		    	if(!vis[a[i]]) tot++, vis[a[i]] = 1;
		    	if(!vis[b[i]]) tot++, vis[b[i]] = 1;
		    	L = max(L, max(l[a[i]], l[b[i]]));
		    	R = min(R, min(r[a[i]], r[b[i]]));
		    }
		if(L <= R) ans = (ans + 1ll*f*(sum[R][tot] - sum[L - 1][tot]))%mod;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) vis[a[i]] = vis[b[i]] = 0;
	}
	cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][40];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(min(n, k) < 0 || n < k) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

map <int, int> M;

int work(int s) {
	M.clear();
	int ans = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) {
	    	if(!M[a[i + 1]]) ans++, M[a[i + 1]] = 1;
	    	if(!M[b[i + 1]]) ans++, M[b[i + 1]] = 1;
	    }
	return ans;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, 40)
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 1, m)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = work(i);
		per(j, 27, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j + 1]], r[a[j + 1]]});
		    	merge(p[i], (node) {l[b[j + 1]], r[b[j + 1]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz])%mod)%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][40];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < k || min(n, k) < 0) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

map <int, int> M;

int work(int s) {
	M.clear();
	int ans = 0;
	rep(i, 0, m)
	    if(s&(1<<i)) {
	    	if(!M[a[i]]) ans++, M[a[i]] = 1;
	    	if(!M[b[i]]) ans++, M[b[i]] = 1;
	    }
	return ans;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, query(1, 1, n, i))
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 0, m - 1)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = work(i);
		per(j, m - 1, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j]], r[a[j]]});
		    	merge(p[i], (node) {l[b[j]], r[b[j]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz])%mod)%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][40];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < k || min(n, k) < 0) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

map <int, int> M;

int work(int s) {
	M.clear();
	int ans = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) {
	    	if(!M[a[i + 1]]) ans++, M[a[i + 1]] = 1;
	    	if(!M[b[i + 1]]) ans++, M[b[i + 1]] = 1;
	    }
	return ans;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, 40)
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 1, m)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = work(i);
		per(j, 27, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j + 1]], r[a[j + 1]]});
		    	merge(p[i], (node) {l[b[j + 1]], r[b[j + 1]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz])%mod)%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][40];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < k) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, 40)
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 1, m)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = get(i);
		per(j, 27, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j + 1]], r[a[j + 1]]});
		    	merge(p[i], (node) {l[b[j + 1]], r[b[j + 1]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz]))%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][40];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < k || min(n, k) < 0) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, 40)
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 1, m)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = get(i);
		per(j, 27, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j + 1]], r[a[j + 1]]});
		    	merge(p[i], (node) {l[b[j + 1]], r[b[j + 1]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz])%mod)%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N], c[N];
LL ans, fac[N], inv[N], sum[N][41];
bool vis[N];

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < 0 || k < 0 || n < k) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
		cin>>l[i]>>r[i];
		c[l[i]]++;
		c[r[i] + 1]--;
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) c[i] += c[i - 1];
	rep(i, 1, n)
	    rep(j, 0, 40) sum[i][j] = (sum[i - 1][j] + cal(c[i] - j, i - j))%mod;
	rep(i, 0, m - 1) cin>>a[i]>>b[i];
	for(int s = 0; s < (1<<m); s++) {
		int tot = 0, f = 1, L = 1, R = n;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) {
		    	f *= -1;
		    	if(!vis[a[i]]) tot++, vis[a[i]] = 1;
		    	if(!vis[b[i]]) tot++, vis[b[i]] = 1;
		    	L = max(L, max(l[a[i]], l[b[i]]));
		    	R = min(R, min(r[a[i]], r[b[i]]));
		    }
		if(L <= R) ans = (ans + 1ll*f*(sum[R][tot] - sum[L - 1][tot]))%mod;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) vis[a[i]] = vis[b[i]] = 0;
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 1e9 + 7;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N], c[N];
LL ans, fac[N], inv[N], sum[N][41];
bool vis[N];

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < 0 || k < 0 || n < k) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
		cin>>l[i]>>r[i];
		c[l[i]]++;
		c[r[i] + 1]--;
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) c[i] += c[i - 1];
	rep(i, 1, n)
	    rep(j, 0, 40) sum[i][j] = (sum[i - 1][j] + cal(c[i] - j, i - j))%mod;
	rep(i, 0, m - 1) cin>>a[i]>>b[i];
	for(int s = 0; s < (1<<m); s++) {
		int tot = 0, f = 1, L = 1, R = n;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) {
		    	f *= -1;
		    	if(!vis[a[i]]) tot++, vis[a[i]] = 1;
		    	if(!vis[b[i]]) tot++, vis[b[i]] = 1;
		    	L = max(L, max(l[a[i]], l[b[i]]));
		    	R = min(R, min(r[a[i]], r[b[i]]));
		    }
		if(L <= R) ans = (ans + 1ll*f*(sum[R][tot] - sum[L - 1][tot]))%mod;
		rep(i, 0, m - 1)
		    if(s&(1<<i)) vis[a[i]] = vis[b[i]] = 0;
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
typedef long long LL;
const LL mod = 998244353;
const int N = 3e5 + 5;

int n, m, l[N], r[N], a[N], b[N];
LL ans, fac[N], inv[N], sum[N][41];
struct Seg {
	int val, tag;
} t[N<<2];

void push_down(int o, int l, int r) {
	int ls = o<<1, rs = o<<1|1;
	t[ls].tag += t[o].tag, t[rs].tag += t[o].tag;
	int mid = (l + r)>>1;
	t[ls].val += (mid - l + 1)*t[o].tag;
	t[rs].val += (r - mid)*t[o].tag;
	t[o].tag = 0;
}

int query(int o, int l, int r, int x) {
	if(l == r) return t[o].val;
	int mid = (l + r)>>1;
	push_down(o, l, r);
	if(x <= mid) return query(o<<1, l, mid, x);
	else return query(o<<1|1, mid + 1, r, x);
}

void update(int o, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[o].val += (r - l + 1)*k;
		t[o].tag += k;
		return;
	}
	push_down(o, l, r);
	int mid = (l + r)>>1;
	if(x <= mid) update(o<<1, l, mid, x, y, k);
	if(mid < y) update(o<<1|1, mid + 1, r, x, y, k);
	t[o].val = t[o<<1].val + t[o<<1|1].val;
}

LL Ksm(LL a, LL b) {
	LL res = 1;
	while(b) {
		if(b&1) res = res*a%mod;
		b /= 2;
		a = a*a%mod;
	}
	return res;
}

LL cal(int n, int k) {
	if(n < k || min(n, k) < 0) return 0;
	return fac[n]*inv[k]%mod*inv[n - k]%mod;
}

int get(int s) {
	int f = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) f++;
	return f;
}

map <int, int> M;

int work(int s) {
	M.clear();
	int ans = 0;
	rep(i, 0, 27)
	    if(s&(1<<i)) {
	    	if(!M[a[i + 1]]) ans++, M[a[i + 1]] = 1;
	    	if(!M[b[i + 1]]) ans++, M[b[i + 1]] = 1;
	    }
	return ans;
}

struct node {
	int l, r;
} p[1<<21];

void merge(node &a, node b) {
	a.l = max(a.l, b.l);
	a.r = min(a.r, b.r);
}

int main() {
	cin>>n>>m;
	rep(i, 1, n) {
	    cin>>l[i]>>r[i];
	    update(1, 1, n, l[i], r[i], 1);
	}
	fac[0] = inv[0] = 1;
	rep(i, 1, n)
	    fac[i] = fac[i - 1]*i%mod, inv[i] = Ksm(fac[i], mod - 2);
	rep(i, 1, n) {
	    ans = (ans + cal(query(1, 1, n, i), i))%mod;
	    rep(j, 0, 40)
	        sum[i][j] = (sum[i - 1][j] + cal(query(1, 1, n, i) - j, i - j))%mod;
	}
	rep(i, 1, m)
	    cin>>a[i]>>b[i];
	int S = (1<<m) - 1;
	p[0].l = 1, p[0].r = n;
	rep(i, 1, S) {
		int f = get(i)&1 ? -1:1;
		int siz = work(i);
		per(j, 27, 0)
		    if(i&(1<<j)) {
		    	int t = i^(1<<j);
		    	p[i] = p[t];
		    	merge(p[i], (node) {l[a[j + 1]], r[a[j + 1]]});
		    	merge(p[i], (node) {l[b[j + 1]], r[b[j + 1]]});
		    	if(p[i].l > p[i].r) break;
		    	ans = (ans + 1ll*f*(sum[p[i].r][siz] - sum[p[i].l - 1][siz])%mod)%mod;
		    	break;
		    }
	}
	cout<<(ans + mod)%mod<<endl;
}


#include <cstdio>
void read(int &a){
	a=0;
	char c=getchar();
	while(c<'0'||c>'9'){
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		a=(a<<1)+(a<<3)+(c^48);
		c=getchar();
	}
}
int quick_power(int a,int b,int Mod){
	int ans=1;
	while(b){
		if(b&1){
			ans=1ll*ans*a%Mod;
		}
		b>>=1;
		a=1ll*a*a%Mod;
	}
	return ans;
}
const int Maxn=300000;
const int Maxm=20;
const int Mod=998244353;
int frac[Maxn+5],inv_f[Maxn+5];
void init(){
	frac[0]=1;
	for(int i=1;i<=Maxn;i++){
		frac[i]=1ll*frac[i-1]*i%Mod;
	}
	inv_f[Maxn]=quick_power(frac[Maxn],Mod-2,Mod);
	for(int i=Maxn-1;i>=0;i--){
		inv_f[i]=1ll*inv_f[i+1]*(i+1)%Mod;
	}
}
int C(int n,int m){
	if(n<m){
		return 0;
	}
	if(m<0){
		return 0;
	}
	return 1ll*frac[n]*inv_f[m]%Mod*inv_f[n-m]%Mod;
}
int l[Maxn+5],r[Maxn+5];
bool vis[Maxn+5];
int n,m;
int a[Maxm+5],b[Maxm+5];
int f[1<<Maxm|5][Maxm+5];
int lis[Maxm<<1|5],len;
bool in[Maxn+5],out[Maxn+5];
int deg[Maxn+5];
int head[Maxn+5],arrive[Maxn+5],nxt[Maxn+5],val[Maxn+5],tot;
int sum[Maxn+5];
void add_edge(int from,int to,int w){
	arrive[++tot]=to;
	nxt[tot]=head[from];
	val[tot]=w;
	head[from]=tot;
}
bool build_graph(int mask){
	len=0;
	for(int i=1;i<=m;i++){
		if((mask>>(i-1))&1){
			if(!in[a[i]]){
				in[a[i]]=1;
				lis[++len]=a[i];
			}
			if(!in[b[i]]){
				in[b[i]]=1;
				lis[++len]=b[i];
			}
		}
	}
	tot=0;
	for(int i=1;i<=len;i++){
		head[lis[i]]=0;
		deg[lis[i]]=0;
	}
	for(int i=1;i<=m;i++){
		if(in[a[i]]&&in[b[i]]&&(mask>>(i-1)&1)==0){
			return 0;
		}
	}
	for(int i=1;i<=m;i++){
		if((mask>>(i-1))&1){
			deg[a[i]]++;
			deg[b[i]]++;
			add_edge(a[i],b[i],i);
			add_edge(b[i],a[i],i);
		}
	}
	return 1;
}
void connect_dfs(int u,int &mask){
	for(int i=head[u];i;i=nxt[i]){
		if(((1<<(val[i]-1))&mask)>0){
			continue;
		}
		mask|=(1<<(val[i]-1));
		int v=arrive[i];
		connect_dfs(v,mask);
	}
}
int calc(int mask){
	for(int i=1;i<=m;i++){
		if((mask>>(i-1))&1){
			out[a[i]]=out[b[i]]=1;
		}
	}
	int ans=0;
	for(int i=1;i<=len;i++){
		if(in[lis[i]]&&!out[lis[i]]){
			ans++;
		}
	}
	for(int i=1;i<=m;i++){
		if((mask>>(i-1))&1){
			out[a[i]]=out[b[i]]=0;
		}
	}
	return ans;
}
bool check(int x,int len){
	return l[x]<=len&&len<=r[x];
}
int count(int x){
	int ans=0;
	while(x){
		ans++;
		x-=(x&(-x));
	}
	return ans;
}
int main(){
	init();
	read(n),read(m);
	for(int i=1;i<=n;i++){
		read(l[i]),read(r[i]);
	}
	for(int i=1;i<=m;i++){
		read(a[i]),read(b[i]);
		vis[a[i]]=vis[b[i]]=1;
	}
	for(int mask=0;mask<(1<<m);mask++){
		f[mask][0]=1;
		if(mask==0){
			continue;
		}
		if(!build_graph(mask)){
			for(int j=1;j<=len;j++){
				in[lis[j]]=0;
			}
			f[mask][0]=0;
			continue;
		}
		int nmask=0;
		connect_dfs(lis[1],nmask);
		if(nmask!=mask){
			for(int j=0;j<=m;j++){
				if(f[nmask][j]==0){
					continue;
				}
				for(int k=0;k+j<=m;k++){
					if(j==0&&k==0){
						continue;
					}
					f[mask][j+k]=(f[mask][j+k]+1ll*f[nmask][j]*f[mask^nmask][k])%Mod;
				}
			}
			for(int j=1;j<=len;j++){
				in[lis[j]]=0;
			}
			continue;
		}
		nmask=mask;
		int u=lis[1];
		int num=0;
		for(int j=head[u];j;j=nxt[j]){
			nmask&=(~(1<<(val[j]-1)));
		}
		num=calc(nmask)-1;
		for(int j=1;j<=m;j++){
			for(int k=0;k<=j;k++){
				f[mask][j]=(f[mask][j]+1ll*f[nmask][k]*C(num,j-k))%Mod;
			}
		}
		num=0;
		for(int j=head[u];j;j=nxt[j]){
			int v=arrive[j];
			for(int k=head[v];k;k=nxt[k]){
				nmask&=(~(1<<(val[k]-1)));
				if(arrive[k]==u){
					continue;
				}
			}
		}
		num=calc(nmask)-1-deg[lis[1]];
		for(int j=1;j<=m;j++){
			for(int k=0;k<j;k++){
				f[mask][j]=(f[mask][j]+1ll*f[nmask][k]*C(num,j-1-k))%Mod;
			}
		}
		for(int j=1;j<=len;j++){
			in[lis[j]]=0;
		}
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			sum[l[i]]++;
			sum[r[i]+1]--;
		}
	}
	for(int i=1;i<=n;i++){
		sum[i]+=sum[i-1];
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		int mask=0;
		for(int j=1;j<=m;j++){
			if(check(a[j],i)&&check(b[j],i)){
				in[a[j]]=in[b[j]]=1;
				mask|=(1<<(j-1));
			}
		}
		int num=0;
		for(int j=1;j<=m;j++){
			if(check(a[j],i)&&!in[a[j]]){
				num++;
				in[a[j]]=1;
			}
			if(check(b[j],i)&&!in[b[j]]){
				num++;
				in[b[j]]=1;
			}
		}
		for(int j=1;j<=m;j++){
			in[a[j]]=in[b[j]]=0;
		}
		int tmp=sum[i];
		tmp+=num;
		for(int j=0;j<=m;j++){
			ans=(ans+1ll*C(tmp,i-j)*f[mask][j])%Mod;
		}
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define S second
#define pb push_back
#define F first
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll read(){
	ll a=0,b=getchar(),c=1;
	while(!isdigit(b))c=b=='-'?-1:1,b=getchar();
	while(isdigit(b))a=a*10+b-'0',b=getchar();
	return a*c;
}
const ll N=3e5+5,mod=998244353;
pii e[35];
ll n,m,ab,ans,l,r,ac,a[2][55][N],T[N],L[N],R[N],b[N],c[N];
bool d[N];
vector<int> g;
ll gg(ll i,ll j){
	ll res=1;
	for(ll k=1;k<=j;k*=2,i=(i*i)%mod)
		if(k&j)res=(res*i)%mod;
	return res;
}
ll cmp(int i,int j){
	if(i<0 or i>j or j>n)
		return 0;
	return b[j]*c[i]%mod*c[j-i]%mod;
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		L[i]=read(),R[i]=read();
		T[L[i]]++,T[R[i]+1]--;
	}
	for(int i=0;i<m;i++)
		e[i].F=read(),e[i].S=read();
	b[0]=c[0]=1;
	for(int i=1;i<=n;i++){
		b[i]=(b[i-1]*i)%mod;
		c[i]=gg(b[i],mod-2);
	}
	for(int i=1;i<=n;i++)
		T[i]+=T[i-1];
	for(int j=0;j<(1<<m);j++){
		bool x=0;
		g.clear();
		for(int i=0;i<m;i++)
		if(j>>i&1){
			x^=1,g.pb(e[i].F);
			g.pb(e[i].S);
			d[e[i].F]=d[e[i].S]=0;
		}
		ac=0,l=0,r=n;
		for(int i=0;i<g.size();i++){
			int A=g[i];
			if(d[A])continue;
			l=max(l,L[A]),r=min(r,R[A]);
			d[A]=1,ac++;
		}
		if(l>r)continue;
		ab=max(ab,ac);
		a[x][ac][l]++;
		a[x][ac][r+1]--;
	}
	for(int i=0;i<=ab;i++)
		for(int j=1;j<=n;j++){
			a[0][i][j]+=a[0][i][j-1];
			a[1][i][j]+=a[1][i][j-1];
			ans+=a[0][i][j]*cmp(j-i,T[j]-i)%mod;
			ans-=a[1][i][j]*cmp(j-i,T[j]-i)%mod;
			ans=(ans%mod+mod)%mod;
		}
	cout << ans;
	return 0;
}