#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3e5 + 5;
const int ha = 998244353;

int n,m;
int l[MAXN],r[MAXN],a[MAXN],b[MAXN];
int fac[MAXN],inv[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

inline void prework(){
	fac[0] = 1;FOR(i,1,MAXN-1) fac[i] = 1ll*fac[i-1]*i%ha;
	inv[MAXN-1] = qpow(fac[MAXN-1]);ROF(i,MAXN-2,0) inv[i] = 1ll*inv[i+1]*(i+1)%ha;
}

inline int C(int n,int m){
	if(n < 0 || m < 0 || n < m) return 0;
	return 1ll*fac[n]*inv[m]%ha*inv[n-m]%ha;
}

int sm[41][MAXN];

int main(){
	prework();
	scanf("%d%d",&n,&m);
	FOR(i,1,n) scanf("%d%d",l+i,r+i),sm[0][l[i]]++,sm[0][r[i]+1]--;
	FOR(i,1,m) scanf("%d%d",a+i,b+i);
	FOR(i,1,n) sm[0][i] += sm[0][i-1];
	FOR(c,1,40){
		FOR(i,1,n){
			sm[c][i] = (sm[c][i-1]+C(sm[0][i]-c,i-c))%ha;
		}
	}
	FOR(i,1,n) sm[0][i] = (sm[0][i-1]+C(sm[0][i],i))%ha;
	int ans = 0;
	FOR(S,0,(1<<n)-1){
		int l = 1,r = n;
		FOR(i,0,n-1){
			if(!((S>>i)&1)) continue;
			l = std::max({l,::l[a[i]],::l[b[i]]});
			r = std::min({r,::r[a[i]],::r[b[i]]});
		}
		int gx = (sm[__builtin_popcount(S)][r]+ha-sm[__builtin_popcount(S)][l-1])%ha;
		if(__builtin_popcount(S)&1) gx = ha-gx;
		(ans += gx) %= ha;
	}
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3e5 + 5;
const int ha = 998244353;

int n,m;
int l[MAXN],r[MAXN],a[MAXN],b[MAXN];
int fac[MAXN],inv[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

inline void prework(){
	fac[0] = 1;FOR(i,1,MAXN-1) fac[i] = 1ll*fac[i-1]*i%ha;
	inv[MAXN-1] = qpow(fac[MAXN-1]);ROF(i,MAXN-2,0) inv[i] = 1ll*inv[i+1]*(i+1)%ha;
}

inline int C(int n,int m){
	if(n < 0 || m < 0 || n < m) return 0;
	return 1ll*fac[n]*inv[m]%ha*inv[n-m]%ha;
}

int sm[41][MAXN];

int main(){
	prework();
	scanf("%d%d",&n,&m);
	FOR(i,1,n) scanf("%d%d",l+i,r+i),sm[0][l[i]]++,sm[0][r[i]+1]--;
	FOR(i,1,m) scanf("%d%d",a+i,b+i);
	FOR(i,1,n) sm[0][i] += sm[0][i-1];
	FOR(c,1,40){
		FOR(i,1,n){
			sm[c][i] = (sm[c][i-1]+C(sm[0][i]-c,i-c))%ha;
		}
	}
	FOR(i,1,n) sm[0][i] = (sm[0][i-1]+C(sm[0][i],i))%ha;
	int ans = 0;
	FOR(S,0,(1<<m)-1){
		int l = 1,r = n;std::vector<int> _;
		FOR(i,0,m-1){
			if(!((S>>i)&1)) continue;
			l = std::max({l,::l[a[i+1]],::l[b[i+1]]});
			r = std::min({r,::r[a[i+1]],::r[b[i+1]]});
			_.pb(a[i+1]);_.pb(b[i+1]);
		}
		if(l > r) continue;
		std::sort(all(_));_.erase(std::unique(all(_)),_.end());
		int gx = (sm[_.size()][r]+ha-sm[_.size()][l-1])%ha;
		if(__builtin_popcount(S)&1) gx = ha-gx;
		(ans += gx) %= ha;
	}
	printf("%d\n",ans);
	return 0;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define int long long
#define N 300010
using namespace std;
const int p=998244353;
inline int read()
{
	int neg=1,num=0;char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')neg=-1;
	for(;isdigit(c);c=getchar())num=(num<<1)+(num<<3)+c-'0';
	return neg*num;
}
int n,m,a[N],b[N],l[N],r[N],s[N],fac[N],inv[N],ans[N][42];
bool vis[N];
inline int Pow(int x,int y){int res=1;for(;y;y>>=1,x=x*x%p)if(y&1)res=res*x%p;return res;}
inline int C(int x,int y){if(x<0 || y<0 || x<y)return 0ll;return fac[x]*inv[y]%p*inv[x-y]%p;}
signed main()
{
	n=read();m=read();fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%p,inv[i]=Pow(fac[i],p-2);
	for(int i=1;i<=n;i++)l[i]=read(),r[i]=read(),s[l[i]]++,s[r[i]+1]--;
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	for(int i=1;i<=n;i++)
		for(int j=0;j<=40;j++)
			ans[i][j]=C(s[i]-j,i-j)+ans[i-1][j];
	for(int i=1;i<=m;i++)a[i]=read(),b[i]=read();
	int res=ans[n][0];
	for(int i=1;i<=(1<<m)-1;i++)
	{
		int L=0,R=n+1,cnt=0;
		for(int j=1;j<=m;j++)
			if((i>>j-1)&1)
			{
				if(!vis[a[j]])L=max(L,l[a[j]]),R=min(R,r[a[j]]),cnt++,vis[a[j]]=1;
				if(!vis[b[j]])L=max(L,l[b[j]]),R=min(R,r[b[j]]),cnt++,vis[b[j]]=1;
			}
		for(int j=1;j<=m;j++)if((i>>j-1)&1)vis[a[j]]=vis[b[j]]=0;
		if(L<=R)res-=ans[R][cnt]-ans[L-1][cnt];
	}
	printf("%lld\n",res);
	return 0;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define int long long
#define N 305010
using namespace std;
const int p=998244353;
inline int read()
{
	int neg=1,num=0;char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')neg=-1;
	for(;isdigit(c);c=getchar())num=(num<<1)+(num<<3)+c-'0';
	return neg*num;
}
int n,m,a[N],b[N],l[N],r[N],s[N],fac[N],inv[N],ans[N][42];
bool vis[N];
inline int Pow(int x,int y){int res=1;for(;y;y>>=1,x=x*x%p)if(y&1)res=res*x%p;return res;}
inline int C(int x,int y){if(x<0 || y<0 || x<y)return 0ll;return fac[x]*inv[y]%p*inv[x-y]%p;}
signed main()
{
	n=read();m=read();fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%p,inv[i]=Pow(fac[i],p-2);
	for(int i=1;i<=n;i++)l[i]=read(),r[i]=read(),s[l[i]]++,s[r[i]+1]--;
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	for(int i=1;i<=n;i++)
		for(int j=0;j<=40;j++)
			ans[i][j]=(C(s[i]-j,i-j)+ans[i-1][j])%p;
	for(int i=1;i<=m;i++)a[i]=read(),b[i]=read();
	int res=ans[n][0];
	for(int i=1;i<=(1<<m)-1;i++)
	{
		int L=0,R=n+1,cnt=0;
		int tmp=i,tot=0;
		for(;tmp;tmp>>=1)if(tmp&1)tot++;
		for(int j=1;j<=m;j++)
			if((i>>j-1)&1)
			{
				if(!vis[a[j]])L=max(L,l[a[j]]),R=min(R,r[a[j]]),cnt++,vis[a[j]]=1;
				if(!vis[b[j]])L=max(L,l[b[j]]),R=min(R,r[b[j]]),cnt++,vis[b[j]]=1;
			}
		for(int j=1;j<=m;j++)if((i>>j-1)&1)vis[a[j]]=vis[b[j]]=0;
		if(L<=R)res=(res-((tot&1)?1:-1)*(ans[R][cnt]-ans[L-1][cnt]))%p;
	}
	printf("%lld\n",(res%p+p)%p);
	return 0;
}
/*
3 3
1 3
1 3
1 3
2 3
1 3
1 2
*/


#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define int long long
#define N 300010
using namespace std;
const int p=998244353;
inline int read()
{
	int neg=1,num=0;char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')neg=-1;
	for(;isdigit(c);c=getchar())num=(num<<1)+(num<<3)+c-'0';
	return neg*num;
}
int n,m,a[N],b[N],l[N],r[N],s[N],fac[N],inv[N],ans[N][42];
bool vis[N];
inline int Pow(int x,int y){int res=1;for(;y;y>>=1,x=x*x%p)if(y&1)res=res*x%p;return res;}
inline int C(int x,int y){if(x<0 || y<0 || x<y)return 0ll;return fac[x]*inv[y]%p*inv[x-y]%p;}
signed main()
{
	n=read();m=read();fac[0]=inv[0]=1;
	for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%p,inv[i]=Pow(fac[i],p-2);
	for(int i=1;i<=n;i++)l[i]=read(),r[i]=read(),s[l[i]]++,s[r[i]+1]--;
	for(int i=1;i<=n;i++)s[i]+=s[i-1];
	for(int i=1;i<=n;i++)
		for(int j=0;j<=40;j++)
			ans[i][j]=(C(s[i]-j,i-j)+ans[i-1][j])%p;
	for(int i=1;i<=m;i++)a[i]=read(),b[i]=read();
	int res=ans[n][0];
	for(int i=1;i<=(1<<m)-1;i++)
	{
		int L=0,R=n+1,cnt=0;
		for(int j=1;j<=m;j++)
			if((i>>j-1)&1)
			{
				if(!vis[a[j]])L=max(L,l[a[j]]),R=min(R,r[a[j]]),cnt++,vis[a[j]]=1;
				if(!vis[b[j]])L=max(L,l[b[j]]),R=min(R,r[b[j]]),cnt++,vis[b[j]]=1;
			}
		for(int j=1;j<=m;j++)if((i>>j-1)&1)vis[a[j]]=vis[b[j]]=0;
		if(L<=R)res=(res-ans[R][cnt]+ans[L-1][cnt])%p;
	}
	printf("%lld\n",(res%p+p)%p);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N];
int cov[N];
int ls[1<<20],rs[1<<20],st[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            //printf("i:%d cov:%d\n",i,cov[i]);
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
            //printf("j:%d i:%d res:%lld\n",j,i,res[j][i]);
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        st[1<<j]=(1<<a)|(1<<b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],__builtin_popcount(st[j]))%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N],st[1<<20];
int cov[N],x[42],c;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            //printf("i:%d cov:%d\n",i,cov[i]);
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
            //printf("j:%d i:%d res:%lld\n",j,i,res[j][i]);
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        x[++c]=a;x[++c]=b;
        f[j].a=a;f[j].b=b;
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    sort(x+1,x+c+1);c=unique(x+1,x+c+1)-(x+1);
    for(int j=0;j<m;++j){
        int aa=lower_bound(x+1,x+c+1,f[j].a)-(x+1);
        int bb=lower_bound(x+1,x+c+1,f[j].b)-(x+1);
        st[1<<j]=(1ll<<aa)|(1ll<<bb);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],__builtin_popcountll(st[j]))%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N];
int cov[N];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
    }
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    for(int j=0;j<m;++j){
        scanf("%d%d",&f[j].a,&f[j].b);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<(1<<m);++j){
        int c=0,l=1,r=n;
        set<int>q;
        for(int k=0;k<m;++k){
            if(j>>k&1){
                c++;
                l=max(l,f[k].l);
                r=min(r,f[k].r);
                q.insert(e[k].a);
                q.insert(e[k].b);
            }
        }
        if(l>r)continue;
        ll res=ch(l,r,(int)q.size())%mod;
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N],id[N],st[1<<20];
int cov[N],c;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
    }
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    int up=1<<m;
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        if(!id[a])id[a]=++c;
        if(!id[b])id[b]=++c;
        st[1<<j]=(1ll<<id[a])|(1ll<<id[b]);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;st[0]=0;
    for(int j=0;j<up;++j){
        int c=0,d=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        for(ll v=st[j];v;v=v/2)d+=(v%2);
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=(ch(ls[j],rs[j],d)%mod+mod)%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N],id[N],st[1<<20];
int cov[N],c;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
    }
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    int up=1<<m;
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        if(!id[a])id[a]=++c;
        if(!id[b])id[b]=++c;
        st[1<<j]=(1ll<<id[a])|(1ll<<id[b]);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;st[0]=0;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=(ch(ls[j],rs[j],__builtin_popcount(st[j]))%mod+mod)%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{S
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N];
int cov[N];
int ls[1<<20],rs[1<<20];
set<int>st[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            //printf("i:%d cov:%d\n",i,cov[i]);
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
            //printf("j:%d i:%d res:%lld\n",j,i,res[j][i]);
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        st[1<<j].insert(a);st[1<<j].insert(b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            if(st[lb].size()<st[p].size()){
                st[j]=st[p];
                for(auto &x:st[lb]){
                    st[j].insert(x);
                }
            }
            else{
                st[j]=st[lb];
                for(auto &x:st[p]){
                    st[j].insert(x);
                }
            }
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],st[j].size())%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N],st[1<<20];
int cov[N],x[42],c;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            //printf("i:%d cov:%d\n",i,cov[i]);
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
            //printf("j:%d i:%d res:%lld\n",j,i,res[j][i]);
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        x[++c]=a;x[++c]=b;
        f[j].a=a;f[j].b=b;
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    sort(x+1,x+c+1);c=unique(x+1,x+c+1)-(x+1);
    for(int j=0;j<m;++j){
        int aa=lower_bound(x+1,x+c+1,f[j].a)-(x+1);
        int bb=lower_bound(x+1,x+c+1,f[j].b)-(x+1);
        st[1<<j]=(1ll<<aa)|(1ll<<bb);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],__builtin_popcount(st[j]))%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N];
int cov[N];
int ls[1<<20],rs[1<<20];
set<int>st[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            //printf("i:%d cov:%d\n",i,cov[i]);
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
            //printf("j:%d i:%d res:%lld\n",j,i,res[j][i]);
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        st[1<<j].insert(a);st[1<<j].insert(b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            if(st[lb].size()<st[p].size()){
                for(auto &x:st[lb]){
                    st[p].insert(x);
                }
            }
            else{
                for(auto &x:st[p]){
                    st[lb].insert(x);
                }
            }
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],st[j].size())%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N],id[N],st[1<<20];
int cov[N],c;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
    }
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    int up=1<<m;
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        if(!id[a])id[a]=++c;
        if(!id[b])id[b]=++c;
        st[1<<j]=(1ll<<id[a])|(1ll<<id[b]);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;st[0]=0;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=(ch(ls[j],rs[j],__builtin_popcount(st[j]))%mod+mod)%mod;
        //printf("j:%d ls:%d rs:%d st:%d now:%d res:%lld\n",j,ls[j],rs[j],st[j],__builtin_popcount(st[j]),res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[42][N];
int cov[N];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
    }
    for(int j=0;j<=2*m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    for(int j=0;j<m;++j){
        scanf("%d%d",&f[j].a,&f[j].b);
    }
    for(int j=0;j<(1<<m);++j){
        int c=0,l=1,r=n;
        set<int>q;
        for(int k=0;k<m;++k){
            if(j>>k&1){
                c++;
                int a=f[k].a,b=f[k].b;
                l=max(l,e[a].l);
                r=min(r,e[a].r);
                l=max(l,e[b].l);
                r=min(r,e[b].r);
                q.insert(a);
                q.insert(b);
            }
        }
        if(l>r)continue;
        ll res=ch(l,r,(int)q.size())%mod;
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans,res[21][N];
int cov[N];
int ls[1<<20],rs[1<<20],st[1<<20];
int n,m,a,b;
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        //ans=(ans+C(cov[i],i))%mod;
    }
    //printf("ans:%lld\n",ans);
    for(int j=0;j<=m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        st[1<<j]=(1<<a)|(1<<b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    ls[0]=1;rs[0]=n;
    for(int j=0;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        int lb=j&(-j),p=j-lb;
        if(p){
            st[j]=st[lb]|st[p];
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        if(ls[j]>rs[j])continue;
        ll res=ch(ls[j],rs[j],__builtin_popcount(st[j]))%mod;
        //printf("j:%d ls:%d rs:%d res:%lld\n",j,ls[j],rs[j],res);
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans;
int cov[N],res[20][N];
int ls[1<<20],rs[1<<20];
int n,m,a,b;
int ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return (res[x][r]-res[x][l-1]+mod)%mod;
}
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        cov[e[i].l]++;cov[e[i].r+1]--;
    }
    for(int i=1;i<=n;++i){
        cov[i]+=cov[i-1];
        ans=(ans+C(cov[i],i))%mod;
    }
    for(int j=0;j<=m;++j){
        for(int i=1;i<=n;++i){
            res[j][i]=(res[j][i-1]+C(cov[i]-j,i-j))%mod;
        }
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    for(int j=1;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        ll res=0;
        int lb=j&(-j),p=j-lb;
        if(p){
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        res=(res+ch(ls[j],rs[j],c)%mod+mod)%mod;
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
const int mod=998244353;
ll Finv[N],fac[N],inv[N];
ll modpow(ll x,ll n,ll mod)
{
	ll res=1;
	for(;n;x=x*x%mod,n/=2)
	if(n&1)res=res*x%mod;
	return res;
}
void init(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;++i)inv[i]=((mod-mod/i)*inv[mod%i])%mod;
	fac[0]=Finv[0]=1;
	for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod,Finv[i]=Finv[i-1]*inv[i]%mod;
	//Finv[n]=modpow(fac[n],mod-2,mod);
	//for(int i=n-1;i>=1;--i)Finv[i]=Finv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
	if(m<0||m>n)return 0;
	return fac[n]*Finv[n-m]%mod*Finv[m]%mod;
}
ll ch(int r,int x){
    if(r<x)return 0;
    return C(r+1,x+1);
}
ll ch(int l,int r,int x){
    l=max(l,x);
    if(l>r || x>r)return 0;
    return ch(r,x)-ch(l-1,x);
}
struct BIT{
	int n,tr[N];
	void init(int _n){
		n=_n;
		memset(tr,0,sizeof tr);
	}
	void add(int x,int v){
		for(int i=x;i<=n;i+=i&-i)
		tr[i]+=v;
	}
	int sum(int x){
		int ans=0;
		for(int i=x;i;i-=i&-i)
		ans+=tr[i];
		return ans;
	}
}tr;
struct node{
    int l,r;
}e[N];
struct ban{
    int a,b;
}f[20];
ll ans;
int ls[1<<20],rs[1<<20];
int n,m,a,b;
int main(){
    init(N-5);
    scanf("%d%d",&n,&m);
    tr.init(n+2);
    for(int i=1;i<=n;++i){
        scanf("%d%d",&e[i].l,&e[i].r);
        tr.add(e[i].l,1);tr.add(e[i].r+1,-1);
    }
    for(int i=1;i<=n;++i){
        ll v=tr.sum(i);
        ans=(ans+C(v,i))%mod;
    }
    int up=1<<m;
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int j=0;j<m;++j){
        scanf("%d%d",&a,&b);
        ls[1<<j]=max(e[a].l,e[b].l);
        rs[1<<j]=min(e[a].r,e[b].r);
    }
    for(int j=1;j<up;++j){
        int c=0;
        for(int k=0;k<m;++k){
            if(j>>k&1)c++;
        }
        ll res=0;
        int lb=j&(-j),p=j-lb;
        if(p){
            ls[j]=max(ls[lb],ls[p]);
            rs[j]=min(rs[lb],rs[p]);
        }
        res=(res+ch(ls[j],rs[j],c)%mod+mod)%mod;
        if(c&1){
            ans=(ans-res+mod)%mod;
        }
        else{
            ans=(ans+res)%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 300005;
const int mod = 998244353;
int fact[N], infact[N];
int qmi(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = (ll)res * a % mod;
		a = (ll)a * a % mod;
		b >>= 1;
	}
	return res;
}
int C(int a, int b)
{
	if (a < b) return 0;
	return (ll)fact[a] * infact[a - b] % mod * infact[b] % mod;
}

void init()
{
	fact[0] = infact[0] = 1;
	for (int i = 1; i < N; ++i)
	{
		fact[i] = (ll)fact[i - 1] * i % mod;
		infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2) % mod;
	}
}
int cnt[N];

ll sum[42][N];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	vector<pii> v(n + 1);

	for (int i = 0; i < n; ++i)
	{
		scanf("%d%d", &v[i].first, &v[i].second);
		++cnt[v[i].first], --cnt[v[i].second + 1];
	}

	for (int i = 1; i < N; ++i)
	{
		cnt[i] = cnt[i] + cnt[i - 1];
	}

	init();

	for (int i = 0; i <= 2 * m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			sum[i][j] = ((ll)sum[i][j - 1] + C(cnt[j] - i, j - i)) % mod;
		}
	}

	vector<pii> hate(m);

	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &hate[i].first, &hate[i].second);
		//编号减1
		--hate[i].first, --hate[i].second;
	}

	int res = 0;
	for (int i = 0; i < (1 << m); ++i)
	{
		int flag = 1;
		int l = 1, r = n;
		//集合中士兵个数
		set<int> S;
		for (int j = 0; j < m; ++j)
		{
			if ((i >> j) & 1)
			{
				flag = -flag;
				l = max(l, v[hate[j].first].first), r = min(r, v[hate[j].first].second);
				l = max(l, v[hate[j].second].first), r = min(r, v[hate[j].second].second);
				S.insert(hate[j].first);
				S.insert(hate[j].second);
			}
		}
		int num = S.size();
		if (r >= l)
		{
			res = (((ll)res + (ll)flag * (sum[num][r] - sum[num][l - 1])) % mod + mod) % mod;
		}
	}

	printf("%d\n", res);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 300005;
const int mod = 998244353;
int fact[N], infact[N];
int qmi(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = (ll)res * a % mod;
		a = (ll)a * a % mod;
		b >>= 1;
	}
	return res;
}
int C(int a, int b)
{
	if (a < b) return 0;
	return (ll)fact[a] * infact[a - b] % mod * infact[b] % mod;
}

void init()
{
	fact[0] = infact[0] = 1;
	for (int i = 1; i < N; ++i)
	{
		fact[i] = (ll)fact[i - 1] * i % mod;
		infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2) % mod;
	}
}
int cnt[N];

ll sum[N][42];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	vector<pii> v(n + 1);

	for (int i = 0; i < n; ++i)
	{
		scanf("%d%d", &v[i].first, &v[i].second);
		++cnt[v[i].first], --cnt[v[i].second + 1];
	}

	for (int i = 1; i < N; ++i)
	{
		cnt[i] = cnt[i] + cnt[i - 1];
	}

	init();

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j <= 2 * m; ++j)
		{
			sum[i][j] = (sum[i - 1][j] + C(cnt[i] - j, i - j)) % mod;
		}
	}

	vector<pii> hate(m);

	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &hate[i].first, &hate[i].second);
		//编号减1
		--hate[i].first, --hate[i].second;
	}

	ll res = 0;
	for (int i = 0; i < (1 << m); ++i)
	{
		int flag = 1;
		int l = 1, r = n;
		//集合中士兵个数
		set<int> S;
		for (int j = 0; j < m; ++j)
		{
			if ((i >> j) & 1)
			{
				flag = -flag;
				l = max(l, v[hate[j].first].first), r = min(r, v[hate[j].first].second);
				l = max(l, v[hate[j].second].first), r = min(r, v[hate[j].second].second);
				S.insert(hate[j].first);
				S.insert(hate[j].second);
			}
		}
		int num = S.size();
		if (r >= l)
		{
			res = ((res + flag * (sum[r][num] - sum[l - 1][num])) % mod + mod) % mod;
		}
	}

	printf("%lld\n", res);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 300005;
const int mod = 1e9 + 7;
int fact[N], infact[N];
int qmi(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = (ll)res * a % mod;
		a = (ll)a * a % mod;
		b >>= 1;
	}
	return res;
}
int C(int a, int b)
{
	if (a < b) return 0;
	return (ll)fact[a] * infact[a - b] % mod * infact[b] % mod;
}

void init()
{
	fact[0] = infact[0] = 1;
	for (int i = 1; i < N; ++i)
	{
		fact[i] = (ll)fact[i - 1] * i % mod;
		infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2) % mod;
	}
}
int cnt[N];

ll sum[42][N];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	vector<pii> v(n + 1);

	for (int i = 0; i < n; ++i)
	{
		scanf("%d%d", &v[i].first, &v[i].second);
		++cnt[v[i].first], --cnt[v[i].second + 1];
	}

	for (int i = 1; i < N; ++i)
	{
		cnt[i] = cnt[i] + cnt[i - 1];
	}

	init();

	for (int i = 0; i <= 2 * m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			sum[i][j] = ((ll)sum[i][j - 1] + C(cnt[j] - i, j - i))% mod;
		}
	}

	vector<pii> hate(m);

	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &hate[i].first, &hate[i].second);
		//编号减1
		--hate[i].first, --hate[i].second;
	}

	int res = 0;
	for (int i = 0; i < (1 << m); ++i)
	{
		int flag = 1;
		int l = 1, r = n;
		//集合中士兵个数
		set<int> S;
		for (int j = 0; j < m; ++j)
		{
			if ((i >> j) & 1)
			{
				flag = -flag;
				l = max(l, v[hate[j].first].first), r = min(r, v[hate[j].first].second);
				l = max(l, v[hate[j].second].first), r = min(r, v[hate[j].second].second);
				S.insert(hate[j].first);
				S.insert(hate[j].second);
			}
		}
		int num = S.size();
		if (r >= l)
		{
			res = (((ll)res + (ll)flag * (sum[num][r] - sum[num][l - 1])) % mod + mod)% mod;
		}
	}

	printf("%d\n", res);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 300005;
const int mod = 998244353;
int fact[N], infact[N];
int qmi(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = (ll)res * a % mod;
		a = (ll)a * a % mod;
		b >>= 1;
	}
	return res;
}
int C(int a, int b)
{
	if (a < b) return 0;
	return (ll)fact[a] * infact[a - b] % mod * infact[b] % mod;
}

void init()
{
	fact[0] = infact[0] = 1;
	for (int i = 1; i < N; ++i)
	{
		fact[i] = (ll)fact[i - 1] * i % mod;
		infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2) % mod;
	}
}
int cnt[N];

ll sum[N][42];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	vector<pii> v(n + 1);

	for (int i = 0; i < n; ++i)
	{
		scanf("%d%d", &v[i].first, &v[i].second);
		++cnt[v[i].first], --cnt[v[i].second + 1];
	}

	for (int i = 1; i < N; ++i)
	{
		cnt[i] = cnt[i] + cnt[i - 1];
	}

	init();

	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j <= 2 * m; ++j)
		{
			sum[i][j] = (sum[i - 1][j] + C(cnt[i] - j, i - j)) % mod;
		}
	}

	vector<pii> hate(m);

	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &hate[i].first, &hate[i].second);
		//编号减1
		--hate[i].first, --hate[i].second;
	}

	ll res = 0;
	for (int i = 0; i < (1 << m); ++i)
	{
		int flag = 1;
		int l = 1, r = n;
		//集合中士兵个数
		set<int> S;
		for (int j = 0; j < m; ++j)
		{
			if ((i >> j) & 1)
			{
				flag = -flag;
				l = max(l, v[hate[j].first].first), r = min(r, v[hate[j].first].second);
				l = max(l, v[hate[j].second].first), r = min(r, v[hate[j].second].second);
				S.insert(hate[j].first);
				S.insert(hate[j].second);
			}
		}
		int num = S.size();
		if (r >= l)
		{
			res = (res + flag * (sum[r][num] - sum[l - 1][num])) % mod;
		}
	}

	printf("%lld\n", res);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 300005;
const int mod = 1e9 + 7;
int fact[N], infact[N];
int qmi(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = (ll)res * a % mod;
		a = (ll)a * a % mod;
		b >>= 1;
	}
	return res;
}
int C(int a, int b)
{
	if (a < b) return 0;
	return (ll)fact[a] * infact[a - b] % mod * infact[b] % mod;
}

void init()
{
	fact[0] = infact[0] = 1;
	for (int i = 1; i < N; ++i)
	{
		fact[i] = (ll)fact[i - 1] * i % mod;
		infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2) % mod;
	}
}
int cnt[N];

ll sum[N][42];
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	vector<pii> v(n + 1);

	for (int i = 0; i < n; ++i)
	{
		scanf("%d%d", &v[i].first, &v[i].second);
		++cnt[v[i].first], --cnt[v[i].second + 1];
	}

	for (int i = 1; i < N; ++i)
	{
		cnt[i] = cnt[i] + cnt[i - 1];
	}

	init();

	for (int i = 0; i <= 2 * m; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			sum[i][j] = ((ll)sum[i][j - 1] + C(cnt[j] - i, j - i))% mod;
		}
	}

	vector<pii> hate(m);

	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &hate[i].first, &hate[i].second);
		//编号减1
		--hate[i].first, --hate[i].second;
	}

	int res = 0;
	for (int i = 0; i < (1 << m); ++i)
	{
		int flag = 1;
		int l = 1, r = n;
		//集合中士兵个数
		set<int> S;
		for (int j = 0; j < m; ++j)
		{
			if ((i >> j) & 1)
			{
				flag = -flag;
				l = max(l, v[hate[j].first].first), r = min(r, v[hate[j].first].second);
				l = max(l, v[hate[j].second].first), r = min(r, v[hate[j].second].second);
				S.insert(hate[j].first);
				S.insert(hate[j].second);
			}
		}
		int num = S.size();
		if (r >= l)
		{
			ll val = (sum[num][r] - sum[num][l - 1] + mod) % mod;
			if (__builtin_popcount(i) & 1) res = ((ll)res - val + mod) % mod;
			else res = ((ll)res + val + mod) % mod;
		}
	}

	printf("%d\n", res);

	return 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF emplace_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
using namespace std;
int f[300005],finv[300005],inv[300005],p[300005][45],t[300005];
int l[300005],r[300005],q1[45],q2[45],mod=998244353;
bool vis[300005];
int n,m;
int C(int x,int y){
	if(x<0||y<0||x<y)RE 0;
	RE f[x]*finv[y]%mod*finv[x-y]%mod;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	FOR(i,1,n)cin>>l[i]>>r[i],t[l[i]]++,t[r[i]+1]--;
	FOR(i,1,m)cin>>q1[i]>>q2[i];
	FOR(i,1,n)t[i]+=t[i-1];
	f[0]=f[1]=1;
	finv[0]=finv[1]=1;
	inv[1]=1;
	FOR(i,2,n){
		f[i]=f[i-1]*i%mod;
		inv[i]=mod-(mod/i)*inv[mod%i]%mod;
		finv[i]=finv[i-1]*inv[i]%mod;
	}
	FOR(i,1,n){
		FOR(j,0,40){
			p[i][j]=p[i-1][j]+C(t[i]-j,i-j);p[i][j]%=mod;
		}
	}
	int ans=0;
	rep(mask,0,1<<m){
		int cnt=__builtin_popcount(mask),num=0,nl=1,nr=n;
		FOR(i,1,m)if(mask&(1<<(m-1))){
			if(!vis[q1[i]]){
				vis[q1[i]]=1;num++;gmin(nr,r[q1[i]]);gmax(nl,l[q1[i]]);
			}
			if(!vis[q2[i]]){
				vis[q2[i]]=1;num++;gmin(nr,r[q2[i]]);gmax(nl,l[q2[i]]);
			}
		}
		if(nr>=nl){
			if(cnt&1){
				ans=(ans-p[nr][cnt]+p[nl-1][cnt]+mod)%mod;
			}else ans=(ans+p[nr][cnt]-p[nl-1][cnt]+mod)%mod;
		}
		FOR(i,1,m)vis[q1[i]]=0,vis[q2[i]]=0;
	}
	cout<<ans;
	RE 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF emplace_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
using namespace std;
int f[300005],finv[300005],inv[300005],p[300005][45],t[300005];
int l[300005],r[300005],q1[45],q2[45],mod=998244353;
bool vis[300005];
int n,m;
int C(int x,int y){
	if(x<0||y<0||x<y)RE 0;
	RE f[x]*finv[y]%mod*finv[x-y]%mod;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	FOR(i,1,n)cin>>l[i]>>r[i],t[l[i]]++,t[r[i]+1]--;
	FOR(i,1,m)cin>>q1[i]>>q2[i];
	FOR(i,1,n)t[i]+=t[i-1];
	f[0]=f[1]=1;
	finv[0]=finv[1]=1;
	inv[1]=1;
	FOR(i,2,n){
		f[i]=f[i-1]*i%mod;
		inv[i]=mod-(mod/i)*inv[mod%i]%mod;
		finv[i]=finv[i-1]*inv[i]%mod;
	}
	FOR(i,1,n){
		FOR(j,0,40){
			p[i][j]=p[i-1][j]+C(t[i]-j,i-j);p[i][j]%=mod;
		}
	}
	int ans=0;
	rep(mask,0,1<<m){
		int cnt=__builtin_popcount(mask),num=0,nl=1,nr=n;
		FOR(i,1,m)if(mask&(1<<(i-1))){
			if(!vis[q1[i]]){
				vis[q1[i]]=1;num++;gmin(nr,r[q1[i]]);gmax(nl,l[q1[i]]);
			}
			if(!vis[q2[i]]){
				vis[q2[i]]=1;num++;gmin(nr,r[q2[i]]);gmax(nl,l[q2[i]]);
			}
		}
		if(nr>=nl){
			if(cnt&1){
				ans=(ans-p[nr][cnt]+p[nl-1][cnt]+mod)%mod;
			}else ans=(ans+p[nr][cnt]-p[nl-1][cnt]+mod)%mod;
		}
		FOR(i,1,m)vis[q1[i]]=0,vis[q2[i]]=0;
	}
	cout<<ans;
	RE 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF emplace_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
using namespace std;
int f[300005],finv[300005],inv[300005],p[300005][45],t[300005];
int l[300005],r[300005],q1[45],q2[45],mod=998244353;
bool vis[300005];
int n,m;
int C(int x,int y){
	if(x<0||y<0||x<y)RE 0;
	RE f[x]*finv[y]%mod*finv[x-y]%mod;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	FOR(i,1,n)cin>>l[i]>>r[i],t[l[i]]++,t[r[i]+1]--;
	FOR(i,1,m)cin>>q1[i]>>q2[i];
	FOR(i,1,n)t[i]+=t[i-1];
	f[0]=f[1]=1;
	finv[0]=finv[1]=1;
	inv[1]=1;
	FOR(i,2,n){
		f[i]=f[i-1]*i%mod;
		inv[i]=mod-(mod/i)*inv[mod%i]%mod;
		finv[i]=finv[i-1]*inv[i]%mod;
	}
	FOR(i,1,n){
		FOR(j,0,40){
			p[i][j]=p[i-1][j]+C(t[i]-j,i-j);p[i][j]%=mod;
		}
	}
	int ans=0;
	rep(mask,0,1<<m){
		int cnt=__builtin_popcount(mask),num=0,nl=1,nr=n;
		FOR(i,1,m)if(mask&(1<<(i-1))){
			if(!vis[q1[i]]){
				vis[q1[i]]=1;num++;gmin(nr,r[q1[i]]);gmax(nl,l[q1[i]]);
			}
			if(!vis[q2[i]]){
				vis[q2[i]]=1;num++;gmin(nr,r[q2[i]]);gmax(nl,l[q2[i]]);
			}
		}
		if(nr>=nl){
			if(cnt&1){
				ans=(ans-p[nr][num]+p[nl-1][num]+mod)%mod;
			}else ans=(ans+p[nr][num]-p[nl-1][num]+mod)%mod;
		}
		FOR(i,1,m)vis[q1[i]]=0,vis[q2[i]]=0;
	}
	cout<<ans;
	RE 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF emplace_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
using namespace std;
int f[300005],finv[300005],inv[300005],p[300005][45],t[300005];
int l[300005],r[300005],q1[45],q2[45],mod=998244353;
bool vis[300005];
int n,m;
int C(int x,int y){
	RE f[x]*finv[y]%mod*finv[x-y]%mod;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	FOR(i,1,n)cin>>l[i]>>r[i],t[l[i]]++,t[r[i]+1]--;
	FOR(i,1,m)cin>>q1[i]>>q2[i];
	FOR(i,1,n)t[i]+=t[i-1];
	f[0]=f[1]=1;
	finv[0]=finv[1]=1;
	inv[1]=1;
	FOR(i,2,n){
		f[i]=f[i-1]*i%mod;
		inv[i]=mod-(mod/i)*inv[mod%i]%mod;
		finv[i]=finv[i-1]*inv[i]%mod;
	}
	FOR(i,1,n){
		FOR(j,0,40){
			p[i][j]=p[i-1][j]+C(t[i]-j,i-j);p[i][j]%=mod;
		}
	}
	int ans=0;
	rep(mask,0,1<<m){
		int cnt=__builtin_popcount(mask),num=0,nl=1,nr=n;
		FOR(i,1,m)if(mask&(1<<(m-1))){
			if(!vis[q1[i]]){
				vis[q1[i]]=1;num++;gmin(nr,r[q1[i]]);gmax(nl,l[q1[i]]);
			}
			if(!vis[q2[i]]){
				vis[q2[i]]=1;num++;gmin(nr,r[q2[i]]);gmax(nl,l[q2[i]]);
			}
		}
		if(nr>=nl){
			if(cnt&1){
				ans=(ans-p[nr][cnt]+p[nl-1][cnt]+mod)%mod;
			}else ans=(ans+p[nr][cnt]-p[nl-1][cnt]+mod)%mod;
		}
		FOR(i,1,m)vis[q1[i]]=0,vis[q2[i]]=0;
	}
	cout<<ans;
	RE 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} const int N = 3e5 + 5, mod = 998244353;
int n, m, l[N], r[N], x[N], y[N], c[N], s[41][N];
int pw[N], inv[N], res;
int qpow (int x, int y) {
    int t = 1;
    while (y) {
        if (y & 1) t = t * x % mod;
        x = x * x % mod, y >>= 1;
    } return t;
}
int C (int x, int y) {
    if (x < y) return 0;
    return pw[x] * inv[y] % mod * inv[x - y] % mod;
}
int cnt (int x) {
    int t = 0; while (x) t ^= 1, x -= x & -x; return t;
}
signed main() {
    read (n), read (m);
    for (int i = 1; i <= n; ++i)
        read (l[i]), read (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 <= m; ++i) read (x[i]), read (y[i]);
    pw[0] = 1;
    for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * i % mod;
    inv[n] = qpow (pw[n], mod - 2);
    for (int i = n; i >= 1; --i) inv[i - 1] = inv[i] * i % mod;
    for (int i = 0; i <= (m << 1); ++i)
        for (int j = i; j <= n; ++j) s[i][j] = (s[i][j - 1] + C (c[j] - i, j - i)) % mod;
    for (int i = 0; i < (1 << m); ++i) {
        set<int> st; st.clear(); int L = 1, R = n;
        for (int j = 1; j <= m; ++j)
            if ((i >> (j - 1)) & 1) {
                st.insert (x[j]), st.insert (y[j]);
                L = max (L, max (l[x[j]], l[y[j]]));
                R = min (R, min (r[x[j]], r[y[j]]));
            }
        int sz = st.size(), num = cnt (i); if (L > R) continue;
        // printf ("%lld %lld %lld\n", sz, L, R);
        if (num) res -= s[sz][R] - s[sz][L - 1];
        else res += s[sz][R] - s[sz][L - 1]; res %= mod;
    }
    return printf ("%lld\n", (res + mod) % mod), 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} const int N = 3e5 + 5, mod = 998244353;
int n, m, l[N], r[N], x[N], y[N], a[N], b[N];
int pw[N], inv[N];
int qpow (int x, int y) {
    int t = 1;
    while (y) {
        if (y & 1) t = t * x % mod;
        x = x * x % mod, y >>= 1;
    } return t;
}
int C (int x, int y) {
    if (x < y) return 0;
    return pw[x] * inv[y] % mod * inv[x - y] % mod;
}
signed main() {
    read (n), read (m);
    for (int i = 1; i <= n; ++i)
        read (l[i]), read (r[i]), ++a[l[i]], --a[r[i] + 1];
    for (int i = 1; i <= m; ++i) {
        read (x[i]), read (y[i]);
        int L = max (l[x[i]], l[y[i]]);
        int R = min (r[x[i]], r[y[i]]);
        if (L <= R) ++b[L], --b[R + 1];
    } pw[0] = 1;
    for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * i % mod;
    inv[n] = qpow (pw[n], mod - 2);
    for (int i = n; i >= 1; --i) inv[i - 1] = inv[i] * i % mod;
    int sa = 0, sb = 0, res = 0;
    for (int i = 1; i <= n; ++i) {
        sa += a[i], sb += b[i];
        for (int j = 0; j <= sb; ++j) {
            if (j & 1) res -= C (sa - 2 * j, i - 2 * j);
            else res += C (sa - 2 * j, i - 2 * j); res %= mod;
        }
    }
    return printf ("%lld\n", (res + mod) % mod), 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn],d[maxn];
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y||x<y||y<0)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n,sum=0,cnt=0;
	for(int i=1;i<=n;i++)d[i]=0;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl)return 0;
		if(!d[a[x]])cnt++,d[a[x]]++;
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl)return 0;
		if(!d[b[x]])cnt++,d[b[x]]++;
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	//cout<<sl<<" "<<sr<<" "<<" "<<(sum[sr]-sum[sl-1]+mo)%mo<<"--------"<<endl;
	for(int i=sl;i<=sr;i++){
		int x=ss[i];
		sum=(1LL*sum+C(x-cnt,i-cnt))%mo;
	}
	return sum;
	//return (sum[sr]-sum[sl-1]+mo)%mo;
}
void dfs(int num,int x,int d){

	if(num==d+1){
		//for(int i=1;i<num;i++)cout<<c[i]<<" ";
		//cout<<"======="<<" "<<ans<<endl;
		if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
		else ans=((ans-work(num-1))%mo+mo)%mo;
		//for(int i=1;i<num;i++)cout<<c[i]<<" ";
		//cout<<"=======-----"<<" "<<ans<<endl;
		return ;
	}
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1,d);
	}
}
int main(){
	//freopen("1.out","w",stdout);
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
		//sum[i]=(1LL*sum[i-1]+1LL*C(x-2,i-2))%mo;
	//	cout<<sum[i]<<" "<<x<<" "<<i<<endl;
	}
//	cout<<ans<<endl;
	for(int i=1;i<=n;i++)dfs(1,1,i);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn],d[maxn],e[maxn][43];
vector<int>w;
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y||x<y||y<0)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
void init(){
	for(int i=0;i<w.size();i++)d[w[i]]=0;
	w.clear();
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n,cnt=0;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl){
			init();
			return 0;
		}
		if(!d[a[x]])cnt++,d[a[x]]++,w.push_back(a[x]);
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl){
			init();
			return 0;
		}
		if(!d[b[x]])cnt++,d[b[x]]++,w.push_back(b[x]);
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	return (1LL*e[cnt][sr]-e[cnt][sl-1]+mo)%mo;
}
void dfs(int num,int x){
	if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
	else ans=((ans-work(num-1))%mo+mo)%mo;
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
	}
	for(int i=1;i<=(m<<1);i++){
		for(int j=1;j<=n;j++){
			int x=ss[j];
			e[i][j]=(1LL*e[i][j-1]+1LL*C(x-i,j-i))%mo;
		}
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn],d[maxn];
vector<int>w;
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y||x<y||y<0)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
void init(){
	for(int i=0;i<w.size();i++)d[w[i]]=0;
	w.clear();
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n,sum=0,cnt=0;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl){
			init();
			return 0;
		}
		if(!d[a[x]])cnt++,d[a[x]]++,w.push_back(a[x]);
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl){
			init();
			return 0;
		}
		if(!d[b[x]])cnt++,d[b[x]]++,w.push_back(b[x]);
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	for(int i=sl;i<=sr;i++){
		int x=ss[i];
		sum=(1LL*sum+C(x-cnt,i-cnt))%mo;
	}
	init();
	return sum;
}
void dfs(int num,int x){
	if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
	else ans=((ans-work(num-1))%mo+mo)%mo;
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn],d[maxn],e[maxn][43];
vector<int>w;
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y||x<y||y<0)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
void init(){
	for(int i=0;i<w.size();i++)d[w[i]]=0;
	w.clear();
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n,cnt=0;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl){
			init();
			return 0;
		}
		if(!d[a[x]])cnt++,d[a[x]]++,w.push_back(a[x]);
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl){
			init();
			return 0;
		}
		if(!d[b[x]])cnt++,d[b[x]]++,w.push_back(b[x]);
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	init();
	return (1LL*e[cnt][sr]-e[cnt][sl-1]+mo)%mo;
}
void dfs(int num,int x){
	if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
	else ans=((ans-work(num-1))%mo+mo)%mo;
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
	}
	for(int i=1;i<=(m<<1);i++){
		for(int j=1;j<=n;j++){
			int x=ss[j];
			e[i][j]=(1LL*e[i][j-1]+1LL*C(x-i,j-i))%mo;
			//cout<<e[i][j]<<" ";
		}
	//	cout<<endl;
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn],d[maxn],e[43][maxn];
vector<int>w;
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y||x<y||y<0)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
void init(){
	for(int i=0;i<w.size();i++)d[w[i]]=0;
	w.clear();
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n,cnt=0;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl){
			init();
			return 0;
		}
		if(!d[a[x]])cnt++,d[a[x]]++,w.push_back(a[x]);
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl){
			init();
			return 0;
		}
		if(!d[b[x]])cnt++,d[b[x]]++,w.push_back(b[x]);
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	init();
	return (e[cnt][sr]-e[cnt][sl-1]+mo)%mo;
}
void dfs(int num,int x){
	if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
	else ans=((ans-work(num-1))%mo+mo)%mo;
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
	}
	for(int i=1;i<=2*m;i++){
		for(int j=1;j<=n;j++){
			int x=ss[j];
			e[i][j]=(1LL*e[i][j-1]+1LL*C(x-i,j-i))%mo;
		}
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
const int mo=998244353;
const int maxn=3e5+5;
using namespace std;
int n,m,l[maxn],r[maxn],fac[maxn],inv[maxn],sum[maxn];
int a[maxn],b[maxn],c[maxn],ans,t[maxn],ss[maxn];
int ksm(int a,int b){
	int sum=1;
	for(;b;b>>=1,a=1LL*a*a%mo)if(b&1)sum=1LL*sum*a%mo;
	return sum;
}
int C(int x,int y){
	if(x<y)return 0;
	if(x==y)return 1;
	return 1LL*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
int query(int x){
	int sum=0;
	for(;x;x-=lowbit(x))sum+=t[x];
	return sum;
}
int work(int len){
	if(len<=0)return 0;
	int sl=1,sr=n;
	for(int i=1;i<=len;i++){
		int x=c[i];
		if(l[a[x]]>sr||r[a[x]]<sl)return 0;
		sl=max(sl,l[a[x]]);sr=min(sr,r[a[x]]);
		if(l[b[x]]>sr||r[b[x]]<sl)return 0;
		sl=max(sl,l[b[x]]);sr=min(sr,r[b[x]]);
	}
	return (sum[sr]-sum[sl-1]+mo)%mo;
}
int dfs(int num,int x){
	if(num&1)ans=((ans+work(num-1))%mo+mo)%mo;
	else ans=((ans-work(num-1))%mo+mo)%mo;
	for(int i=x;i<=m;i++){
		c[num]=i;
		dfs(num+1,i+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1LL*i*fac[i-1]%mo;
	inv[n]=ksm(fac[n],mo-2);for(int i=n;i>=1;i--)inv[i-1]=1LL*inv[i]*i%mo;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&l[i],&r[i]);
		t[l[i]]++;t[r[i]+1]--;
	}
	for(int i=1;i<=n;i++)ss[i]=ss[i-1]+t[i];
	for(int i=1;i<=m;i++)scanf("%d %d",&a[i],&b[i]);
	for(int i=1;i<=n;i++){
		int x=ss[i];
		ans=(1ll*ans+1LL*C(x,i))%mo;
		sum[i]=(1LL*sum[i-1]+1LL*C(x-2,i-2))%mo;
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353,maxlen=300000;

int n,m,now,ans=0;
int jc[300005],inv[300005],pre[45][300005],cf[300005];

struct node
{
	int l,r;
}a[300005];

struct node_enemy
{
	int x,y;
}enemy[300005];

int quick_power(int a,int b)
{
	int res=1;
	for (;b;b=b>>1,a=(a*a)%mod)
	{
		if (b&1)  res=(res*a)%mod;
	}
	return res;
}

int C(int x1,int x2)
{
	if (x1<x2)  return 0;
	else if (x1==x2)  return 1;
	else if (x2==0)  return 1;
	return ((jc[x1]*inv[x1-x2])%mod*inv[x2])%mod;
}

inline void init()
{
	jc[0]=1;
	for (int i=1;i<=maxlen;i++)  jc[i]=(jc[i-1]*i)%mod;

	inv[maxlen]=quick_power(jc[maxlen],mod-2);
	for (int i=maxlen-1;i>=1;i--)  inv[i]=(inv[i+1]*(i+1))%mod;
}

signed main()
{
	cin>>n>>m;
	init();
	for (int i=1;i<=n;i++)
	{
		cin>>a[i].l>>a[i].r;
		cf[a[i].l]++,cf[a[i].r+1]--;
	}
	for (int i=1;i<=m;i++)  cin>>enemy[i].x>>enemy[i].y;

	for (int i=1;i<=n;i++)  cf[i]=cf[i-1]+cf[i];
	for (int i=0;i<=2*m;i++)
	{
		for (int j=1;j<=n;j++)  pre[i][j]=pre[i][j-1]+C(cf[j]-i,j-i);
	}
	for (int i=0;i<(1<<m);i++)
	{
		set<int> s;

		int cnt=0,l=1,r=n;
		for (int j=1;j<=m;j++)
		{
			if ((i>>(j-1))&1)
			{
				cnt++;
				s.insert(enemy[j].x),s.insert(enemy[j].y);
				l=max(l,a[enemy[j].x].l),l=max(l,a[enemy[j].y].l);
				r=min(r,a[enemy[j].x].r),r=min(r,a[enemy[j].y].r);
			}
	 	}
		if (l>r)  continue;

		now=((pre[s.size()][r]-pre[s.size()][l-1])%mod+mod)%mod;
		if (cnt%2==0)  ans=(ans+now)%mod;
		else ans=((ans-now)%mod+mod)%mod;
	}
	cout<<ans<<endl;

	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define maxlen 300000
using namespace std;
const int mod=998244353;

int n,m,x,y,tot=0,ans=0;
int cf[300005],cf2[300005],jc[300005];

struct node
{
	int l,r;
}a[300005];

inline void get_find(int x,int y)
{
	int al=a[x].l,ar=a[x].r,bl=a[y].l,br=a[y].r;
	if (al>bl)  swap(al,bl),swap(ar,br);
	if (ar>=bl)  cf2[bl]++,cf[ar+1]--;
}

inline int quick_power(int a,int b)
{
	int res=1;
	for (;b;b=b>>1,a=(a*a)%mod)
	{
		if (b&1)  res=(res*a)%mod;
	}
	return res;
}

inline int ny(int k)
{
	return quick_power(k,mod-2);
}

inline int C(int x,int y)
{
	if (x<y)  return 0;
	return ((jc[x]*ny(jc[y]))%mod*ny(jc[x-y]))%mod;
}

inline int fuckC(int x,int y)
{
	int fft=1;
	for (int i=x;i>=x-y+1;i--)  fft=(fft*i)/(x-i+1);
	return fft;
}

signed main()
{
	cin>>n>>m;
	jc[0]=1;
	for (int i=1;i<=maxlen;i++)  jc[i]=(jc[i-1]*i)%mod;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i].l>>a[i].r;
		cf[a[i].l]++,cf[a[i].r+1]--;
	}
	for (int i=1;i<=m;i++)
	{
		cin>>x>>y;
		get_find(x,y);
	}
	for (int i=1;i<=n;i++)  tot+=cf[i],cf[i]=tot;
	tot=0;
	for (int i=1;i<=n;i++)  tot+=cf2[i],cf2[i]=tot;

	for (int i=1;i<=n;i++)
	{
		int now=cf[i];
		if (now<=20)
		{
			if (fuckC(now,i)<cf2[i])  continue;
		}
		int gx=((C(now,i)-cf2[i])%mod+mod)%mod;
		ans=(ans+gx)%mod;
	}
	cout<<ans<<endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define mes(a,b) memset((a),(b),sizeof((a)))
#define syio std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);
#define lson l, mid, rt << 1
#define rson mid+1, r, rt << 1 | 1
#define lowbit(a) ((a)&-(a))
#define pb push_back
#define mkp make_pair
typedef long long ll;
typedef long double real;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const double pi = acos(-1.0);
const double eps = 1e-8;
const int mxn = 300033;
const int mod = 998244353;
inline int read(){
    int x = 0,f = 1;char c = getchar();
    while(!isdigit(c))f = c == '-' ? -1 : 1,c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x * f;
}
inline ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll ksm(ll a,ll b,ll mod){ll ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);
int dx[] = {0 , 1, 0 , -1};
int dy[] = {1 , 0, -1 , 0};
int n, m;
ll fac[mxn], inv[mxn];
ll l[mxn], r[mxn];
ll num[mxn], sum[mxn][50];
pii d[50];
void init()
{
    fac[0] = 1;
    for (int i = 1; i <= n; ++ i) fac[i] = fac[i - 1]*i%mod;
    inv[n] = ksm(fac[n], mod-2, mod);
    for (int i = n-1; i >= 0; -- i) inv[i] = inv[i + 1]*(i + 1)%mod;
}
ll comb(ll n, ll m)
{
    if (m < 0 || m > n) return 0;
    return fac[n] * inv[m]%mod * inv[n - m]%mod;
}
int count1(ll x)
{
    int cnt = 0;
    while (x)
    {
        cnt ++; x &= (x - 1);
    }
    return cnt;
}
int main()
{
    syio;
    cin>>n>>m;
    init();
    for (int i = 1; i <= n; ++ i)
    {
        cin>>l[i]>>r[i];
        num[l[i]] ++; num[r[i] + 1] --;
    }
    for (int i = 1; i <= n; ++ i)
    num[i] += num[i - 1];

    int a, b;
    for (int i = 0; i < m; ++ i)
    {
        cin>>a>>b; d[i] = mkp(a, b);
    }
    for (int i = 1; i <= n; ++ i)
    for (int j = 0; j <= 2*m; ++ j)
    sum[i][j] = (sum[i - 1][j] + comb(num[i] - j, i - j));

    ll res = 0;
    for (int i = 0; i < (1 << m); ++ i)
    {
        set<int> st;
        for (int j = 0; j < m; ++ j)
        if (i >> j & 1)
        {
            st.insert(d[j].first);
            st.insert(d[j].second);
        }
        int tot = st.size();
        ll dl = 1, dr = n;
        for (auto it : st)
        {
            dl = max(dl, l[it]);
            dr = min(dr, r[it]);
        }
        if (dl > dr) continue;
        ll tmp = (sum[dr][tot] - sum[dl - 1][tot] + mod)%mod;
        if (count1(i) & 1) res = (res - tmp + mod)%mod;
        else res = (res + tmp) %mod;
    }
    cout<<res<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define mes(a,b) memset((a),(b),sizeof((a)))
#define syio std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);
#define lson l, mid, rt << 1
#define rson mid+1, r, rt << 1 | 1
#define lowbit(a) ((a)&-(a))
#define pb push_back
#define mkp make_pair
typedef long long ll;
typedef long double real;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const double pi = acos(-1.0);
const double eps = 1e-8;
const int mxn = 300033;//
const int mod = 998244353;
inline int read(){
    int x = 0,f = 1;char c = getchar();
    while(!isdigit(c))f = c == '-' ? -1 : 1,c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x * f;
}
inline ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll ksm(ll a,ll b,ll mod){ll ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);
int dx[] = {0 , 1, 0 , -1};
int dy[] = {1 , 0, -1 , 0};
ll n, m;
ll fac[mxn], inv[mxn];
int l[mxn], r[mxn];
ll num[mxn], sum[mxn][45];
pair<ll, ll> d[50];
void init()
{
    fac[0] = 1;
    for (int i = 1; i < mxn; ++ i) fac[i] = fac[i - 1] * i%mod;
    inv[mxn - 1] = ksm(fac[mxn - 1], mod - 2, mod);
    for (int i = mxn - 2; i >= 0; -- i)
    inv[i] = inv[i + 1] * (i + 1)%mod;
}
ll comb(ll n, ll m)
{
    if (m < 0 || m > n) return 0;
    return fac[n]*inv[m]%mod*inv[n - m]%mod;
}
int count1(ll x)
{
    int cnt = 0;
    while (x)
    {
        cnt ++; x &= (x - 1);
    }
    return cnt;
}
int main()
{
    syio;
    init();
    cin>>n>>m;
    for (int i = 1; i <= n; ++ i)
    {
        cin>>l[i]>>r[i];
        num[l[i]] ++; num[r[i] + 1] --;
    }
    for (int i = 1; i <= n; ++ i)
    num[i] += num[i - 1];
    for (int i = 0; i < m; ++ i)
    cin>>d[i].first>>d[i].second;

    for (int i = 1; i <= n; ++ i)
    for (int j = 0; j <= 2*m; ++ j)
    sum[i][j] = (sum[i - 1][j] + comb(num[i] - j, i - j))%mod;

    ll res = 0;
    for (int i = 0; i < (1 << m); ++ i)
    {
        set<int> s;
        for (int j = 0; j < m; ++ j)
        if ((i >> j) & 1)
        {
            s.insert(d[j].first); s.insert(d[j].second);
        }
        int tot = s.size();
        int jl = 1, jr = n;
        for (auto it : s)
        {
            jl = max(jl, l[it]);
            jr = min(jr, r[it]);
        }
        if (jl > jr) continue;
        ll tmp = (sum[jr][tot] - sum[jl - 1][tot] + mod)%mod;
        if (count1(i) & 1) res = (res - tmp + mod)%mod;
        else res = (res + tmp)%mod;
    }
    cout<<res<<endl;
    return 0;
}


/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define IN(i, l, r) (l < i && i < r)
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define getI(a) scanf("%d", &a)
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define getS(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define char2Int(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
  cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...)                       \
  {                                          \
    string _s = #args;                       \
    replace(_s.begin(), _s.end(), ',', ' '); \
    stringstream _ss(_s);                    \
    istream_iterator<string> _it(_ss);       \
    err(_it, args);                          \
  }

void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " , ";
  err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

// struct
class UnionFind {
 private:
  vi p, rank, sz;

 public:
  UnionFind(int n) {
    p.assign(n, 0);
    rank.assign(n, 0);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int findSet(int i) { return (i == p[i] ? i : findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        sz[x] += sz[y];
      } else {
        sz[y] += sz[x];
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};

// data
int n, m;
int l[300010], r[300010], a[60], b[60];
int cnt[300010];
int A[300010];
int rv[300010];

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 C(int n, int k) {
  if (k > n || n < 0 || k < 0) return 0;
  return mul(A[n], mul(rv[n - k], rv[k]));
}

int main() {
  getII(n, m);

  REP(i, 0, n) { getII(l[i], r[i]); }
  REP(i, 0, m) { getII(a[i], b[i]); }
  REP(i, 0, n) {
    cnt[l[i]]++;
    cnt[r[i] + 1]--;
  }

  REP(i, 0, n + 1) cnt[i + 1] += cnt[i];
  A[0] = 1;
  REP(i, 1, n + 1) A[i] = mul(A[i - 1], i);
  REP(i, 0, n + 1) rv[i] = inv(A[i]);

  vector<vi> p(2 * m + 1, vi(n + 1));
  REP(i, 1, n + 1) {
    REP(j, 0, 2 * m + 1) { p[j][i] = add(p[j][i - 1], C(cnt[i] - j, i - j)); }
  }
  int ans = 0;
  REP(mask, 0, (1 << m)) {
    int sign = 1;
    set<int> used;
    REP(i, 0, m) {
      if (bit(mask, 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);
  return 0;
}


/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define IN(i, l, r) (l < i && i < r)
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define getI(a) scanf("%d", &a)
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define getS(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define char2Int(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
  cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...)                       \
  {                                          \
    string _s = #args;                       \
    replace(_s.begin(), _s.end(), ',', ' '); \
    stringstream _ss(_s);                    \
    istream_iterator<string> _it(_ss);       \
    err(_it, args);                          \
  }

void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " , ";
  err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

// struct
class UnionFind {
 private:
  vi p, rank, sz;

 public:
  UnionFind(int n) {
    p.assign(n, 0);
    rank.assign(n, 0);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int findSet(int i) { return (i == p[i] ? i : findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        sz[x] += sz[y];
      } else {
        sz[y] += sz[x];
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};

// data
int n, m;
map<int, int> s;
vii nodes;
ll A[300010];
ll rv[300010];
int rr[300010];
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); }

ll C(int n, int k) {
  if (k > n || n < 0 || k < 0) return 0;
  return mul(A[n], mul(rv[n - k], rv[k]));
}

int main() {
  getII(n, m);
  int l, r;
  REP(i, 1, n + 1) {
    getII(l, r);
    nodes.eb(l, -i);
    nodes.eb(r, i);
    rr[i] = r;
  }
  int a, b;
  UnionFind uf(n + 1);
  REP(i, 0, m) {
    getII(a, b);
    uf.unionSet(a, b);
  }
  sort(nodes.begin(), nodes.end());
  A[0] = 1;
  REP(i, 1, n + 1) A[i] = (A[i - 1] * i) % mod;
  REP(i, 0, n + 1) rv[i] = inv(A[i]);

  ll base = 1;
  ll ans = 0;
  // REP(i, 0, nodes.size()) {
  //   if (nodes[i].second < 0) {
  //     // s.insert(uf.findSet(-i));
  //     ++s[uf.findSet(-nodes[i].second)];
  //     // error(i, uf.findSet(-nodes[i].second), s.size());
  //     // if (s.size() >= nodes[i].first) {
  //     //   ans += C(s.size() - 1, nodes[i].first - 1);
  //     //   ans %= mod;
  //     //   // error(i, ans, nodes[i].ff, nodes[i].ss);
  //     // }
  //     REP(k, nodes[i].first, s.size() + 1) {
  //       ans += C(s.size() - 1, k - 1);
  //       ans %= mod;
  //     }
  //   } else {
  //     --s[uf.findSet(nodes[i].second)];
  //     if (s[uf.findSet(nodes[i].second)] == 0)
  //       s.erase(uf.findSet(nodes[i].second));
  //   }
  // }
  int j = 0;
  REP(i, 1, n + 1) {
    while (j < nodes.size() && nodes[j].second < 0 && nodes[j].first == i) {
      ++s[uf.findSet(-nodes[j].second)];
      ++j;
    }
    ans += C(s.size(), i);
    // error(i, ans, s.size(), C(s.size(), i));
    while (j < nodes.size() && nodes[j].first == i) {
      int u = uf.findSet(nodes[j].second);
      --s[u];
      if (s[u] == 0) s.erase(u);
      ++j;
    }
  }
  printf("%lld\n", ans);
  return 0;
}


/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define IN(i, l, r) (l < i && i < r)
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define getI(a) scanf("%d", &a)
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define getS(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define char2Int(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
  cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...)                       \
  {                                          \
    string _s = #args;                       \
    replace(_s.begin(), _s.end(), ',', ' '); \
    stringstream _ss(_s);                    \
    istream_iterator<string> _it(_ss);       \
    err(_it, args);                          \
  }

void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " , ";
  err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

// struct
class UnionFind {
 private:
  vi p, rank, sz;

 public:
  UnionFind(int n) {
    p.assign(n, 0);
    rank.assign(n, 0);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int findSet(int i) { return (i == p[i] ? i : findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        sz[x] += sz[y];
      } else {
        sz[y] += sz[x];
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};

// data
int n, m;
map<int, int> s;
vii nodes;
ll A[300010];
static int mod_inv(int a, int m = mod) {
  // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
  int g = m, r = a, x = 0, y = 1;

  while (r != 0) {
    int q = g / r;
    g %= r;
    swap(g, r);
    x -= q * y;
    swap(x, y);
  }

  return x < 0 ? x + m : x;
}

ll C(int n, int k) {
  if (k == 0) return 1;
  return (A[n] * mod_inv(k)) % mod;
}

int main() {
  getII(n, m);
  int l, r;
  REP(i, 1, n + 1) {
    getII(l, r);
    nodes.eb(l, -i);
    nodes.eb(r, i);
  }
  int a, b;
  UnionFind uf(n + 1);
  REP(i, 0, m) {
    getII(a, b);
    uf.unionSet(a, b);
  }
  sort(nodes.begin(), nodes.end());
  A[0] = 1;
  REP(i, 1, n + 1) A[i] = (A[i - 1] * i) % mod;
  ll base = 1;
  ll ans = 0;
  REP(i, 0, nodes.size()) {
    if (nodes[i].second < 0) {
      // s.insert(uf.findSet(-i));
      ++s[uf.findSet(-nodes[i].second)];
      // error(i, uf.findSet(-nodes[i].second), s.size());
      if (s.size() >= nodes[i].first) {
        ans += C(s.size() - 1, nodes[i].first - 1);
        ans %= mod;
        // error(i, ans, nodes[i].ff, nodes[i].ss);
      }
    } else {
      --s[uf.findSet(nodes[i].second)];
      if (s[uf.findSet(nodes[i].second)] == 0)
        s.erase(uf.findSet(nodes[i].second));
    }
  }
  printf("%lld\n", ans);
  return 0;
}


/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define IN(i, l, r) (l < i && i < r)
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define getI(a) scanf("%d", &a)
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define getS(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define char2Int(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
  cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...)                       \
  {                                          \
    string _s = #args;                       \
    replace(_s.begin(), _s.end(), ',', ' '); \
    stringstream _ss(_s);                    \
    istream_iterator<string> _it(_ss);       \
    err(_it, args);                          \
  }

void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " , ";
  err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

// struct
class UnionFind {
 private:
  vi p, rank, sz;

 public:
  UnionFind(int n) {
    p.assign(n, 0);
    rank.assign(n, 0);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int findSet(int i) { return (i == p[i] ? i : findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        sz[x] += sz[y];
      } else {
        sz[y] += sz[x];
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};

// data
int n, m;
map<int, int> s;
vii nodes;
ll A[300010];
int rr[300010];
static int mod_inv(int a, int m = mod) {
  // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
  int g = m, r = a, x = 0, y = 1;

  while (r != 0) {
    int q = g / r;
    g %= r;
    swap(g, r);
    x -= q * y;
    swap(x, y);
  }

  return x < 0 ? x + m : x;
}

ll C(int n, int k) {
  if (k > n || n < 0 || k < 0) return 0;
  if (k == 0) return 1;
  return ((A[n] * mod_inv(k)) % mod * mod_inv(n-k)) % mod;
}

int main() {
  getII(n, m);
  int l, r;
  REP(i, 1, n + 1) {
    getII(l, r);
    nodes.eb(l, -i);
    nodes.eb(r, i);
    rr[i] = r;
  }
  int a, b;
  UnionFind uf(n + 1);
  REP(i, 0, m) {
    getII(a, b);
    uf.unionSet(a, b);
  }
  sort(nodes.begin(), nodes.end());
  A[0] = 1;
  REP(i, 1, n + 1) A[i] = (A[i - 1] * i) % mod;
  ll base = 1;
  ll ans = 0;
  // REP(i, 0, nodes.size()) {
  //   if (nodes[i].second < 0) {
  //     // s.insert(uf.findSet(-i));
  //     ++s[uf.findSet(-nodes[i].second)];
  //     // error(i, uf.findSet(-nodes[i].second), s.size());
  //     // if (s.size() >= nodes[i].first) {
  //     //   ans += C(s.size() - 1, nodes[i].first - 1);
  //     //   ans %= mod;
  //     //   // error(i, ans, nodes[i].ff, nodes[i].ss);
  //     // }
  //     REP(k, nodes[i].first, s.size() + 1) {
  //       ans += C(s.size() - 1, k - 1);
  //       ans %= mod;
  //     }
  //   } else {
  //     --s[uf.findSet(nodes[i].second)];
  //     if (s[uf.findSet(nodes[i].second)] == 0)
  //       s.erase(uf.findSet(nodes[i].second));
  //   }
  // }
  int j = 0;
  REP(i, 1, n + 1) {
    while (j < nodes.size() && nodes[j].second < 0 && nodes[j].first == i) {
      ++s[uf.findSet(-nodes[j].second)];
      ++j;
    }
    ans += C(s.size(), i);
    while (j < nodes.size() && nodes[j].first == i) {
      int u = uf.findSet(nodes[j].second);
      --s[u];
      if (s[u] == 0) s.erase(u);
      ++j;
    }
  }
  printf("%lld\n", ans);
  return 0;
}


/*
ID: leezhen
TASK: practice
LANG: C++11
*/
#include <assert.h>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<pair<int, int> > vii;
typedef long long ll;
#define bit(x, i) (x & (1 << i))
#define IN(i, l, r) (l < i && i < r)
#define LINR(i, l, r) (l <= i && i <= r)
#define LIN(i, l, r) (l <= i && i < r)
#define INR(i, l, r) (l < i && i <= r)
#define getI(a) scanf("%d", &a)
#define getII(a, b) scanf("%d%d", &a, &b)
#define getIII(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define getS(x) scanf("%s", x)
#define clr(a, x) memset(a, x, sizeof(a))
#define char2Int(c) (c - '0')
#define sz(x) ((int)((x).size()))
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
// for debug
#define what_is(x) \
  cerr << "Line " << __LINE__ << ": " << #x << " is " << (x) << endl;
#define error(args...)                       \
  {                                          \
    string _s = #args;                       \
    replace(_s.begin(), _s.end(), ',', ' '); \
    stringstream _ss(_s);                    \
    istream_iterator<string> _it(_ss);       \
    err(_it, args);                          \
  }

void err(istream_iterator<string> it) { cerr << endl; }
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << " , ";
  err(++it, args...);
}
#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

// struct
class UnionFind {
 private:
  vi p, rank, sz;

 public:
  UnionFind(int n) {
    p.assign(n, 0);
    rank.assign(n, 0);
    sz.assign(n, 1);
    for (int i = 0; i < n; i++) p[i] = i;
  }
  int findSet(int i) { return (i == p[i] ? i : findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        sz[x] += sz[y];
      } else {
        sz[y] += sz[x];
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};

// data
int n, m;
map<int, int> s;
vii nodes;
ll A[300010];
int rr[300010];
static int mod_inv(int a, int m = mod) {
  // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
  int g = m, r = a, x = 0, y = 1;

  while (r != 0) {
    int q = g / r;
    g %= r;
    swap(g, r);
    x -= q * y;
    swap(x, y);
  }

  return x < 0 ? x + m : x;
}

ll C(int n, int k) {
  if (k > n) return 0;
  if (k == 0) return 1;
  return (A[n] * mod_inv(k)) % mod;
}

int main() {
  getII(n, m);
  int l, r;
  REP(i, 1, n + 1) {
    getII(l, r);
    nodes.eb(l, -i);
    nodes.eb(r, i);
    rr[i] = r;
  }
  int a, b;
  UnionFind uf(n + 1);
  REP(i, 0, m) {
    getII(a, b);
    uf.unionSet(a, b);
  }
  sort(nodes.begin(), nodes.end());
  A[0] = 1;
  REP(i, 1, n + 1) A[i] = (A[i - 1] * i) % mod;
  ll base = 1;
  ll ans = 0;
  // REP(i, 0, nodes.size()) {
  //   if (nodes[i].second < 0) {
  //     // s.insert(uf.findSet(-i));
  //     ++s[uf.findSet(-nodes[i].second)];
  //     // error(i, uf.findSet(-nodes[i].second), s.size());
  //     // if (s.size() >= nodes[i].first) {
  //     //   ans += C(s.size() - 1, nodes[i].first - 1);
  //     //   ans %= mod;
  //     //   // error(i, ans, nodes[i].ff, nodes[i].ss);
  //     // }
  //     REP(k, nodes[i].first, s.size() + 1) {
  //       ans += C(s.size() - 1, k - 1);
  //       ans %= mod;
  //     }
  //   } else {
  //     --s[uf.findSet(nodes[i].second)];
  //     if (s[uf.findSet(nodes[i].second)] == 0)
  //       s.erase(uf.findSet(nodes[i].second));
  //   }
  // }
  int j = 0;
  REP(i, 1, n + 1) {
    while (j < nodes.size() && nodes[j].second < 0 && nodes[j].first == i) {
      ++s[uf.findSet(-nodes[j].second)];
      ++j;
    }
    ans += C(s.size(), i);
    while (j < nodes.size() && nodes[j].first == i) {
      int u = uf.findSet(nodes[j].second);
      --s[u];
      if (s[u] == 0) s.erase(u);
      ++j;
    }
  }
  printf("%lld\n", ans);
  return 0;
}