#include <bits/stdc++.h>
using namespace std;

int N, K, Q;
vector<int> values(1), weights(1), changes;
map< int, vector<int> > queries;
vector<long long> answers;

struct segment { int l, r, v, w; };

void evolve(vector<int> &knapsack, int v, int w) {
	for (int k=K; k>=w; --k) knapsack[k] = max( knapsack[k], v + knapsack[k-w] );
}

long long output(const vector<int> &knapsack) {
    long long answer = 0;
    for (int k=K; k>=1; --k) answer = (answer*10000019 + knapsack[k]) % 1000000007;
    return answer;
}

void solve(int lo, int hi, const vector<segment> &segments, vector<int> knapsack) {
    if (hi-lo <= 1) return;

    // find all segments we can already add to knapsack
    vector<segment> remains;
    for (const auto &seg : segments) {
        if (seg.l <= lo && seg.r >= hi-1) {
            evolve( knapsack, seg.v, seg.w );
        } else {
            remains.push_back(seg);
        }
    }

    // solve for med if needed
    int med = (lo+hi) / 2;
    if (queries.count(med)) {
        vector<int> med_knapsack = knapsack;
        for (const auto &seg : remains) {
            if (seg.l < med && seg.r >= med) {
                evolve( med_knapsack, seg.v, seg.w );
            }
        }
        long long curr = output(med_knapsack);
        for (int q : queries[med]) answers[q] = curr;
    }

    // make recursive calls
    vector<segment> left, right;
    for (const auto &seg : remains) {
        if (seg.l < med) left.push_back(seg);
        if (seg.r > med) right.push_back(seg);
    }
    solve( lo, med, left, knapsack );
    solve( med, hi, right, knapsack );
}

int main() {
    cin >> N >> K;
    for (int n=0; n<N; ++n) {
        int v, w; cin >> v >> w;
        values.push_back(v);
        weights.push_back(w);
        changes.push_back( +(n+1) );
    }
    cin >> Q;
    for (int q=0; q<Q; ++q) {
        int t; cin >> t;
        if (t == 1) {
            int v, w; cin >> v >> w;
            values.push_back(v);
            weights.push_back(w);
            changes.push_back( +(values.size()-1) );
        }
        if (t == 2) {
            int x; cin >> x;
            changes.push_back( -x );
        }
        if (t == 3) {
            queries[ changes.size() ].push_back(q);
        }
    }

    answers.resize(Q,-1);

    N = values.size();
    vector<int> starts(N), ends(N,-1);
    for (unsigned i=0; i<changes.size(); ++i)
    	if (changes[i]>0) starts[changes[i]]=i; else ends[-changes[i]]=i;
    for (int n=1; n<=N; ++n) if (ends[n]==-1) { ends[n] = changes.size(); changes.push_back(-n); }

    vector<segment> segments;
    for (int n=1; n<N; ++n) segments.push_back( { starts[n], ends[n], values[n], weights[n] } );

    for (int q : queries[ changes.size() ]) answers[q] = 0;

    solve( 0, changes.size(), segments, vector<int>(K+1,0) );

    for (auto a : answers) if (a != -1) cout << a << endl;
}