#include<bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)
typedef long long LL;
int N;
LL X[200001];
LL V[200001];
//各頂点に対して区間を作る
LL L[200001];
LL R[200001];

map<LL,LL>v;
map<LL,LL>v2;

const LL MAX_N = 1 << 20;
LL MOD=1e9+7;

//セグメント木を持つグローバル配列
LL n,dat[2*MAX_N-1],dat_ma[2*MAX_N-1],dat_sa[2*MAX_N-1];

//初期化
void init(LL n_){
   //簡単のために要素数を2のべき乗に
   n=1;
   while(n<n_) n*=2;
   //全ての値をINT_MAXに
   for(LL i=0;i<2*n-1;i++){
       dat[i]=1e10;
       dat_ma[i]=-100;
       dat_sa[i]=0;
   }
}

//k番目の値(0-indexed)をaに変更
void update(LL k,LL a){
   //葉の節点
   k+=n-1;
  dat[k]=a;
  dat_ma[k]=a;
  dat_sa[k]=a;
  //登りながら更新
  while(k>0){
     k=(k-1)/2;
     dat[k] = min(dat[k*2+1],dat[k*2+2]);
     dat_ma[k]=max(dat_ma[k*2+1],dat_ma[k*2+2]);
     dat_sa[k]=dat_sa[k*2+1]+dat_sa[k*2+2];
  }
}
//[a,b)の最小値を求める
//後ろの方の引数は、計算の簡単のための引数
//kは節点の番号、l,rはその接点が[l,r)に対応していることを表す
//従って外からはquery(a,b,0,0,nと呼ぶ)
LL query(int a,int b,int k,int l,int r){
    //[a,b)と[l,r)が交差しなければINT_MAX
    if(r<=a||b<=l) return 1e10;
    //[a,b)が[l,r)を完全に含んでいればこの接点の値
    if(a<=l&&r<=b) return dat[k];
    else{
       //そうでなければ、2つの子の最小値
       LL vl =query(a,b,k*2+1,l,(l+r)/2);
       LL vr =query(a,b,k*2+2,(l+r)/2,r);
       return min(vl,vr);
    }
}

//[a,b)の最大値を求める
//後ろの方の引数は、計算の簡単のための引数
//kは節点の番号、l,rはその接点が[l,r)に対応していることを表す
//従って外からはquery(a,b,0,0,nと呼ぶ)
LL query_ma(int a,int b,int k,int l,int r){
    //[a,b)と[l,r)が交差しなければINT_MAX
    if(r<=a||b<=l) return -1000;
    //[a,b)が[l,r)を完全に含んでいればこの接点の値
    if(a<=l&&r<=b) return dat_ma[k];
    else{
       //そうでなければ、2つの子の最大値
       LL vl =query_ma(a,b,k*2+1,l,(l+r)/2);
       LL vr =query_ma(a,b,k*2+2,(l+r)/2,r);
       return max(vl,vr);
    }
}

//[a,b)の最大値を求める
//後ろの方の引数は、計算の簡単のための引数
//kは節点の番号、l,rはその接点が[l,r)に対応していることを表す
//従って外からはquery(a,b,0,0,nと呼ぶ)
LL query_sa(int a,int b,int k,int l,int r){
    //[a,b)と[l,r)が交差しなければINT_MAX
    if(r<=a||b<=l) return 0;
    //[a,b)が[l,r)を完全に含んでいればこの接点の値
    if(a<=l&&r<=b) return dat_sa[k];
    else{
       //そうでなければ、2つの子の最大値
       LL vl =query_sa(a,b,k*2+1,l,(l+r)/2);
       LL vr =query_sa(a,b,k*2+2,(l+r)/2,r);
       return (vl+vr)%MOD;
    }
}


typedef pair<LL,LL> P;

int main(){
    cin>>N;
    REP(i,N){
        cin>>X[i]>>V[i];
        v[X[i]]=0;
        v2[V[i]]=0;
    }
    int count=1;
    for(auto it=v.begin();it!=v.end();it++){
        it->second=count;
        count++;
    }
    count=1;
    for(auto it=v2.begin();it!=v2.end();it++){
        it->second=count;
        count++;
    }

    //セグ木の初期化
    init(N+10);
    //座圧してセグ木につっこむ
    REP(i,N){
       X[i]=v[X[i]];
       V[i]=v2[V[i]];
       update(X[i],V[i]);
    }
    //各クエリを取得
    vector<P> nobu;
    REP(i,N){
       L[i]=query(X[i],n,0,0,n);
       R[i]=query_ma(0,X[i]+1,0,0,n);
       nobu.push_back(P(L[i],R[i]));
      // cout<<"aa"<<L[i]<<"bb"<<R[i]<<endl;
    }
    sort(nobu.begin(),nobu.end());
    
    init(N+10);
    update(0,1);
    REP(i,nobu.size()){
        /*REP(j,10){
            cout<<query_sa(j,j+1,0,0,n)<<" ";
        }
        cout<<endl;
        REP(j,10){
            cout<<query_sa(0,j+1,0,0,n)<<" ";
        }
        cout<<endl<<endl;*/
        update(nobu[i].second,(query_sa(nobu[i].first-1,n,0,0,n)+query_sa(nobu[i].second,nobu[i].second+1,0,0,n))%MOD);
    }
    //cout<<n<<endl;
    cout<<(query_sa(N,N+1,0,0,n))%MOD<<endl;
    
    
    return(0);
}

Measured memory_bytes: 56180