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
// clang-format off
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("popcnt")
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
using namespace std;
template<class Fun>
class y_combinator_result {
    Fun fun_;
public:
    template<class T> explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {}
    template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(ref(*this), forward<Args>(args)...); }
};
template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun)); }
// using namespace __gnu_pbds;
// template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef XOX
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) { ris << "(" << d.first << ", " << d.second << ")"; }
sim dor(rge<c> d) { *this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]"; }
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
struct { template <class T> operator T() { T x; cin >> x; return x; } } in;
#define endl '\n'
#define pb emplace_back
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
using i64 = long long;
template <class T> using vt = vector<T>;
template <class T, size_t n> using ar = array<T, n>;
namespace R = ranges;
auto ra(auto x, auto y) { return R::iota_view(x, y); }
auto rae(auto x, auto y) { return ra(x, y + 1); }
// #define int long long
template <class T>
T power(T a, i64 b) { T res = 1; for (; b; b /= 2, a *= a) if (b % 2) res *= a; return res; }
template <int P>
struct MInt {
    int x;
    MInt() : x{} {}
    MInt(i64 _x) : x{norm(_x % P)} {}
    int norm(int _x) const { if (_x < 0) _x += P; if (_x >= P) _x -= P; return _x; }
    int val() const { return x; }
    explicit operator int() const { return x; }
    MInt operator-() const { MInt res; res.x = norm(P - x); return res; }
    MInt inv() const { assert(x != 0); return power(*this, P - 2); }
    MInt &operator*=(MInt rhs) { x = (i64)x * rhs.x % P; return *this; }
    MInt &operator+=(MInt rhs) { x = norm(x + rhs.x); return *this; }
    MInt &operator-=(MInt rhs) { x = norm(x - rhs.x); return *this; }
    MInt &operator/=(MInt rhs) { return *this *= rhs.inv(); }
    friend MInt operator*(MInt lhs, MInt rhs) { MInt res = lhs; res *= rhs; return res; }
    friend MInt operator+(MInt lhs, MInt rhs) { MInt res = lhs; res += rhs; return res; }
    friend MInt operator-(MInt lhs, MInt rhs) { MInt res = lhs; res -= rhs; return res; }
    friend MInt operator/(MInt lhs, MInt rhs) { MInt res = lhs; res /= rhs; return res; }
    friend istream &operator>>(istream &is, MInt &a) { i64 v; is >> v; a = MInt(v); return is; }
    friend ostream &operator<<(ostream &os, const MInt &a) { return os << a.val(); }
    friend bool operator==(MInt lhs, MInt rhs) { return lhs.val() == rhs.val(); }
    friend bool operator!=(MInt lhs, MInt rhs) { return lhs.val() != rhs.val(); }
};
const int P = 1000 * 1000 * 1000 + 7;
using Z = MInt<P>;
struct Combo {
    vt<Z> fact, ifact;
    Combo(int n) : fact(n + 1), ifact(n + 1) {
        fact[0] = 1;
        for (int i : ra(1, n + 1)) fact[i] = fact[i - 1] * i;
        ifact[n] = fact[n].inv();
        for (int i = n; i > 0; i--) ifact[i - 1] = ifact[i] * i;
    }
    Z c(int n, int k) const {
        if (k < 0 || k > n) return 0;
        return fact[n] * ifact[k] * ifact[n - k];
    }
    Z f(int n) const { return fact[n]; }
    Z ifc(int n) const { return ifact[n]; }
};
// clang-format on

struct Tree {
    struct Node {
        int val, lazy;
    };
    int n;
    vt<Node> t;
    Tree(int n_, int def) : n(n_), t(4 * n_, {def, def}) {}
    void push(int v, int l, int r) {
        if (l == r || t[v].lazy == -1) return;
        t[2 * v].lazy = t[2 * v + 1].lazy = t[v].lazy;
        t[2 * v].val = t[2 * v + 1].val = t[v].lazy;
        t[v].lazy = -1;
    }
    void set(int v, int l, int r, int L, int R, int x) {
        if (r < L || R < l) return;
        if (L <= l && r <= R) {
            t[v].val = x;
            t[v].lazy = x;
            return;
        }
        push(v, l, r);
        int m = (l + r) / 2;
        set(2 * v, l, m, L, R, x);
        set(2 * v + 1, m + 1, r, L, R, x);
    }
    int get(int v, int l, int r, int i) {
        if (l == r) return t[v].val;
        push(v, l, r);
        int m = (l + r) / 2;
        if (i <= m) return get(2 * v, l, m, i);
        return get(2 * v + 1, m + 1, r, i);
    }
    void set(int l, int r, int x) { set(1, 0, n - 1, l, r, x); }
    int get(int i) { return get(1, 0, n - 1, i); }
};

void solve() {
    int n = in;
    vt<vt<int>> g(n);
    auto edge = [&](int u, int v) {
        if (u == -1) return;
        g[u].pb(v);
    };
    Tree whot(2 * n, -1);
    for (int i : ra(0, n)) {
        int l = in, r = in;
        l--, r--;
        edge(whot.get(l), i);
        edge(whot.get(r), i);
        whot.set(l, r, i);
    }
    for (int i : ra(0, n)) {
        sort(all(g[i]));
        g[i].erase(unique(all(g[i])), g[i].end());
    }
    Combo comb(n);
    Z ans = 0;
    // fake ass reachability
    const int magic = 1 << 11;
    vt<bitset<magic>> set(n);
    vt<int> sumreach(n);
    for (int i = 0; i < n; i += magic) {
        for (int j = 0; j < n; j++) {
            set[j].reset();
            if (0 <= j - i && j - i < magic) set[j][j - i] = 1;
        }
        for (int j = n - 1; j >= 0; j--) {
            for (int to : g[j]) {
                set[j] |= set[to];
            }
            sumreach[j] += set[j].count();
        }
    }
    for (int i = 0; i < n; i++) {
        ans += Z(sumreach[i]).inv();
    }
    cout << ans << endl;
}

int32_t main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    // int t = in;
    while (t--) {
        solve();
    }
}