#include using namespace std; using Int = long long; template inline void chmin(T1 &a,T2 b){if(a>b) a=b;} template inline void chmax(T1 &a,T2 b){if(a struct Mint{ static constexpr T mod = MOD; T v; Mint():v(0){} Mint(signed v):v(v){} Mint(long long t){v=t%MOD;if(v<0) v+=MOD;} Mint pow(long long k){ Mint res(1),tmp(v); while(k){ if(k&1) res*=tmp; tmp*=tmp; k>>=1; } return res; } static Mint add_identity(){return Mint(0);} static Mint mul_identity(){return Mint(1);} Mint inv(){return pow(MOD-2);} Mint& operator+=(Mint a){v+=a.v;if(v>=MOD)v-=MOD;return *this;} Mint& operator-=(Mint a){v+=MOD-a.v;if(v>=MOD)v-=MOD;return *this;} Mint& operator*=(Mint a){v=1LL*v*a.v%MOD;return *this;} Mint& operator/=(Mint a){return (*this)*=a.inv();} Mint operator+(Mint a) const{return Mint(v)+=a;}; Mint operator-(Mint a) const{return Mint(v)-=a;}; Mint operator*(Mint a) const{return Mint(v)*=a;}; Mint operator/(Mint a) const{return Mint(v)/=a;}; Mint operator-() const{return v?Mint(MOD-v):Mint(v);} bool operator==(const Mint a)const{return v==a.v;} bool operator!=(const Mint a)const{return v!=a.v;} bool operator <(const Mint a)const{return v constexpr T Mint::mod; template ostream& operator<<(ostream &os,Mint m){os< V compress(V v){ sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); return v; } template map dict(const vector &v){ map res; for(int i=0;i<(int)v.size();i++) res[v[i]]=i; return res; } map dict(const string &v){ return dict(vector(v.begin(),v.end())); } namespace FFT{ using dbl = double; struct num{ dbl x,y; num(){x=y=0;} num(dbl x,dbl y):x(x),y(y){} }; inline num operator+(num a,num b){ return num(a.x+b.x,a.y+b.y); } inline num operator-(num a,num b){ return num(a.x-b.x,a.y-b.y); } inline num operator*(num a,num b){ return num(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); } inline num conj(num a){ return num(a.x,-a.y); } int base=1; vector rts={{0,0},{1,0}}; vector rev={0,1}; const dbl PI=acosl(-1.0); void ensure_base(int nbase){ if(nbase<=base) return; rev.resize(1<>1]>>1)+((i&1)<<(nbase-1)); rts.resize(1< &a,int n=-1){ if(n==-1) n=a.size(); assert((n&(n-1))==0); int zeros=__builtin_ctz(n); ensure_base(zeros); int shift=base-zeros; for(int i=0;i>shift)) swap(a[i],a[rev[i]>>shift]); for(int k=1;k fa; vector multiply(vector &a,vector &b){ int need=a.size()+b.size()-1; int nbase=0; while((1<(int)fa.size()) fa.resize(sz); for(int i=0;i>1);i++){ int j=(sz-i)&(sz-1); num z=(fa[j]*fa[j]-conj(fa[i]*fa[i]))*r; if(i!=j) fa[j]=(fa[i]*fa[i]-conj(fa[j]*fa[j]))*r; fa[i]=z; } fft(fa,sz); vector res(need); for(int i=0;i struct ArbitraryModConvolution{ using dbl=FFT::dbl; using num=FFT::num; vector multiply(vector as,vector bs){ int need=as.size()+bs.size()-1; int sz=1; while(sz fa(sz),fb(sz); for(int i=0;i<(int)as.size();i++) fa[i]=num(as[i].v&((1<<15)-1),as[i].v>>15); for(int i=0;i<(int)bs.size();i++) fb[i]=num(bs[i].v&((1<<15)-1),bs[i].v>>15); fft(fa,sz);fft(fb,sz); dbl ratio=0.25/sz; num r2(0,-1),r3(ratio,0),r4(0,-ratio),r5(0,1); for(int i=0;i<=(sz>>1);i++){ int j=(sz-i)&(sz-1); num a1=(fa[i]+conj(fa[j])); num a2=(fa[i]-conj(fa[j]))*r2; num b1=(fb[i]+conj(fb[j]))*r3; num b2=(fb[i]-conj(fb[j]))*r4; if(i!=j){ num c1=(fa[j]+conj(fa[i])); num c2=(fa[j]-conj(fa[i]))*r2; num d1=(fb[j]+conj(fb[i]))*r3; num d2=(fb[j]-conj(fb[i]))*r4; fa[i]=c1*d1+c2*d2*r5; fb[i]=c1*d2+c2*d1; } fa[j]=a1*b1+a2*b2*r5; fb[j]=a1*b2+a2*b1; } fft(fa,sz);fft(fb,sz); vector cs(need); using ll = long long; for(int i=0;i struct FormalPowerSeries{ using Poly = vector; using Conv = function; Conv conv; FormalPowerSeries(Conv conv):conv(conv){} Poly pre(const Poly &as,int deg){ return Poly(as.begin(),as.begin()+min((int)as.size(),deg)); } Poly add(Poly as,Poly bs){ int sz=max(as.size(),bs.size()); Poly cs(sz,T(0)); for(int i=0;i<(int)as.size();i++) cs[i]+=as[i]; for(int i=0;i<(int)bs.size();i++) cs[i]+=bs[i]; return cs; } Poly sub(Poly as,Poly bs){ int sz=max(as.size(),bs.size()); Poly cs(sz,T(0)); for(int i=0;i<(int)as.size();i++) cs[i]+=as[i]; for(int i=0;i<(int)bs.size();i++) cs[i]-=bs[i]; return cs; } Poly mul(Poly as,Poly bs){ return conv(as,bs); } Poly mul(Poly as,T k){ for(auto &a:as) a*=k; return as; } // F(0) must not be 0 Poly inv(Poly as,int deg){ assert(as[0]!=T(0)); Poly rs({T(1)/as[0]}); for(int i=1;ias.size()) return Poly(); reverse(as.begin(),as.end()); reverse(bs.begin(),bs.end()); int need=as.size()-bs.size()+1; Poly ds=pre(mul(as,inv(bs,need)),need); reverse(ds.begin(),ds.end()); return ds; } // F(0) must be 1 Poly sqrt(Poly as,int deg){ assert(as[0]==T(1)); T inv2=T(1)/T(2); Poly ss({T(1)}); for(int i=1;i class Enumeration{ private: static vector fact,finv,invs; public: static void init(int n){ n=min(n,M::mod-1); int m=fact.size(); if(n=m;i--) finv[i-1]=finv[i]*M(i); for(int i=m;i<=n;i++) invs[i]=finv[i]*fact[i-1]; } static M Fact(int n){ init(n); return fact[n]; } static M Finv(int n){ init(n); return finv[n]; } static M Invs(int n){ init(n); return invs[n]; } static M C(int n,int k){ if(n > D(int n,int m){ vector< vector > dp(n+1,vector(m+1,0)); dp[0][0]=M(1); for(int i=0;i<=n;i++){ for(int j=1;j<=m;j++){ if(i-j>=0) dp[i][j]=dp[i][j-1]+dp[i-j][j]; else dp[i][j]=dp[i][j-1]; } } return dp; } static M B(int n,int k){ if(n==0) return M(1); k=min(k,n); init(k); vector dp(k+1); dp[0]=M(1); for(int i=1;i<=k;i++) dp[i]=dp[i-1]+((i&1)?-finv[i]:finv[i]); M res(0); for(int i=1;i<=k;i++) res+=M(i).pow(n)*finv[i]*dp[k-i]; return res; } static M montmort(int n){ init(n); M res(0); for(int k=2;k<=n;k++){ if(k&1) res-=finv[k]; else res+=finv[k]; } return res*=fact[n]; } static M LagrangePolynomial(vector &y,M t){ int n=y.size()-1; if(t.v<=n) return y[t.v]; init(n+1); vector dp(n+1,1),pd(n+1,1); for(int i=0;i0;i--) pd[i-1]=pd[i]*(t-M(i)); M res(0); for(int i=0;i<=n;i++){ M tmp=y[i]*dp[i]*pd[i]*finv[i]*finv[n-i]; if((n-i)&1) res-=tmp; else res+=tmp; } return res; } }; template vector Enumeration::fact=vector(); template vector Enumeration::finv=vector(); template vector Enumeration::invs=vector(); //INSERT ABOVE HERE signed main(){ int n; cin>>n; vector as(n),bs(n); for(int i=0;i>as[i]>>bs[i]; vector vs; for(int a:as) vs.emplace_back(a); for(int b:bs) vs.emplace_back(b); vs.emplace_back(0); vs.emplace_back(1e9+6); vs=compress(vs); auto dc=dict(vs); int sz=dc.size(); const int MOD = 1e9+7; using M = Mint; ArbitraryModConvolution arb; FormalPowerSeries FPS([&](auto as,auto bs){return arb.multiply(as,bs);}); using Poly = FormalPowerSeries::Poly; Poly sum; const int deg = 1<<7; for(int l=0;l; E::init(deg); //for(int i=0;i<10;i++) cout< > dp(n+1,vector(sz,0)); for(int j=0;j+1 > nx(n+1,vector(sz,0)); if(i&1){ for(int l=1;l=0;k--) nx[1][k]+=sum[l]*dp[l][j] *M(as[i]<=vs[k]&&vs[k+1]<=bs[i])*M(vs[k+1]-vs[k])*rev; } } } swap(dp,nx); } M ans{0}; for(int i=1;i<=n;i++) for(int j=0;j+1