1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <string>
#include <cstring>

#define REP(a,n) for (int a = 0; a<(n); ++a)
#define FOR(a,b,c) for (int a = (b); a<=(c); ++a)
#define FORD(a,b,c) for (int a = (b); a>=(c); --a)
#define FOREACH(a,v) for (auto a : v)

#define MP make_pair
#define PB push_back

template<class T> inline int size(const T&t) { return t.size(); }

using namespace std;

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<string> vs;
typedef long long LL;

///////////////////////////////

#define INF 1'000'000'000'000'000'000LL
#define MOD 1'000'000'007
#define SIZE (1<<19)

int N;
LL pos[SIZE] = {-INF-1}, zas[SIZE];
int pocz[SIZE], kon[SIZE];
vi kraw[SIZE];
int wyn_nie[SIZE] = {1}, wyn_tak[SIZE];
vi start_tu[SIZE];
int otw[2*SIZE], lmst[2*SIZE], rmst[2*SIZE];

int suma_do(int stop, int p = 1, int s = SIZE) {
  if (stop == s)
    return otw[p];
  p *= 2;
  s /= 2;
  if (stop <= s)
    return suma_do(stop, p, s);
  else
    return (otw[p] + suma_do(stop - s, p + 1, s)) % MOD;
}

void wstaw(int p, int val) {
  p += SIZE;
  while (p) {
    otw[p] = (otw[p] + val) % MOD;
    p /= 2;
  }
}

inline int suma(int start, int stop) { // wliczamy start, nie wliczamy stop
  return (suma_do(stop) + MOD - (start ? suma_do(start) : 0)) % MOD;
}

inline int daj_lewy(int a, int b) {
  return pocz[a] < pocz[b] ? a : b;
}

inline int daj_prawy(int a, int b) {
  return kon[a] > kon[b] ? a : b;
}

pii najb_para(int start, int stop, int p = 1, int s = SIZE) {
  if (!start && stop == s)
    return MP(lmst[p], rmst[p]);
  p *= 2;
  s /= 2;
  if (stop <= s)
    return najb_para(start, stop, p, s);
  else
  if (start >= s)
    return najb_para(start - s, stop - s, p + 1, s);
  else {
    pii x = najb_para(start, s, p, s);
    pii y = najb_para(0, stop - s, p + 1, s);
    return MP(daj_lewy(x.first, y.first), daj_prawy(x.second, y.second));
  }
}

int najb_lewy(int start, int stop, int p = 1, int s = SIZE) {
  if (!start && stop == s)
    return lmst[p];
  p *= 2;
  s /= 2;
  if (stop <= s)
    return najb_lewy(start, stop, p, s);
  else
  if (start >= s)
    return najb_lewy(start - s, stop - s, p + 1, s);
  else
    return daj_lewy(najb_lewy(start, s, p, s), najb_lewy(0, stop - s, p + 1, s));
}

int najb_prawy(int start, int stop, int p = 1, int s = SIZE) {
  if (!start && stop == s)
    return rmst[p];
  p *= 2;
  s /= 2;
  if (stop <= s)
    return najb_prawy(start, stop, p, s);
  else
  if (start >= s)
    return najb_prawy(start - s, stop - s, p + 1, s);
  else
    return daj_prawy(najb_prawy(start, s, p, s), najb_prawy(0, stop - s, p + 1, s));
}

void licz_lewe() {
  priority_queue<pii> Q;
  REP(a, N + 2)
    Q.emplace(-pocz[a], a);
  while (!Q.empty()) {
    int nr = Q.top().second;
    int _pocz = -Q.top().first;
    Q.pop();
    if (pocz[nr] != _pocz)
      continue;
    for (int a : kraw[nr])
      if (pocz[nr] < pocz[a]) {
        pocz[a] = pocz[nr];
        Q.emplace(-pocz[a], a);
      }
  }
}

void licz_prawe() {
  priority_queue<pii> Q;
  REP(a, N + 2)
    Q.emplace(kon[a], a);
  while (!Q.empty()) {
    int nr = Q.top().second;
    int _kon = Q.top().first;
    Q.pop();
    if (kon[nr] != _kon)
      continue;
    for (int a : kraw[nr])
      if (kon[nr] > kon[a]) {
        kon[a] = kon[nr];
        Q.emplace(kon[a], a);
      }
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  cin >> N;
  FOR(a, 1, N)
    cin >> pos[a] >> zas[a];
  pos[N + 1] = 2 * INF + 1;

  // liczę pocz i kon
  REP(a, N + 2)
    pocz[a] = lower_bound(pos, pos + N + 2, pos[a] - zas[a]) - pos;
  REP(a, N + 2)
    kon[a] = upper_bound(pos, pos + N + 2, pos[a] + zas[a]) - pos;
  REP(a, SIZE)
    lmst[SIZE + a] = rmst[SIZE + a] = min(a, N + 1);
  FORD(p, SIZE - 1, 1) {
    lmst[p] = daj_lewy(lmst[2 * p], lmst[2 * p + 1]);
    rmst[p] = daj_prawy(rmst[2 * p], rmst[2 * p + 1]);
  }
  REP(a, N + 2) {
//    cerr << a << " impl bezp. " << pocz[a] << " - " << kon[a] - 1 << "; najb. lewy " << najb_lewy(pocz[a], kon[a]) << ", najb. prawy " << najb_prawy(pocz[a], kon[a]) << endl;
    pii pp = najb_para(pocz[a], kon[a]);
//    int nl = najb_lewy(pocz[a], kon[a]);
//    int np = najb_prawy(pocz[a], kon[a]);
    int nl = pp.first, np = pp.second;
    kraw[nl].PB(a);
    if (np != nl)
      kraw[np].PB(a);
  }
  licz_lewe();
  licz_prawe();
/*  REP(a, N + 2) {
//    cerr << a << " implikuje " << pocz[a] << " - " << kon[a] - 1 << endl;
    kraw[a].clear();
  }*/
  set<pii> byly;
  FOR(a, 1, N)
    if (byly.find(MP(pocz[a], kon[a])) == byly.end()) {
      byly.emplace(pocz[a], kon[a]);
      start_tu[pocz[a]].PB(a);
    }
  FOR(a, 1, N + 1) {
    wyn_nie[a] = (wyn_nie[a - 1] + suma(a - 1, a)) % MOD;
    for (auto x : start_tu[a])
      wyn_tak[x] = (wyn_nie[a - 1] + suma(a - 1, kon[x] - 1)) % MOD;
    for (auto x : start_tu[a])
      wstaw(kon[x] - 1, wyn_tak[x]);
  }
//  REP(a, N + 2)
//    cerr << a << ", wyn_nie " << wyn_nie[a] << ", wyn_tak " << wyn_tak[a] << endl;
  cout << wyn_nie[N + 1] << endl;
}