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
#include <bits/stdc++.h>
using namespace std;
#define rep(a, b) for (int a = 0; a < (b); a++)
#define rep1(a, b) for (int a = 1; a <= (b); a++)
#define all(x) (x).begin(), (x).end()
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int MOD = 1e9 + 7;

const int LIM = 1<<19;
int n, q;

ll add[LIM], mul[LIM];

int jmp[LIM];
ll prefsum[LIM];

ll getsum(int l, int r) {
    if (l > r) return 0;
    return prefsum[r]-prefsum[l]+add[l];
}

const int TREESIZE = LIM<<1;
ll prodtree[TREESIZE];
ll tree[TREESIZE];
pii ivl[TREESIZE];

ll advance(ll start, ll dp, ll prod) {
    return (start*prod + dp)%MOD;
}

void build(int v=1, int l=0, int r=LIM-1) {
    if (l >= n) return;
    ivl[v] = {l, r};
    prodtree[v] = mul[l];
    if (l == r) return;
    int lv = 2*v;
    int rv = 2*v+1;
    int mid = (l+r)/2;
    build(lv, l, mid);
    build(rv, mid+1, r);
    prodtree[v] = (prodtree[lv]*prodtree[rv])%MOD;
    tree[v] = advance(tree[lv], tree[rv], prodtree[rv]);
}

vector<pll> leftupd;
vector<pll> rightupd;
ll que(ll cur, int l, int r) {
    for (l+=LIM, r+=LIM+1; l<r; l>>=1, r>>=1) {
        if (l&1) {
            leftupd.push_back({tree[l], prodtree[l]});
            l++;
        }
        if (r&1) {
            r--;
            rightupd.push_back({tree[r], prodtree[r]});
        }
    }
    reverse(all(rightupd));
    
    for (auto [dp, prod]: leftupd) cur = advance(cur, dp, prod);
    for (auto [dp, prod]: rightupd) cur = advance(cur, dp, prod);
    leftupd.clear();
    rightupd.clear();
    
    return cur;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    
    cin >> n >> q;
    rep(i, n) cin >> add[i] >> mul[i];
    
    int curidx = n;
    for (int i = n-1; i >= 0; i--) {
        if (mul[i] > 1) curidx = i;
        jmp[i] = curidx;
    }

    ll sum = 0;
    rep(i, n) {
        sum += add[i];
        prefsum[i] = sum;
    }

    rep(i, n) tree[LIM+i] = (mul[i] == 1 ? add[i] : 0);
    build();
    leftupd.reserve(1067);
    rightupd.reserve(1067);

    ll x;
    int l, r;
    rep(i, q) {
        cin >> x >> l >> r;
        if (x == 0) x += add[l++];
        while (l<r && x<MOD) {
            int jmpidx = min(r, jmp[l]);
            x = x+getsum(l, jmpidx-1);
            l = jmpidx;
            if (l == r || x >= MOD) break;
            x = max(x+add[l], x*mul[l]);
            l++;
        }
        if (l == r) {
            cout << x%MOD << "\n";
            continue;
        }

        x = que(x%MOD, l, r-1);
        cout << x << "\n";
    }

    return 0;
}