Problem:
Range Min of Max Query
整数の組の列
(a_1,b_1), (a_2,b_2),..,(a_N,b_N)
が与えられます。
二種類のクエリを処理してください。
一種類目のクエリでは、
a_L,a_{L+1},..,a_R
に
X
を加算します。
二種類目のクエリでは、
max(a_L,b_L),max(a_{L+1},b_{L+1}),..,max(a_R,b_R)
の最小値を求めます。
入力
N Q
a_1 b_1
a_2 b_2
:
a_N b_N
query_1
query_2
:
query_Q
i
番目のクエリが一種類目のクエリの場合、
query_i
は
1 L_i R_i X_i
となります。
i
番目のクエリが二種類目のクエリの場合、
query_i
は
2 L_i R_i
となります。
出力
ans_1
ans_2
:
ans_k
二種類目のクエリに対する答えを順に出力せよ。
制約
1 \leq N,Q \leq 10^5
1 \leq a_i,b_i \leq 10^9
1 \leq L_i \leq R_i \leq N
-10^9 \leq X_i \leq 10^9
入力例
6 6
8 1
6 1
9 4
1 5
2 1
1 4
2 1 3
1 1 3 3
2 1 3
2 4 6
1 4 6 3
2 4 6
出力例
6
9
2
4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define ll long long
using namespace std;const int A = 1e5 + 5;
struct node{ll x,y;int id;}a[A];
int read(){int x = 0,f = 1;char c = getchar();
	while(!isdigit(c)){if(c == '-')f = -1;c = getchar();}
	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
	return x * f;
}int n,m,q,o,l,r,c,L,R,_o_,_l_,_r_;ll t[A],qz[A],hz[A],_s_;
int K(int p){return (p - 1) / m + 1;}
int KL(int p){return p * m - m + 1;}
int KR(int p){return min(n,p * m);}
void build(int l,int r){sort(a + l,a + r + 1,
		[](node x,node y){return x.x - x.y < y.x - y.y;});
	qz[l] = a[l].y,hz[r] = a[r].x;
	for(int i = l + 1;i <= r;i++)qz[i] = min(qz[i - 1],a[i].y);
	for(int i = r - 1;i >= l;i--)hz[i] = min(hz[i + 1],a[i].x);}
bool operator < (node x,node y){return x.id < y.id;}
int main(){n = read(),m = 100,q = read();
	for(int i = 1;i <= n;i++)
		a[i].x = read(),a[i].y = read(),a[i].id = i;
	for(int i = 1;i <= K(n);i++)build(KL(i),KR(i));
	while(q--){o = read(),L = K(l = read()),R = K(r = read());
		if(o == 1){c = read(),_l_ = 0;
			if(L == R){sort(a + KL(L),a + KR(L) + 1);
				for(int i = l;i <= r;i++)a[i].x += c;
				build(KL(L),KR(L));
			}else{sort(a + KL(L),a + KR(L) + 1);
				sort(a + KL(R),a + KR(R) + 1);
				for(int i = l;i <= KR(L);i++)a[i].x += c;
				for(int i = KL(R);i <= r;i++)a[i].x += c;
				build(KL(L),KR(L)),build(KL(R),KR(R));
				for(ll i = L + 1;i < R;i++)t[i] += c;
			}
		}else{ll s = 1e18;_l_ = l,_r_ = r;
			if(L == R){sort(a + KL(L),a + KR(L) + 1);
				for(int i = l;i <= r;i++)
					s = min(s,max(a[i].x + t[L],a[i].y));
				build(KL(L),KR(L));
			}else{sort(a + KL(L),a + KR(L) + 1);
				sort(a + KL(R),a + KR(R) + 1);
				for(int i = l;i <= KR(L);i++)
					s = min(s,max(a[i].x + t[L],a[i].y));
				for(int i = KL(R);i <= r;i++)
					s = min(s,max(a[i].x + t[R],a[i].y));
				build(KL(L),KR(L)),build(KL(R),KR(R));
				for(ll i = L + 1;i < R;i++){
					int _l = KL(i),_r = KR(i),S = KR(i) + 1;
					while(_l <= _r){int mid = _l + _r >> 1;
						if(a[mid].x - a[mid].y + t[i] >= 0)
							S = mid,_r = mid - 1;
						else _l = mid + 1;
					}if(S != KL(i))s = min(s,qz[S - 1]);
					if(S != KR(i) + 1)s = min(s,hz[S] + t[i]);
				}
			}printf("%lld\n",_s_ = s);
		}
	}return 0;
}
accuracy: 1
time_ms: 1340
memory_kb: 7708
final_rank: 9

code_snippet: // AOJ #3118 Range Min of Max Query
// 2025.3.21

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const ll INF = 1LL << 60;

int N, Q;
vector<ll> A, B;

struct Node {
    ll dmin, dmax;
    ll minA;
    ll minB;
    ll f;
    int t;
};

vector<Node> seg;
vector<ll> lz;

Node mergeNode(const Node &L, const Node &R) {
    Node res;
    res.dmin = min(L.dmin, R.dmin);
    res.dmax = max(L.dmax, R.dmax);
    res.minB = min(L.minB, R.minB);
    if(L.t == 1 && R.t == 1) {
        res.t = 1;
        res.minA = min(L.minA, R.minA);
        res.f = res.minA;
    } else if(L.t == 2 && R.t == 2) {
        res.t = 2;
        res.f = res.minB;
    } else {
        res.t = 0;
        res.f = min(L.f, R.f);
    }
    return res;
}

void build(int i, int s, int e) {
    if(s == e) {
        ll d = A[s] - B[s];
        seg[i].dmin = seg[i].dmax = d;
        seg[i].minB = B[s];
        if(d >= 0) {
            seg[i].t = 1;
            seg[i].minA = A[s];
            seg[i].f = A[s];
        } else {
            seg[i].t = 2;
            seg[i].f = B[s];
        }
        return;
    }
    int m = (s + e) / 2;
    build(i * 2, s, m);
    build(i * 2 + 1, m + 1, e);
    seg[i] = mergeNode(seg[i * 2], seg[i * 2 + 1]);
}

void update(int i, int s, int e, int l, int r, ll x);
void pushDown(int i, int s, int e) {
    if(lz[i] != 0) {
        int m = (s + e) / 2;
        update(i * 2, s, m, s, m, lz[i]);
        update(i * 2 + 1, m + 1, e, m + 1, e, lz[i]);
        lz[i] = 0;
    }
}

void update(int i, int s, int e, int l, int r, ll x) {
    if(r < s || e < l) return;
    if(s >= l && e <= r) {
        if(s == e) {
            seg[i].dmin += x;
            seg[i].dmax += x;
            ll A_val = seg[i].minB + seg[i].dmin;
            if(seg[i].dmin >= 0) {
                seg[i].t = 1;
                seg[i].minA = A_val;
                seg[i].f = A_val;
            } else {
                seg[i].t = 2;
                seg[i].f = seg[i].minB;
            }
            return;
        }
        if(seg[i].t == 1 && seg[i].dmin + x >= 0) {
            seg[i].dmin += x;
            seg[i].dmax += x;
            seg[i].minA += x;
            seg[i].f = seg[i].minA;
            lz[i] += x;
            return;
        }
        if(seg[i].t == 2 && seg[i].dmax + x < 0) {
            seg[i].dmin += x;
            seg[i].dmax += x;
            lz[i] += x;
            return;
        }
    }
    int m = (s + e) / 2;
    pushDown(i, s, e);
    update(i * 2, s, m, l, r, x);
    update(i * 2 + 1, m + 1, e, l, r, x);
    seg[i] = mergeNode(seg[i * 2], seg[i * 2 + 1]);
}

ll query(int i, int s, int e, int l, int r) {
    if(r < s || e < l) return INF;
    if(s >= l && e <= r) return seg[i].f;
    int m = (s + e) / 2;
    pushDown(i, s, e);
    return min(query(i * 2, s, m, l, r), query(i * 2 + 1, m + 1, e, l, r));
}

int main(){
    N = Cin(), Q = Cin();
    A.resize(N + 1); B.resize(N + 1);
    for (int i = 1; i <= N; i++) A[i] = Cin(), B[i] = Cin();

    seg.resize(4 * (N + 1));
    lz.assign(4 * (N + 1), 0);
    build(1, 1, N);

    while(Q--){
        int t = Cin();
        if(t == 1){
            int L = Cin(), R = Cin(); ll X = Cin();
            update(1, 1, N, L, R, X);
        } else {
            int L = Cin(), R = Cin();
            Cout(query(1, 1, N, L, R));
        }
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 26432
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;

    ////////////////////////////////////////////////////////////////////////////////
    // 平方分割用ライブラリ
    const int B = 250; // ブロックサイズ
    auto getSqCount = [](int n, int B) -> int { return (n + B - 1) / B; };
    int sqCnt = getSqCount(n, B);
    auto getSqInterval = [](int n, int B, int sqCnt) -> pair<vector<int>, vector<int>> {
        vector<int> sqL(sqCnt), sqR(sqCnt);
        int sum = 0;
        for (int i = 0; i < sqCnt; i++) {
            sqL[i] = sum;
            sum += B;
            sqR[i] = sum;
        }
        sqR.back() = n;
        return {sqL, sqR};
    };
    auto [sqL, sqR] = getSqInterval(n, B, sqCnt);
    vector<int> sqIdx(n);
    for (int i = 0; i < sqCnt; i++) {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            sqIdx[j] = i;
        }
    }
    auto getSqIdx = [&](int i) -> int { return sqIdx[i]; };
    auto getSqLength = [&](int i) -> int { return sqR[i] - sqL[i]; };
    ////////////////////////////////////////////////////////////////////////////////

    int q;
    cin >> q;
    vector<ll> a(n), b(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
    }
    vector<ll> add(sqCnt);
    using P = pair<ll, ll>;
    vector<vector<pair<ll, P>>> v(sqCnt);
    auto update = [&](int i) -> void {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            v[i][j - sqL[i]] = {b[j] - a[j], {a[j], b[j]}};
        }
        sort(v[i].begin(), v[i].end());
        for (int j = 1; j < v[i].size(); j++) {
            v[i][j].second.first = min(v[i][j].second.first, v[i][j - 1].second.first);
            v[i][v[i].size() - 1 - j].second.second =
                min(v[i][v[i].size() - 1 - j].second.second, v[i][v[i].size() - j].second.second);
        }
    };
    for (int i = 0; i < sqCnt; i++) {
        v[i].resize(getSqLength(i));
        update(i);
    }

    while (q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int L, R, x;
            cin >> L >> R >> x;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                a[L] += x;
            }
            update(lid);

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                a[R] += x;
            }
            update(rid);

            for (; L < R; L += B) {
                int id = sqIdx[L];
                add[id] += x;
            }
        } else {
            ll res = 2e18;
            int L, R;
            cin >> L >> R;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                res = min(res, max(a[L] + add[lid], b[L]));
            }

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                res = min(res, max(a[R] + add[rid], b[R]));
            }

            while (L < R) {
                int id = sqIdx[L];
                {
                    int l = -1, r = getSqLength(id);
                    while (r - l > 1) {
                        int mid = (l + r) / 2;
                        if (v[id][mid].first <= add[id]) l = mid;
                        else r = mid;
                    }
                    if (l == -1) {
                        res = min(res, v[id][0].second.second);
                    } else if (l + 1 == getSqLength(id)) {
                        res = min(res, v[id][l].second.first + add[id]);
                    } else {
                        res = min(res, v[id][l].second.first + add[id]);
                        res = min(res, v[id][l + 1].second.second);
                    }
                }
                L += B;
            }
            cout << res << "\n";
        }
    }
}
accuracy: 1
time_ms: 1080
memory_kb: 7600
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;

    ////////////////////////////////////////////////////////////////////////////////
    // 平方分割用ライブラリ
    const int B = 250; // ブロックサイズ
    auto getSqCount = [](int n, int B) -> int { return (n + B - 1) / B; };
    int sqCnt = getSqCount(n, B);
    auto getSqInterval = [](int n, int B, int sqCnt) -> pair<vector<int>, vector<int>> {
        vector<int> sqL(sqCnt), sqR(sqCnt);
        int sum = 0;
        for (int i = 0; i < sqCnt; i++) {
            sqL[i] = sum;
            sum += B;
            sqR[i] = sum;
        }
        sqR.back() = n;
        return {sqL, sqR};
    };
    auto [sqL, sqR] = getSqInterval(n, B, sqCnt);
    vector<int> sqIdx(n);
    for (int i = 0; i < sqCnt; i++) {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            sqIdx[j] = i;
        }
    }
    auto getSqIdx = [&](int i) -> int { return sqIdx[i]; };
    auto getSqLength = [&](int i) -> int { return sqR[i] - sqL[i]; };
    ////////////////////////////////////////////////////////////////////////////////

    int q;
    cin >> q;
    vector<ll> a(n), b(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
    }
    vector<ll> add(sqCnt);
    using P = pair<ll, ll>;
    vector<vector<pair<ll, P>>> v(sqCnt);
    auto update = [&](int i) -> void {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            v[i][j - sqL[i]] = {b[j] - a[j], {a[j], b[j]}};
        }
        sort(v[i].begin(), v[i].end());
        for (int j = 1; j < v[i].size(); j++) {
            v[i][j].second.first = min(v[i][j].second.first, v[i][j - 1].second.first);
            v[i][v[i].size() - 1 - j].second.second =
                min(v[i][v[i].size() - 1 - j].second.second, v[i][v[i].size() - j].second.second);
        }
    };
    for (int i = 0; i < sqCnt; i++) {
        v[i].resize(getSqLength(i));
        update(i);
    }

    while (q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int L, R, x;
            cin >> L >> R >> x;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                a[L] += x;
            }
            update(lid);

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                a[R] += x;
            }
            update(rid);

            while (L < R) {
                int id = sqIdx[L];
                add[id] += x;
                L += B;
            }
        } else {
            ll res = 2e18;
            int L, R;
            cin >> L >> R;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                res = min(res, max(a[L] + add[lid], b[L]));
            }

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                res = min(res, max(a[R] + add[rid], b[R]));
            }

            while (L < R) {
                int id = sqIdx[L];
                {
                    int l = -1, r = getSqLength(id);
                    while (r - l > 1) {
                        int mid = (l + r) / 2;
                        if (v[id][mid].first <= add[id]) l = mid;
                        else r = mid;
                    }
                    if (l == -1) {
                        res = min(res, v[id][0].second.second);
                    } else if (l + 1 == getSqLength(id)) {
                        res = min(res, v[id][l].second.first + add[id]);
                    } else {
                        res = min(res, v[id][l].second.first + add[id]);
                        res = min(res, v[id][l + 1].second.second);
                    }
                }
                L += B;
            }
            cout << res << "\n";
        }
    }
}
accuracy: 1
time_ms: 1110
memory_kb: 7564
final_rank: 6

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;

    ////////////////////////////////////////////////////////////////////////////////
    // 平方分割用ライブラリ
    const int B = 250; // ブロックサイズ
    auto getSqCount = [](int n, int B) -> int { return (n + B - 1) / B; };
    int sqCnt = getSqCount(n, B);
    auto getSqInterval = [](int n, int B, int sqCnt) -> pair<vector<int>, vector<int>> {
        vector<int> sqL(sqCnt), sqR(sqCnt);
        int sum = 0;
        for (int i = 0; i < sqCnt; i++) {
            sqL[i] = sum;
            sum += B;
            sqR[i] = sum;
        }
        sqR.back() = n;
        return {sqL, sqR};
    };
    auto [sqL, sqR] = getSqInterval(n, B, sqCnt);
    vector<int> sqIdx(n);
    for (int i = 0; i < sqCnt; i++) {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            sqIdx[j] = i;
        }
    }
    auto getSqIdx = [&](int i) -> int { return sqIdx[i]; };
    ////////////////////////////////////////////////////////////////////////////////

    int q;
    cin >> q;
    vector<ll> a(n), b(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
    }
    vector<ll> add(sqCnt);
    using P = pair<ll, ll>;
    vector<vector<pair<ll, P>>> v(sqCnt);
    auto update = [&](int i) -> void {
        for (int j = sqL[i]; j < sqR[i]; j++) {
            v[i][j - sqL[i]] = {b[j] - a[j], {a[j], b[j]}};
        }
        sort(v[i].begin(), v[i].end());
        for (int j = 1; j < v[i].size(); j++) {
            v[i][j].second.first = min(v[i][j].second.first, v[i][j - 1].second.first);
            v[i][v[i].size() - 1 - j].second.second =
                min(v[i][v[i].size() - 1 - j].second.second, v[i][v[i].size() - j].second.second);
        }
    };
    for (int i = 0; i < sqCnt; i++) {
        v[i].resize(sqR[i] - sqL[i]);
        update(i);
    }

    while (q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int L, R, x;
            cin >> L >> R >> x;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                a[L] += x;
            }
            update(lid);

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                a[R] += x;
            }
            update(rid);

            while (L < R) {
                int id = sqIdx[L];
                add[id] += x;
                L += B;
            }
        } else {
            ll res = 2e18;
            int L, R;
            cin >> L >> R;
            L -= 1, R -= 1;

            int lid = sqIdx[L];
            for (; L <= R and L < sqR[lid]; L++) {
                res = min(res, max(a[L] + add[lid], b[L]));
            }

            int rid = sqIdx[R];
            for (; L <= R and sqL[rid] <= R; R--) {
                res = min(res, max(a[R] + add[rid], b[R]));
            }

            while (L < R) {
                int id = sqIdx[L];
                {
                    int l = -1, r = sqR[id] - sqL[id];
                    while (r - l > 1) {
                        int mid = (l + r) / 2;
                        if (v[id][mid].first <= add[id]) l = mid;
                        else r = mid;
                    }
                    if (l == -1) {
                        res = min(res, v[id][0].second.second);
                    } else if (l + 1 == sqR[id] - sqL[id]) {
                        res = min(res, v[id][l].second.first + add[id]);
                    } else {
                        res = min(res, v[id][l].second.first + add[id]);
                        res = min(res, v[id][l + 1].second.second);
                    }
                }
                L += B;
            }
            cout << res << "\n";
        }
    }
}
accuracy: 1
time_ms: 1120
memory_kb: 7584
final_rank: 7

code_snippet: #pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template<class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<class T> 
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    for (int i = 0; i < int(v.size()); i++) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
template<class Container> inline int SZ(Container& v) { return int(v.size()); }
template<class T> inline void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template<class T1, class T2> inline bool chmax(T1& a, T2 b) { if (a < b) {a = b; return true ;} return false ;}
template<class T1, class T2> inline bool chmin(T1& a, T2 b) { if (a > b) {a = b; return true ;} return false ;}
inline int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(ull x) { return __builtin_popcountll(x); }
inline int kthbit(ull x, int k) { return (x>>k) & 1; }
inline constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x-1) * 10; }
inline void print() { cout << "\n"; }
template<class T>
inline void print(const vector<T>& v) {
    for (int i = 0; i < int(v.size()); i++) {
        if (i) cout << " ";
        cout << v[i];
    }
    print();
}
template<class T, class... Args>
inline void print(const T& x, const Args& ... args) {
    cout << x << " ";
    print(args...);
}
#ifdef MINATO_LOCAL
inline void debug_out() { cerr << endl; }
template <class T, class... Args>
inline void debug_out(const T& x, const Args& ... args) {
    cerr << " " << x;
    debug_out(args...);
}
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr int sz = 200;
constexpr ll INF = 1e18;
using Tu = tuple<ll, ll, ll>;
int main() {
    int N,Q; cin >> N >> Q;
    vector<ll> A(N),B(N);
    rep(i,N) cin >> A[i] >> B[i];

    vector<vector<Tu>> C(N/sz+1);
    vector<vector<ll>> MA(N/sz+1),MB(N/sz+1);
    vector<ll> lazy(N/sz+1);
    rep(i,N) {
        C[i/sz].emplace_back(A[i]-B[i],A[i],B[i]);
    }
    rep(i,N/sz+1) {
        MA[i].assign(SZ(C[i])+1,INF);
        MB[i].assign(SZ(C[i])+1,INF);
    }

    auto updsum=[&](int x) {
        if (lazy[x]) {
            int l = sz*x;
            int r = min(sz*(x+1),N);
            for (int i = l; i < r; i++) {
                A[i] += lazy[x];
            }
            lazy[x] = 0;
        }
    };
    auto updsort=[&](int x) {
        int l = sz*x;
        int r = min(sz*(x+1),N);
        for (int i = l; i < r; i++) {
            C[x][i-l] = Tu(A[i]-B[i],A[i],B[i]);
        }
        sort(all(C[x]));
        rep(i,SZ(C[x])) {
            MB[x][i+1] = min(MB[x][i],get<2>(C[x][i]));
        }
        rrep(i,SZ(C[x])) {
            MA[x][i] = min(MA[x][i+1],get<1>(C[x][i]));
        }
    };
    rep(i,N/sz+1) updsort(i);

    rep(_,Q) {
        int t; cin >> t;
        if (t==1) {
            int l,r,x; cin >> l >> r >> x;
            l--;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);

                for (int i = l/sz+1; i < r/sz; i++) {
                    lazy[i] += x;
                }

                for (int i = r/sz*sz; i < r; i++) {
                    A[i] += x;
                }
                updsum(r/sz);
                updsort(r/sz);
            }
        } else {
            int l,r; cin >> l >> r;
            l--;
            ll ans = 1e18;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
                for (int i = r/sz*sz; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[r/sz],B[i]));
                }

                for (int i = l/sz+1; i < r/sz; i++) {
                    int k = lower_bound(all(C[i]),Tu(-lazy[i],-INF,-INF)) - C[i].begin();
                    chmin(ans,min(MB[i][k],MA[i][k]+lazy[i]));
                }                
            }

            cout << ans << ln;
        }
    }
}
accuracy: 1
time_ms: 730
memory_kb: 9464
final_rank: 3

code_snippet: #pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template<class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<class T> 
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    for (int i = 0; i < int(v.size()); i++) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
template<class Container> inline int SZ(Container& v) { return int(v.size()); }
template<class T> inline void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template<class T1, class T2> inline bool chmax(T1& a, T2 b) { if (a < b) {a = b; return true ;} return false ;}
template<class T1, class T2> inline bool chmin(T1& a, T2 b) { if (a > b) {a = b; return true ;} return false ;}
inline int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(ull x) { return __builtin_popcountll(x); }
inline int kthbit(ull x, int k) { return (x>>k) & 1; }
inline constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x-1) * 10; }
inline void print() { cout << "\n"; }
template<class T>
inline void print(const vector<T>& v) {
    for (int i = 0; i < int(v.size()); i++) {
        if (i) cout << " ";
        cout << v[i];
    }
    print();
}
template<class T, class... Args>
inline void print(const T& x, const Args& ... args) {
    cout << x << " ";
    print(args...);
}
#ifdef MINATO_LOCAL
inline void debug_out() { cerr << endl; }
template <class T, class... Args>
inline void debug_out(const T& x, const Args& ... args) {
    cerr << " " << x;
    debug_out(args...);
}
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr int sz = 250;
constexpr ll INF = 1e18;
using Tu = tuple<ll, ll, ll>;
int main() {
    int N,Q; cin >> N >> Q;
    vector<ll> A(N),B(N);
    rep(i,N) cin >> A[i] >> B[i];

    vector<vector<Tu>> C(N/sz+1);
    vector<vector<ll>> MA(N/sz+1),MB(N/sz+1);
    vector<ll> lazy(N/sz+1);
    rep(i,N) {
        C[i/sz].emplace_back(A[i]-B[i],A[i],B[i]);
    }
    rep(i,N/sz+1) {
        MA[i].assign(SZ(C[i])+1,INF);
        MB[i].assign(SZ(C[i])+1,INF);
    }

    auto updsum=[&](int x) {
        if (lazy[x]) {
            int l = sz*x;
            int r = min(sz*(x+1),N);
            for (int i = l; i < r; i++) {
                A[i] += lazy[x];
            }
            lazy[x] = 0;
        }
    };
    auto updsort=[&](int x) {
        int l = sz*x;
        int r = min(sz*(x+1),N);
        for (int i = l; i < r; i++) {
            C[x][i-l] = Tu(A[i]-B[i],A[i],B[i]);
        }
        sort(all(C[x]));
        rep(i,SZ(C[x])) {
            MB[x][i+1] = min(MB[x][i],get<2>(C[x][i]));
        }
        rrep(i,SZ(C[x])) {
            MA[x][i] = min(MA[x][i+1],get<1>(C[x][i]));
        }
    };
    rep(i,N/sz+1) updsort(i);

    rep(_,Q) {
        int t; cin >> t;
        if (t==1) {
            int l,r,x; cin >> l >> r >> x;
            l--;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);

                for (int i = l/sz+1; i < r/sz; i++) {
                    lazy[i] += x;
                }

                for (int i = r/sz*sz; i < r; i++) {
                    A[i] += x;
                }
                updsum(r/sz);
                updsort(r/sz);
            }
        } else {
            int l,r; cin >> l >> r;
            l--;
            ll ans = 1e18;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
                for (int i = r/sz*sz; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[r/sz],B[i]));
                }

                for (int i = l/sz+1; i < r/sz; i++) {
                    int k = lower_bound(all(C[i]),Tu(-lazy[i],-INF,-INF)) - C[i].begin();
                    chmin(ans,min(MB[i][k],MA[i][k]+lazy[i]));
                }                
            }

            cout << ans << ln;
        }
    }
}
accuracy: 1
time_ms: 760
memory_kb: 8604
final_rank: 2

code_snippet: #pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template<class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<class T> 
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    for (int i = 0; i < int(v.size()); i++) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
template<class Container> inline int SZ(Container& v) { return int(v.size()); }
template<class T> inline void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template<class T1, class T2> inline bool chmax(T1& a, T2 b) { if (a < b) {a = b; return true ;} return false ;}
template<class T1, class T2> inline bool chmin(T1& a, T2 b) { if (a > b) {a = b; return true ;} return false ;}
inline int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(ull x) { return __builtin_popcountll(x); }
inline int kthbit(ull x, int k) { return (x>>k) & 1; }
inline constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x-1) * 10; }
inline void print() { cout << "\n"; }
template<class T>
inline void print(const vector<T>& v) {
    for (int i = 0; i < int(v.size()); i++) {
        if (i) cout << " ";
        cout << v[i];
    }
    print();
}
template<class T, class... Args>
inline void print(const T& x, const Args& ... args) {
    cout << x << " ";
    print(args...);
}
#ifdef MINATO_LOCAL
inline void debug_out() { cerr << endl; }
template <class T, class... Args>
inline void debug_out(const T& x, const Args& ... args) {
    cerr << " " << x;
    debug_out(args...);
}
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr int sz = 150;
constexpr ll INF = 1e18;
using Tu = tuple<ll, ll, ll>;
int main() {
    int N,Q; cin >> N >> Q;
    vector<ll> A(N),B(N);
    rep(i,N) cin >> A[i] >> B[i];

    vector<vector<Tu>> C(N/sz+1);
    vector<vector<ll>> MA(N/sz+1),MB(N/sz+1);
    vector<ll> lazy(N/sz+1);
    rep(i,N) {
        C[i/sz].emplace_back(A[i]-B[i],A[i],B[i]);
    }
    rep(i,N/sz+1) {
        MA[i].assign(SZ(C[i])+1,INF);
        MB[i].assign(SZ(C[i])+1,INF);
    }

    auto updsum=[&](int x) {
        if (lazy[x]) {
            int l = sz*x;
            int r = min(sz*(x+1),N);
            for (int i = l; i < r; i++) {
                A[i] += lazy[x];
            }
            lazy[x] = 0;
        }
    };
    auto updsort=[&](int x) {
        int l = sz*x;
        int r = min(sz*(x+1),N);
        for (int i = l; i < r; i++) {
            C[x][i-l] = Tu(A[i]-B[i],A[i],B[i]);
        }
        sort(all(C[x]));
        rep(i,SZ(C[x])) {
            MB[x][i+1] = min(MB[x][i],get<2>(C[x][i]));
        }
        rrep(i,SZ(C[x])) {
            MA[x][i] = min(MA[x][i+1],get<1>(C[x][i]));
        }
    };
    rep(i,N/sz+1) updsort(i);

    rep(_,Q) {
        int t; cin >> t;
        if (t==1) {
            int l,r,x; cin >> l >> r >> x;
            l--;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);

                for (int i = l/sz+1; i < r/sz; i++) {
                    lazy[i] += x;
                }

                for (int i = r/sz*sz; i < r; i++) {
                    A[i] += x;
                }
                updsum(r/sz);
                updsort(r/sz);
            }
        } else {
            int l,r; cin >> l >> r;
            l--;
            ll ans = 1e18;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
                for (int i = r/sz*sz; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[r/sz],B[i]));
                }

                for (int i = l/sz+1; i < r/sz; i++) {
                    int k = lower_bound(all(C[i]),Tu(-lazy[i],-INF,-INF)) - C[i].begin();
                    chmin(ans,min(MB[i][k],MA[i][k]+lazy[i]));
                }                
            }

            cout << ans << ln;
        }
    }
}
accuracy: 1
time_ms: 800
memory_kb: 10136
final_rank: 4

code_snippet: #ifdef ONLINE_JUDGE
#pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template<class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<class T> 
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    for (int i = 0; i < int(v.size()); i++) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
template<class Container> inline int SZ(Container& v) { return int(v.size()); }
template<class T> inline void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template<class T1, class T2> inline bool chmax(T1& a, T2 b) { if (a < b) {a = b; return true ;} return false ;}
template<class T1, class T2> inline bool chmin(T1& a, T2 b) { if (a > b) {a = b; return true ;} return false ;}
inline int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(ull x) { return __builtin_popcountll(x); }
inline int kthbit(ull x, int k) { return (x>>k) & 1; }
inline constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x-1) * 10; }
inline void print() { cout << "\n"; }
template<class T>
inline void print(const vector<T>& v) {
    for (int i = 0; i < int(v.size()); i++) {
        if (i) cout << " ";
        cout << v[i];
    }
    print();
}
template<class T, class... Args>
inline void print(const T& x, const Args& ... args) {
    cout << x << " ";
    print(args...);
}
#ifdef MINATO_LOCAL
inline void debug_out() { cerr << endl; }
template <class T, class... Args>
inline void debug_out(const T& x, const Args& ... args) {
    cerr << " " << x;
    debug_out(args...);
}
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr int sz = 320;
constexpr ll INF = 1e18;
using Tu = tuple<ll, ll, ll>;
int main() {
    int N,Q; cin >> N >> Q;
    vector<ll> A(N),B(N);
    rep(i,N) cin >> A[i] >> B[i];

    vector<vector<Tu>> C(N/sz+1);
    vector<vector<ll>> MA(N/sz+1),MB(N/sz+1);
    vector<ll> lazy(N/sz+1);
    rep(i,N) {
        C[i/sz].emplace_back(A[i]-B[i],A[i],B[i]);
    }
    rep(i,N/sz+1) {
        MA[i].assign(SZ(C[i])+1,INF);
        MB[i].assign(SZ(C[i])+1,INF);
    }

    auto updsum=[&](int x) {
        if (lazy[x]) {
            int l = sz*x;
            int r = min(sz*(x+1),N);
            for (int i = l; i < r; i++) {
                A[i] += lazy[x];
            }
            lazy[x] = 0;
        }
    };
    auto updsort=[&](int x) {
        int l = sz*x;
        int r = min(sz*(x+1),N);
        for (int i = l; i < r; i++) {
            C[x][i-l] = Tu(A[i]-B[i],A[i],B[i]);
        }
        sort(all(C[x]));
        rep(i,SZ(C[x])) {
            MB[x][i+1] = min(MB[x][i],get<2>(C[x][i]));
        }
        rrep(i,SZ(C[x])) {
            MA[x][i] = min(MA[x][i+1],get<1>(C[x][i]));
        }
    };
    rep(i,N/sz+1) updsort(i);

    rep(_,Q) {
        int t; cin >> t;
        if (t==1) {
            int l,r,x; cin >> l >> r >> x;
            l--;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);

                for (int i = l/sz+1; i < r/sz; i++) {
                    lazy[i] += x;
                }

                for (int i = r/sz*sz; i < r; i++) {
                    A[i] += x;
                }
                updsum(r/sz);
                updsort(r/sz);
            }
        } else {
            int l,r; cin >> l >> r;
            l--;
            ll ans = 1e18;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
                for (int i = r/sz*sz; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[r/sz],B[i]));
                }

                for (int i = l/sz+1; i < r/sz; i++) {
                    int k = lower_bound(all(C[i]),Tu(-lazy[i],-INF,-INF)) - C[i].begin();
                    chmin(ans,min(MB[i][k],MA[i][k]+lazy[i]));
                }                
            }

            cout << ans << ln;
        }
    }
}
accuracy: 1
time_ms: 910
memory_kb: 9956
final_rank: 8

code_snippet: #ifdef ONLINE_JUDGE
#pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
constexpr char ln = '\n';
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template<class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<class T> 
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    for (int i = 0; i < int(v.size()); i++) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
template<class Container> inline int SZ(Container& v) { return int(v.size()); }
template<class T> inline void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template<class T1, class T2> inline bool chmax(T1& a, T2 b) { if (a < b) {a = b; return true ;} return false ;}
template<class T1, class T2> inline bool chmin(T1& a, T2 b) { if (a > b) {a = b; return true ;} return false ;}
inline int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(ull x) { return __builtin_popcountll(x); }
inline int kthbit(ull x, int k) { return (x>>k) & 1; }
inline constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x-1) * 10; }
inline void print() { cout << "\n"; }
template<class T>
inline void print(const vector<T>& v) {
    for (int i = 0; i < int(v.size()); i++) {
        if (i) cout << " ";
        cout << v[i];
    }
    print();
}
template<class T, class... Args>
inline void print(const T& x, const Args& ... args) {
    cout << x << " ";
    print(args...);
}
#ifdef MINATO_LOCAL
inline void debug_out() { cerr << endl; }
template <class T, class... Args>
inline void debug_out(const T& x, const Args& ... args) {
    cerr << " " << x;
    debug_out(args...);
}
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

constexpr int sz = 320;
constexpr ll INF = 1e18;
using Tu = tuple<ll, ll, ll>;
int main() {
    int N,Q; cin >> N >> Q;
    vector<ll> A(N),B(N);
    rep(i,N) cin >> A[i] >> B[i];

    vector<vector<Tu>> C(N/sz+1);
    vector<vector<ll>> MA(N/sz+1),MB(N/sz+1);
    vector<ll> lazy(N/sz+1);
    rep(i,N) {
        C[i/sz].emplace_back(A[i]-B[i],A[i],B[i]);
    }
    rep(i,N/sz+1) {
        MA[i].assign(SZ(C[i])+1,INF);
        MB[i].assign(SZ(C[i])+1,INF);
    }

    auto updsum=[&](int x) {
        if (lazy[x]) {
            int l = sz*x;
            int r = min(sz*(x+1),N);
            for (int i = l; i < r; i++) {
                A[i] += lazy[x];
            }
            lazy[x] = 0;
        }
    };
    auto updsort=[&](int x) {
        int l = sz*x;
        int r = min(sz*(x+1),N);
        for (int i = l; i < r; i++) {
            C[x][i-l] = Tu(A[i]-B[i],A[i],B[i]);
        }
        sort(all(C[x]));
        rep(i,SZ(C[x])) {
            MB[x][i+1] = min(MB[x][i],get<2>(C[x][i]));
        }
        rrep(i,SZ(C[x])) {
            MA[x][i] = min(MA[x][i+1],get<1>(C[x][i]));
        }
    };
    rep(i,N/sz+1) updsort(i);

    rep(_,Q) {
        int t; cin >> t;
        if (t==1) {
            int l,r,x; cin >> l >> r >> x;
            l--;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    A[i] += x;
                }
                updsum(l/sz);
                updsort(l/sz);

                for (int i = l/sz+1; i < r/sz; i++) {
                    lazy[i] += x;
                }

                for (int i = r/sz*sz; i < r; i++) {
                    A[i] += x;
                }
                updsum(r/sz);
                updsort(r/sz);
            }
        } else {
            int l,r; cin >> l >> r;
            l--;
            ll ans = 1e18;
            if (l/sz == r/sz) {
                for (int i = l; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
            } else {
                for (int i = l; i < (l/sz+1)*sz; i++) {
                    chmin(ans,max(A[i]+lazy[l/sz],B[i]));
                }
                for (int i = r/sz*sz; i < r; i++) {
                    chmin(ans,max(A[i]+lazy[r/sz],B[i]));
                }

                for (int i = l/sz+1; i < r/sz; i++) {
                    int k = lower_bound(all(C[i]),Tu(-lazy[i],-INF,-INF)) - C[i].begin();
                    chmin(ans,min(MB[i][k],MA[i][k+1]+lazy[i]));
                }                
            }

            cout << ans << ln;
        }
    }
}
accuracy: 0.2
time_ms: 910
memory_kb: 9820
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using ll                            = long long;
using uint                          = unsigned int;
using ull                           = unsigned long long;
using ld                            = long double;
template<typename T> using max_heap = std::priority_queue<T>;
template<typename T> using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
constexpr int popcount(const ull v) { return v ? __builtin_popcountll(v) : 0; }
constexpr int log2p1(const ull v) { return v ? 64 - __builtin_clzll(v) : 0; }
constexpr int lsbp1(const ull v) { return __builtin_ffsll(v); }
constexpr int clog(const ull v) { return v ? log2p1(v - 1) : 0; }
constexpr ull ceil2(const ull v) { return 1ULL << clog(v); }
constexpr ull floor2(const ull v) { return v ? (1ULL << (log2p1(v) - 1)) : 0ULL; }
constexpr bool btest(const ull mask, const int ind) { return (mask >> ind) & 1ULL; }
template<typename T> void bset(T& mask, const int ind) { mask |= ((T)1 << ind); }
template<typename T> void breset(T& mask, const int ind) { mask &= ~((T)1 << ind); }
template<typename T> void bflip(T& mask, const int ind) { mask ^= ((T)1 << ind); }
template<typename T> void bset(T& mask, const int ind, const bool b) { (b ? bset(mask, ind) : breset(mask, ind)); }
template<typename T>
class fenwick
{
public:
    fenwick(const std::vector<T>& vs) : sz{(int)vs.size()}, cap{(int)ceil2(sz)}, vals(cap + 1, 0)
    {
        std::copy(vs.begin(), vs.end(), vals.begin() + 1);
        for (int x = 1; x < cap; x++) { vals[x + (x & -x)] += vals[x]; }
    }
    void add(const int a, const T& v)
    {
        assert(0 <= a and a < sz);
        for (int ind = a + 1; ind <= cap; ind += ind & (-ind)) { vals[ind] += v; }
    }
    T sum(const int a) const
    {
        assert(0 <= a and a <= sz);
        T sum{};
        for (int ind = a; ind != 0; ind &= ind - 1) { sum += vals[ind]; }
        return sum;
    }
    T sum(const int l, const int r) const { return assert(0 <= l and l <= r and r <= sz), sum(r) - sum(l); }
    int size() const { return sz; }
    friend std::ostream& operator<<(std::ostream& os, const fenwick& fw)
    {
        os << "[";
        for (int i = 0; i < fw.sz; i++) { os << fw.sum(i, i + 1) << (i + 1 == fw.sz ? "" : ","); }
        return (os << "]\n");
    }

private:
    const int sz, cap;
    std::vector<T> vals;
};

template<typename T, typename F, typename Merge, typename Compose, typename Apply>
class lazyseg
{
public:
    lazyseg(const std::vector<T>& vs,
            const Merge merge_,
            const T& e_,
            const Compose compose_,
            const F& id_,
            const Apply apply_) : size{(int)vs.size()}, depth{clog(size)}, half{1 << depth}, vals(half << 1, e_), ops(half << 1, id_), merge{merge_}, e{e_}, compose{compose_}, id{id_}, apply{apply_}
    {
        std::copy(vs.begin(), vs.end(), vals.begin() + half);
        for (int i = half - 1; i >= 1; i--) { up(i); }
    }
    T get(const int a) { return assert(a < size), fold(a, a + 1); }
    void set(int a, const T& v)
    {
        assert(0 <= a and a < size);
        top_down(a += half), top_down(a + 1), ops[a] = id, vals[a] = v;
        while (a >>= 1) { up(a); }
    }
    T fold(int l, int r)
    {
        assert(0 <= l and l <= r and r <= size);
        if (l >= r) { return e; }
        top_down(l += half), top_down(r += half);
        T accl = e, accr = e;
        for (; l < r; l >>= 1, r >>= 1) {
            if (l & 1) { accl = merge(accl, vals[l++]); }
            if (r & 1) { accr = merge(vals[--r], accr); }
        }
        return merge(accl, accr);
    }
    void act(int l, int r, const F& f)
    {
        assert(0 <= l and l <= r and r <= size);
        const int lin = l + half, rin = r + half;
        top_down(l += half), top_down(r += half);
        for (int ls = 1, rs = 1; l < r; l >>= 1, r >>= 1, ls <<= 1, rs <<= 1) {
            if (l & 1) { update(l++, f, ls); }
            if (r & 1) { update(--r, f, rs); }
        }
        bottom_up(lin), bottom_up(rin);
    }
    friend std::ostream& operator<<(std::ostream& os, const lazyseg& lseg)
    {
        auto lseg2 = lseg;
        os << "[";
        for (int i = 0; i < lseg.size; i++) { os << lseg2.get(i) << (i + 1 == lseg2.size ? "" : ","); }
        return (os << "]\n");
    }

private:
    void up(const int i) { vals[i] = merge(vals[i << 1], vals[i << 1 | 1]); }
    void update(const int a, const F& f, const int l) { ops[a] = compose(f, ops[a]), vals[a] = apply(f, vals[a], l); }
    void down(const int a, const int l) { update(a << 1, ops[a], l >> 1), update(a << 1 | 1, ops[a], l >> 1), ops[a] = id; }
    void top_down(const int a)
    {
        const int b = (a / (a & -a)) >> 1;
        for (int i = 0, l = half; i < depth; i++, l >>= 1) {
            const int v = a >> (depth - i);
            if (v > b) { break; }
            down(v, l);
        }
    }
    void bottom_up(int a)
    {
        a = (a / (a & -a)) >> 1;
        for (; a >= 1; a >>= 1) { up(a); }
    }
    const int size, depth, half;
    std::vector<T> vals;
    std::vector<F> ops;
    const Merge merge;
    const T e;
    const Compose compose;
    const F id;
    const Apply apply;
};

template<typename T> constexpr T inf_v      = std::numeric_limits<T>::max() / 4;
template<typename Real> constexpr Real pi_v = Real{3.141592653589793238462643383279502884};
template<typename T> constexpr T TEN(const int n) { return n == 0 ? T{1} : TEN<T>(n - 1) * T{10}; }
const auto min_merge    = [](const auto& x1, const auto& x2) { return std::min(x1, x2); };
const auto max_merge    = [](const auto& x1, const auto& x2) { return std::max(x1, x2); };
const auto minmax_merge = [](const auto& x1, const auto& x2) { return std::decay_t<decltype(x1)>{std::min(x1.first, x2.first), std::max(x1.second, x2.second)}; };
const auto sum_merge    = [](const auto& x1, const auto& x2) { return x1 + x2; };
const auto affine_merge = [](const auto& x1, const auto& x2) { return std::decay_t<decltype(x1)>{x1.first * x2.first, x1.first * x2.second + x1.second}; };

const auto plus_comp   = [](const auto& f1, const auto& f2) { return f1 + f2; };
const auto mult_comp   = [](const auto& f1, const auto& f2) { return f1 * f2; };
const auto assign_comp = [](const auto f1, const auto f2) { return f1 == inf_v<std::decay_t<decltype(f1)>> ? f2 : f1; };
const auto affine_comp = [](const auto& f1, const auto& f2) { return std::decay_t<decltype(f1)>{f1.first * f2.first, f1.first * f2.second + f1.second}; };

const auto min_plus_apply      = [](const auto& f, const auto& x, const auto&) { return x + f; };
const auto max_plus_apply      = [](const auto& f, const auto& x, const auto&) { return x + f; };
const auto minmax_plus_apply   = [](const auto& f, const auto& x, const auto&) { return std::decay_t<decltype(x)>{x.first + f, x.second + f}; };
const auto minmax_mult_apply   = [](const auto& f, const auto& x, const auto&) { return f >= 0 ? std::decay<decltype(x)>{f * x.first, f * x.second} : std::decay_t<decltype(x)>{f * x.second, f * x.first}; };
const auto min_assign_apply    = [](const auto& f, const auto& x, const auto&) { return f == inf_v<std::decay_t<decltype(f)>> ? x : f; };
const auto max_assign_apply    = [](const auto& f, const auto& x, const auto&) { return f == inf_v<std::decay_t<decltype(f)>> ? x : f; };
const auto minmax_assign_apply = [](const auto& f, const auto& x, const auto&) { return f == inf_v<std::decay_t<decltype(f)>> ? x : std::decay_t<decltype(x)>{f, f}; };
const auto minmax_affine_apply = [](const auto& f, const auto x, const auto&) { return f.first >= 0 ? std::decay_t<decltype(x)>{x.first * f.first + f.second, x.second * f.first + f.second} : std::decay_t<decltype(x)>{x.second * f.first + f.second, x.first * f.first + f.second}; };
const auto sum_plus_apply      = [](const auto& f, const auto& x, const auto& l) { return x + f * l; };
const auto sum_mult_apply      = [](const auto& f, const auto& x, const auto&) { return x * f; };
const auto sum_assign_apply    = [](const auto& f, const auto& x, const auto& l) { return f == inf_v<std::decay_t<decltype(f)>> ? x : f * l; };
const auto sum_affine_apply    = [](const auto& f, const auto x, const auto& l) { return x * f.first + f.second * l; };

const auto reverse = [](const auto f) { return [f](const auto& x1, const auto& x2) { return f(x2, x1); }; };

template<typename T> bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template<typename T> bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
template<typename F> struct fix : F
{
    fix(F&& f) : F{std::forward<F>(f)} {}
    template<typename... Args> auto operator()(Args&&... args) const { return F::operator()(*this, std::forward<Args>(args)...); }
};
template<typename T, int n, int i = 0>
auto nd_array(int const (&szs)[n], const T x = T{})
{
    if constexpr (i == n) {
        return x;
    } else {
        return std::vector(szs[i], nd_array<T, n, i + 1>(szs, x));
    }
}
class printer
{
public:
    printer(std::ostream& os_ = std::cout) : os{os_} { os << std::fixed << std::setprecision(15); }
    template<typename T> int operator()(const T& v) { return os << v, 0; }
    template<typename T> int operator()(const std::vector<T>& vs)
    {
        for (int i = 0; i < (int)vs.size(); i++) { os << (i ? " " : ""), this->operator()(vs[i]); }
        return 0;
    }
    template<typename T> int operator()(const std::vector<std::vector<T>>& vss)
    {
        for (int i = 0; i < (int)vss.size(); i++) { os << (0 <= i or i + 1 < (int)vss.size() ? "\n" : ""), this->operator()(vss[i]); }
        return 0;
    }
    template<typename T, typename... Args> int operator()(const T& v, const Args&... args) { return this->operator()(v), os << ' ', this->operator()(args...), 0; }
    template<typename... Args> int ln(const Args&... args) { return this->operator()(args...), os << '\n', 0; }
    template<typename... Args> int el(const Args&... args) { return this->operator()(args...), os << std::endl, 0; }
    template<typename... Args> int fmt(const std::string& s, const Args&... args) { return rec(s, 0, args...); }

private:
    int rec(const std::string& s, int index) { return os << s.substr(index, s.size()), 0; }
    template<typename T, typename... Args> int rec(const std::string& s, int index, const T& v, const Args&... args) { return index == s.size() ? 0 : s[index] == '%' ? (this->operator()(v), rec(s, index + 1, args...)) : (os << s[index], rec(s, index + 1, v, args...)); }
    std::ostream& os;
};
printer out;
class scanner
{
public:
    scanner(std::istream& is_ = std::cin) : is{is_} { is.tie(nullptr), std::ios::sync_with_stdio(false); }
    template<typename T> T val()
    {
        T v;
        return is >> v, v;
    }
    template<typename T> T val(const T offset) { return val<T>() - offset; }
    template<typename T> std::vector<T> vec(const int n)
    {
        std::vector<T> vs(n);
        for (auto& v : vs) { v = val<T>(); }
        return vs;
    }
    template<typename T> std::vector<T> vec(const int n, const T offset)
    {
        std::vector<T> vs(n);
        for (auto& v : vs) { v = val<T>(offset); }
        return vs;
    }
    template<typename T> std::vector<std::vector<T>> vvec(const int n0, const int n1)
    {
        std::vector<std::vector<T>> vss(n0);
        for (auto& vs : vss) { vs = vec<T>(n1); }
        return vss;
    }
    template<typename T> std::vector<std::vector<T>> vvec(const int n0, const int n1, const T offset)
    {
        std::vector<std::vector<T>> vss(n0);
        for (auto& vs : vss) { vs = vec<T>(n1, offset); }
        return vss;
    }
    template<typename... Args> auto tup() { return std::tuple<std::decay_t<Args>...>{val<Args>()...}; }
    template<typename... Args> auto tup(const Args&... offsets) { return std::tuple<std::decay_t<Args>...>{val<Args>(offsets)...}; }

private:
    std::istream& is;
};
scanner in;
#    define SHOW(...) static_cast<void>(0)
int main()
{
    const auto [N, Q] = in.tup<int, int>();
    std::vector<ll> as(N), bs(N);
    for (int i = 0; i < N; i++) { std::tie(as[i], bs[i]) = in.tup<ll, ll>(); }
    std::vector<int> ts(Q + 2), ls(Q + 2), rs(Q + 2);
    std::vector<ll> xs(Q + 2);
    ts[0] = 1, ls[0] = 0, rs[0] = N, xs[0] = 0;
    ts[Q + 1] = 1, ls[Q + 1] = 0, rs[Q + 1] = N, xs[Q + 1] = inf_v<ll>;
    for (int q = 1; q <= Q; q++) {
        std::tie(ts[q], ls[q], rs[q]) = in.tup<int, int, int>(0, 1, 0);
        xs[q]                         = ts[q] == 1 ? in.val<ll>() : 0LL;
    }

    std::vector<int> over(N);  // over[i] = j <=> Become as[i]>bs[i] right after j-th query
                               // [Note] 0 <= over[i] < Q+2 (forall i)
    using pii = std::pair<int, int>;
    using ppv = std::pair<pii, std::vector<int>>;

    std::vector<ppv> infos{{{0, Q + 2}, {}}};  // Items are like: {[L,R], {i1,i2,...}}
                                               //                 L <= over[i] < R (i = i1,i2,...)
    for (int i = 0; i < N; i++) { infos[0].second.push_back(i); }

    while (not infos.empty()) {
        std::vector<ppv> ninfos;
        int qid         = 0;
        auto bit        = fenwick(std::vector<ll>(N, 0));
        auto distribute = [&](const ppv& info) -> void {
            const auto [l, r] = info.first;
            const auto& is    = info.second;
            if (r - l == 1) {
                for (const int i : is) { over[i] = l; }
                return;
            }
            const auto mid = (l + r) / 2;
            while (qid + 1 < mid) {  // Test after (mid-1)-th query
                const auto t = ts[qid];
                if (t == 1) {
                    const auto ql = ls[qid], qr = rs[qid];
                    const auto qx = xs[qid];
                    bit.add(ql, qx);
                    if (qr < N) { bit.add(qr, -qx); }
                }
                qid++;
            }
            std::vector<int> firsts, seconds;
            for (const int i : is) {
                const auto a_i = as[i] + bit.sum(i + 1);
                if (a_i > bs[i]) {  // l <= over[i] < mid
                    firsts.push_back(i);
                } else {  // mid <= over[i] < r
                    seconds.push_back(i);
                }
            }
            if (not firsts.empty()) { ninfos.push_back({{l, mid}, firsts}); }
            if (not seconds.empty()) { ninfos.push_back({{mid, r}, seconds}); }
        };
        for (const auto& info : infos) { distribute(info); }
        infos = ninfos;
        ninfos.clear();
    }
    std::vector<std::vector<int>> iss(Q + 2);
    for (int i = 0; i < N; i++) { iss[over[i]].push_back(i); }

    SHOW(over);

    auto bit  = fenwick(std::vector<ll>(N, 0));
    auto aseg = lazyseg(std::vector<ll>(N, inf_v<ll>), min_merge, inf_v<ll>, plus_comp, 0LL, min_plus_apply);
    auto bseg = lazyseg(bs, min_merge, inf_v<ll>, plus_comp, 0LL, min_plus_apply);
    for (int q = 0; q < Q + 2; q++) {
        const auto t = ts[q];
        const auto l = ls[q], r = rs[q];
        if (t == 1) {
            const auto x = xs[q];
            SHOW("Query 1.", q, t, l, r, x);
            bit.add(ls[q], x);
            if (rs[q] < N) { bit.add(rs[q], -x); }
            aseg.act(ls[q], rs[q], x);
        } else {
            SHOW("Query 2.", q, t, l, r);
            const auto amin = aseg.fold(l, r);
            const auto bmin = bseg.fold(l, r);
            SHOW(amin, bmin);
            out.ln(std::min(amin, bmin));
        }
        for (const int i : iss[q]) {
            const auto a_i = as[i] + bit.sum(i + 1);
            SHOW("Updating.", i, a_i, bs[i]);
            assert(a_i > bs[i]);
            aseg.set(i, a_i);
            bseg.set(i, inf_v<ll>);
        }
        SHOW(aseg);
        SHOW(bseg);
    }
    return 0;
}
accuracy: 0.2
time_ms: 120
memory_kb: 20352
final_rank: 17

code_snippet: /* preprocessor start */
#ifdef LOCAL
//*
    #define _GLIBCXX_DEBUG  // gcc
/*/
    #define _LIBCPP_DEBUG 0 // clang
//*/
    #define __clock__
    // #define __buffer_check__
#else
    #pragma GCC optimize("Ofast")
/*
    #define _GLIBCXX_DEBUG  // gcc
/*/
//    #define _LIBCPP_DEBUG 0 // clang
//*/
    // #define __buffer_check__
    // #define NDEBUG
#endif
#define __precision__ 10
#define iostream_untie true
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#define __all(v) std::begin(v), std::end(v)
#define __rall(v) std::rbegin(v), std::rend(v)
#define __popcount(n) __builtin_popcountll(n)
#define __clz32(n) __builtin_clz(n)
#define __clz64(n) __builtin_clzll(n)
#define __ctz32(n) __builtin_ctz(n)
#define __ctz64(n) __builtin_ctzll(n)
/* preprocessor end */

namespace std
{
    // hash
    template <class T> size_t hash_combine(size_t seed, T const &key) { return seed ^ (hash<T>()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); }
    template <class T, class U> struct hash<pair<T, U>> { size_t operator()(pair<T, U> const &pr) const { return hash_combine(hash_combine(0, pr.first), pr.second); } };
    template <class tuple_t, size_t index = tuple_size<tuple_t>::value - 1> struct tuple_hash_calc { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(tuple_hash_calc<tuple_t, index - 1>::apply(seed, t), get<index>(t)); } };
    template <class tuple_t> struct tuple_hash_calc<tuple_t, 0> { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(seed, get<0>(t)); } };
    template <class... T> struct hash<tuple<T...>> { size_t operator()(tuple<T...> const &t) const { return tuple_hash_calc<tuple<T...>>::apply(0, t); } };
    // iostream
    template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { return is >> p.first >> p.second; }
    template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { return os << p.first << ' ' << p.second; }
    template <class tuple_t, size_t index> struct tupleis { static istream &apply(istream &is, tuple_t &t) { tupleis<tuple_t, index - 1>::apply(is, t); return is >> get<index>(t); } };
    template <class tuple_t> struct tupleis<tuple_t, SIZE_MAX> { static istream &apply(istream &is, tuple_t &t) { return is; } };
    template <class... T> istream &operator>>(istream &is, tuple<T...> &t) { return tupleis<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(is, t); }
    template <> istream &operator>>(istream &is, tuple<> &t) { return is; }
    template <class tuple_t, size_t index> struct tupleos { static ostream &apply(ostream &os, const tuple_t &t) { tupleos<tuple_t, index - 1>::apply(os, t); return os << ' ' << get<index>(t); } };
    template <class tuple_t> struct tupleos<tuple_t, 0> { static ostream &apply(ostream &os, const tuple_t &t) { return os << get<0>(t); } };
    template <class... T> ostream &operator<<(ostream &os, const tuple<T...> &t) { return tupleos<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(os, t); }
    template <> ostream &operator<<(ostream &os, const tuple<> &t) { return os; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    istream& operator>>(istream& is, Container &cont) { for(auto&& e : cont) is >> e; return is; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    ostream& operator<<(ostream& os, const Container &cont) { bool flag = 1; for(auto&& e : cont) flag ? flag = 0 : (os << ' ', 0), os << e; return os; }
} // namespace std

namespace setting
{
    using namespace std;
    using namespace chrono;
    system_clock::time_point start_time, end_time;
    long long get_elapsed_time() { end_time = system_clock::now(); return duration_cast<milliseconds>(end_time - start_time).count(); }
    void print_elapsed_time() { cerr << "\n----- Exec time : " << get_elapsed_time() << " ms -----\n\n"; }
    void buffer_check() { char bufc; if(cin >> bufc) cerr << "\n\033[1;35mwarning\033[0m: buffer not empty.\n"; }
    struct setupper
    {
        setupper()
        {
            if(iostream_untie) ios::sync_with_stdio(false), cin.tie(nullptr);
            cout << fixed << setprecision(__precision__);
    #ifdef stderr_path
            if(freopen(stderr_path, "a", stderr)) cerr << fixed << setprecision(__precision__);
    #endif
    #ifdef LOCAL
            cerr << boolalpha << "\n----- stderr at LOCAL -----\n\n";
    #endif
    #ifdef __buffer_check__
            atexit(buffer_check);
    #endif
    #ifdef __clock__
            start_time = system_clock::now();
            atexit(print_elapsed_time);
    #endif
        }
    } __setupper; // struct setupper
} // namespace setting

#ifdef __clock__
    #include "C:\Users\euler\OneDrive\Documents\Competitive_Programming\Library\local\clock.hpp"
#else
    #define build_clock() ((void)0)
    #define set_clock() ((void)0)
    #define get_clock() ((void)0)
#endif

#ifdef LOCAL
    #include "C:\Users\euler\OneDrive\Documents\Competitive_Programming\Library\local\dump.hpp"
#else
    #define dump(...) ((void)0)
#endif

/* function utility start */
template <class T, class... types> T read(types... args) noexcept { typename std::remove_const<T>::type obj(args...); std::cin >> obj; return obj; }
#define input(type, var, ...) type var{read<type>(__VA_ARGS__)}
// substitute y for x if x > y.
template <class T> inline bool chmin(T &x, const T &y) { return x > y ? x = y, true : false; }
// substitute y for x if x < y.
template <class T> inline bool chmax(T &x, const T &y) { return x < y ? x = y, true : false; }
// binary search on discrete range.
template <class iter_type, class pred_type>
iter_type binary(iter_type __ok, iter_type __ng, pred_type pred)
{
    std::ptrdiff_t dist(__ng - __ok);
    while(std::abs(dist) > 1)
    {
        iter_type mid(__ok + dist / 2);
        if(pred(mid)) __ok = mid, dist -= dist / 2;
        else __ng = mid, dist /= 2;
    }
    return __ok;
}
// binary search on real numbers.
template <class pred_type>
long double binary(long double __ok, long double __ng, const long double eps, pred_type pred)
{
    while(std::abs(__ok - __ng) > eps)
    {
        long double mid{(__ok + __ng) / 2};
        (pred(mid) ? __ok : __ng) = mid;
    }
    return __ok;
}
// size of array.
template <class A, size_t N> size_t size(A (&array)[N]) { return N; }
// be careful that val is type-sensitive.
template <class T, class A, size_t N> void init(A (&array)[N], const T &val) { std::fill((T*)array, (T*)(array + N), val); }
/* functon utility end */

/* using alias start */
using namespace std;
using i32 = int_least32_t; using i64 = int_least64_t; using u32 = uint_least32_t; using u64 = uint_least64_t;
using p32 = pair<i32, i32>; using p64 = pair<i64, i64>;
template <class T, class Comp = less<T>> using heap = priority_queue<T, vector<T>, Comp>;
template <class T> using hashset = unordered_set<T>;
template <class Key, class Value> using hashmap = unordered_map<Key, Value>;
/* using alias end */

/* library start */



/* library end */

/* The main code follows. */

template <class T> void _main();
struct solver;
int main() { _main<solver>(); }

template <class solver>
void _main()
{
    unsigned t;
#ifdef LOCAL
    t = 1;
#else
    t = 1; // single test case
#endif
    // t = -1; // infinite loop
    // cin >> t; // case number given

    while(t--) solver();
}

struct solver
{

    vector<vector<int>> id;
    vector<vector<i64>> lb,ra;
    vector<i64> a,b;
    vector<i64> inc;

    solver()
    {
        const i64 inf=1e16;
        int n,Q; cin>>n>>Q;
        a.resize(n),b.resize(n);
        const int B=sqrt(3*n),m=(n-1+B)/B;
        id.resize(m);
        inc.resize(m);
        lb.resize(m),ra.resize(m);

        // initialize
        for(int i=0,k=0;i<n;i+=B,++k)
        {
            for(int j=i;j<n and j<i+B;++j)
            {
                id[k].emplace_back(j);
                cin>>a[j]>>b[j];
            }
            sort(__all(id[k]),
            [&](const auto &x, const auto &y)
            {
                return a[x]-b[x]<a[y]-b[y];
            });

            int sz=id[k].size();

            lb[k].emplace_back(inf);
            lb[k].resize(sz+1);
            for(int j=0;j<sz;++j)
            {
                lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
            }

            ra[k].resize(sz);
            ra[k].emplace_back(inf);
            for(int j=sz;j;--j)
            {
                ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
            }
        }

        // process queries
        for(int type,l,r,x;Q--;)
        {
            cin>>type>>l>>r; --l;
            const int ll=l/B,rr=r/B;

            if(type==1) // interval add
            {
                cin>>x;
                for(int k=ll+1;k<rr;++k)
                {
                    inc[k]+=x;
                }
                if(ll<rr)
                {
                    // left most
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    for(int i=l;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });
                    {
                        const int k=ll;
                        for(int j=ra[k].size()-1;j;--j)
                        {
                            ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                        }
                        for(size_t j=0;j+1<lb[k].size();++j)
                        {
                            lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
                        }
                    }

                    // right most
                    for(int i=rr*B;i<(rr+1)*B and i<n;++i)
                    {
                        a[i]+=inc[rr];
                    }
                    inc[rr]=0;
                    for(int i=rr*B;i<r;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[rr]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });
                    {
                        const int k=rr;
                        for(int j=ra[k].size()-1;j;--j)
                        {
                            ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                        }
                        for(size_t j=0;j+1<lb[k].size();++j)
                        {
                            lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
                        }
                    }
                }
                else
                {
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    for(int i=l;i<r;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=ll;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }
                    for(size_t j=0;j+1<lb[k].size();++j)
                    {
                        lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
                    }
                }
            }
            else // range min of max
            {
                i64 ans=inf;
                for(int k=ll+1;k<rr;++k)
                {
                    // binary search
                    int ok=m,ng=-1;
                    while(ok-ng>1)
                    {
                        int mid=(ok+ng)/2;
                        int now=id[k][mid];
                        if(a[now]+inc[k]>=b[now])
                        {
                            ok=mid;
                        }
                        else
                        {
                            ng=mid;
                        }
                    }
                    chmin(ans, lb[k][ok]);
                    chmin(ans, ra[k][ok]+inc[k]);
                }

                dump(ans);

                // left most
                {
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=ll;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }
                    for(size_t j=0;j+1<lb[k].size();++j)
                    {
                        lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
                    }

                    for(int i=l;i<(ll+1)*B and i<r;++i)
                    {
                        chmin(ans, max(a[i],b[i]));
                    }
                }

                dump(ans);

                // right most
                {
                    for(int i=rr*B;i<(rr+1)*B and i<n;++i)
                    {
                        a[i]+=inc[rr];
                    }
                    inc[rr]=0;
                    sort(__all(id[rr]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=rr;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }
                    for(size_t j=0;j+1<lb[k].size();++j)
                    {
                        lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
                    }

                    for(int i=max(l,rr*B);i<r;++i)
                    {
                        chmin(ans, max(a[i],b[i]));
                    }
                }

                cout << ans << "\n";
            }
        }
    }
};
accuracy: 0.2
time_ms: 1910
memory_kb: 7620
final_rank: 20

code_snippet: /* preprocessor start */
#ifdef LOCAL
//*
    #define _GLIBCXX_DEBUG  // gcc
/*/
    #define _LIBCPP_DEBUG 0 // clang
//*/
    #define __clock__
    // #define __buffer_check__
#else
    #pragma GCC optimize("Ofast")
/*
    #define _GLIBCXX_DEBUG  // gcc
/*/
//    #define _LIBCPP_DEBUG 0 // clang
//*/
    // #define __buffer_check__
    // #define NDEBUG
#endif
#define __precision__ 10
#define iostream_untie true
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#define __all(v) std::begin(v), std::end(v)
#define __rall(v) std::rbegin(v), std::rend(v)
#define __popcount(n) __builtin_popcountll(n)
#define __clz32(n) __builtin_clz(n)
#define __clz64(n) __builtin_clzll(n)
#define __ctz32(n) __builtin_ctz(n)
#define __ctz64(n) __builtin_ctzll(n)
/* preprocessor end */

namespace std
{
    // hash
    template <class T> size_t hash_combine(size_t seed, T const &key) { return seed ^ (hash<T>()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); }
    template <class T, class U> struct hash<pair<T, U>> { size_t operator()(pair<T, U> const &pr) const { return hash_combine(hash_combine(0, pr.first), pr.second); } };
    template <class tuple_t, size_t index = tuple_size<tuple_t>::value - 1> struct tuple_hash_calc { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(tuple_hash_calc<tuple_t, index - 1>::apply(seed, t), get<index>(t)); } };
    template <class tuple_t> struct tuple_hash_calc<tuple_t, 0> { static size_t apply(size_t seed, tuple_t const &t) { return hash_combine(seed, get<0>(t)); } };
    template <class... T> struct hash<tuple<T...>> { size_t operator()(tuple<T...> const &t) const { return tuple_hash_calc<tuple<T...>>::apply(0, t); } };
    // iostream
    template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { return is >> p.first >> p.second; }
    template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { return os << p.first << ' ' << p.second; }
    template <class tuple_t, size_t index> struct tupleis { static istream &apply(istream &is, tuple_t &t) { tupleis<tuple_t, index - 1>::apply(is, t); return is >> get<index>(t); } };
    template <class tuple_t> struct tupleis<tuple_t, SIZE_MAX> { static istream &apply(istream &is, tuple_t &t) { return is; } };
    template <class... T> istream &operator>>(istream &is, tuple<T...> &t) { return tupleis<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(is, t); }
    template <> istream &operator>>(istream &is, tuple<> &t) { return is; }
    template <class tuple_t, size_t index> struct tupleos { static ostream &apply(ostream &os, const tuple_t &t) { tupleos<tuple_t, index - 1>::apply(os, t); return os << ' ' << get<index>(t); } };
    template <class tuple_t> struct tupleos<tuple_t, 0> { static ostream &apply(ostream &os, const tuple_t &t) { return os << get<0>(t); } };
    template <class... T> ostream &operator<<(ostream &os, const tuple<T...> &t) { return tupleos<tuple<T...>, tuple_size<tuple<T...>>::value - 1>::apply(os, t); }
    template <> ostream &operator<<(ostream &os, const tuple<> &t) { return os; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    istream& operator>>(istream& is, Container &cont) { for(auto&& e : cont) is >> e; return is; }
    template <class Container, typename Value = typename Container::value_type, enable_if_t<!is_same<decay_t<Container>, string>::value, nullptr_t> = nullptr>
    ostream& operator<<(ostream& os, const Container &cont) { bool flag = 1; for(auto&& e : cont) flag ? flag = 0 : (os << ' ', 0), os << e; return os; }
} // namespace std

namespace setting
{
    using namespace std;
    using namespace chrono;
    system_clock::time_point start_time, end_time;
    long long get_elapsed_time() { end_time = system_clock::now(); return duration_cast<milliseconds>(end_time - start_time).count(); }
    void print_elapsed_time() { cerr << "\n----- Exec time : " << get_elapsed_time() << " ms -----\n\n"; }
    void buffer_check() { char bufc; if(cin >> bufc) cerr << "\n\033[1;35mwarning\033[0m: buffer not empty.\n"; }
    struct setupper
    {
        setupper()
        {
            if(iostream_untie) ios::sync_with_stdio(false), cin.tie(nullptr);
            cout << fixed << setprecision(__precision__);
    #ifdef stderr_path
            if(freopen(stderr_path, "a", stderr)) cerr << fixed << setprecision(__precision__);
    #endif
    #ifdef LOCAL
            cerr << boolalpha << "\n----- stderr at LOCAL -----\n\n";
    #endif
    #ifdef __buffer_check__
            atexit(buffer_check);
    #endif
    #ifdef __clock__
            start_time = system_clock::now();
            atexit(print_elapsed_time);
    #endif
        }
    } __setupper; // struct setupper
} // namespace setting

#ifdef __clock__
    #include "C:\Users\euler\OneDrive\Documents\Competitive_Programming\Library\local\clock.hpp"
#else
    #define build_clock() ((void)0)
    #define set_clock() ((void)0)
    #define get_clock() ((void)0)
#endif

#ifdef LOCAL
    #include "C:\Users\euler\OneDrive\Documents\Competitive_Programming\Library\local\dump.hpp"
#else
    #define dump(...) ((void)0)
#endif

/* function utility start */
template <class T, class... types> T read(types... args) noexcept { typename std::remove_const<T>::type obj(args...); std::cin >> obj; return obj; }
#define input(type, var, ...) type var{read<type>(__VA_ARGS__)}
// substitute y for x if x > y.
template <class T> inline bool chmin(T &x, const T &y) { return x > y ? x = y, true : false; }
// substitute y for x if x < y.
template <class T> inline bool chmax(T &x, const T &y) { return x < y ? x = y, true : false; }
// binary search on discrete range.
template <class iter_type, class pred_type>
iter_type binary(iter_type __ok, iter_type __ng, pred_type pred)
{
    std::ptrdiff_t dist(__ng - __ok);
    while(std::abs(dist) > 1)
    {
        iter_type mid(__ok + dist / 2);
        if(pred(mid)) __ok = mid, dist -= dist / 2;
        else __ng = mid, dist /= 2;
    }
    return __ok;
}
// binary search on real numbers.
template <class pred_type>
long double binary(long double __ok, long double __ng, const long double eps, pred_type pred)
{
    while(std::abs(__ok - __ng) > eps)
    {
        long double mid{(__ok + __ng) / 2};
        (pred(mid) ? __ok : __ng) = mid;
    }
    return __ok;
}
// size of array.
template <class A, size_t N> size_t size(A (&array)[N]) { return N; }
// be careful that val is type-sensitive.
template <class T, class A, size_t N> void init(A (&array)[N], const T &val) { std::fill((T*)array, (T*)(array + N), val); }
/* functon utility end */

/* using alias start */
using namespace std;
using i32 = int_least32_t; using i64 = int_least64_t; using u32 = uint_least32_t; using u64 = uint_least64_t;
using p32 = pair<i32, i32>; using p64 = pair<i64, i64>;
template <class T, class Comp = less<T>> using heap = priority_queue<T, vector<T>, Comp>;
template <class T> using hashset = unordered_set<T>;
template <class Key, class Value> using hashmap = unordered_map<Key, Value>;
/* using alias end */

/* library start */



/* library end */

/* The main code follows. */

template <class T> void _main();
struct solver;
int main() { _main<solver>(); }

template <class solver>
void _main()
{
    unsigned t;
#ifdef LOCAL
    t = 1;
#else
    t = 1; // single test case
#endif
    // t = -1; // infinite loop
    // cin >> t; // case number given

    while(t--) solver();
}

struct solver
{

    vector<vector<int>> id;
    vector<vector<i64>> lb,ra;
    vector<i64> a,b;
    vector<i64> inc;

    solver()
    {
        const i64 inf=1e16;
        int n,Q; cin>>n>>Q;
        a.resize(n),b.resize(n);
        const int B=sqrt(3*n),m=(n-1+B)/B;
        id.resize(m);
        inc.resize(m);
        lb.resize(m),ra.resize(m);

        // initialize
        for(int i=0,k=0;i<n;i+=B,++k)
        {
            for(int j=i;j<n and j<i+B;++j)
            {
                id[k].emplace_back(j);
                cin>>a[j]>>b[j];
            }
            sort(__all(id[k]),
            [&](const auto &x, const auto &y)
            {
                return a[x]-b[x]<a[y]-b[y];
            });

            int sz=id[k].size();

            lb[k].emplace_back(inf);
            lb[k].resize(sz+1);
            for(int j=0;j<sz;++j)
            {
                lb[k][j+1]=min(lb[k][j],b[id[k][j]]);
            }

            ra[k].resize(sz);
            ra[k].emplace_back(inf);
            for(int j=sz;j;--j)
            {
                ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
            }
        }

        // process queries
        for(int type,l,r,x;Q--;)
        {
            cin>>type>>l>>r; --l;
            const int ll=l/B,rr=r/B;

            if(type==1) // interval add
            {
                cin>>x;
                for(int k=ll+1;k<rr;++k)
                {
                    inc[k]+=x;
                }
                if(ll<rr)
                {
                    // left most
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    for(int i=l;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });
                    {
                        const int k=ll;
                        for(int j=ra[k].size()-1;j;--j)
                        {
                            ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                        }
                    }

                    // right most
                    for(int i=rr*B;i<(rr+1)*B and i<n;++i)
                    {
                        a[i]+=inc[rr];
                    }
                    inc[rr]=0;
                    for(int i=rr*B;i<r;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[rr]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });
                    {
                        const int k=rr;
                        for(int j=ra[k].size()-1;j;--j)
                        {
                            ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                        }
                    }
                }
                else
                {
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    for(int i=l;i<r;++i)
                    {
                        a[i]+=x;
                    }
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=ll;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }
                }
            }
            else // range min of max
            {
                i64 ans=inf;
                for(int k=ll+1;k<rr;++k)
                {
                    // binary search
                    int ok=m,ng=-1;
                    while(ok-ng>1)
                    {
                        int mid=(ok+ng)/2;
                        int now=id[k][mid];
                        if(a[now]+inc[k]>=b[now])
                        {
                            ok=mid;
                        }
                        else
                        {
                            ng=mid;
                        }
                    }
                    chmin(ans, lb[k][ok]);
                    chmin(ans, ra[k][ok]+inc[k]);
                }

                dump(ans);

                // left most
                {
                    for(int i=ll*B;i<(ll+1)*B and i<n;++i)
                    {
                        a[i]+=inc[ll];
                    }
                    inc[ll]=0;
                    sort(__all(id[ll]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=ll;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }

                    for(int i=l;i<(ll+1)*B and i<r;++i)
                    {
                        chmin(ans, max(a[i],b[i]));
                    }
                }

                dump(ans);

                // right most
                {
                    for(int i=rr*B;i<(rr+1)*B and i<n;++i)
                    {
                        a[i]+=inc[rr];
                    }
                    inc[rr]=0;
                    sort(__all(id[rr]),
                    [&](const auto &x, const auto &y)
                    {
                        return a[x]-b[x]<a[y]-b[y];
                    });

                    const int k=rr;
                    for(int j=ra[k].size()-1;j;--j)
                    {
                        ra[k][j-1]=min(ra[k][j],a[id[k][j-1]]);
                    }

                    for(int i=max(l,rr*B);i<r;++i)
                    {
                        chmin(ans, max(a[i],b[i]));
                    }
                }

                cout << ans << "\n";
            }
        }
    }
};
accuracy: 0.2
time_ms: 1850
memory_kb: 7576
final_rank: 19

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

const int N = 100000, S = (N + sqrt(N) - 1) / sqrt(N);
ll A[N], B[N], sumX[S] = {};
vector<ll> ruiA[S], ruiB[S];
vector<int> v[S];
int lb[S];

int b, b_n, L[S], R[S];
bool need_to_be_eval[S] = {}, need_to_calc[S] = {};

void evaluate(int b, int l, int r) {
  if (sumX[b] == 0) return;
  FOR(i, l, r) A[i] += sumX[b];
  for (ll &e : ruiA[b]) e += sumX[b];
  sumX[b] = 0;
}

void calc_lb(int idx) {
  lb[idx] = -1;
  int ub = v[idx].size();
  while (ub - lb[idx] > 1) {
    int mid = (lb[idx] + ub) >> 1;
    (A[v[idx][mid]] - B[v[idx][mid]] <= -sumX[idx] ? lb[idx] : ub) = mid;
  }
  need_to_calc[idx] = false;
}

void init(int idx) {
  sort(ALL(v[idx]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
  ruiB[idx][0] = B[v[idx][0]];
  FOR(i, 1, ruiB[idx].size()) ruiB[idx][i] = min(ruiB[idx][i - 1], B[v[idx][i]]);
  ruiA[idx].back() = A[v[idx].back()];
  for (int i = int(ruiA[idx].size()) - 2; i >= 0; --i) ruiA[idx][i] = min(ruiA[idx][i + 1], A[v[idx][i]]);
  need_to_be_eval[idx] = false;
  calc_lb(idx);
}

int main() {
  int n, q; cin >> n >> q;
  REP(i, n) cin >> A[i] >> B[i];
  b = sqrt(n);
  b_n = (n + b - 1) / b;
  REP(i, b_n) L[i] = b * i;
  REP(i, b_n - 1) R[i] = b * (i + 1);
  R[b_n - 1] = n;
  REP(i, b_n) {
    int sz = R[i] - L[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), L[i]);
  }
  REP(i, b_n) init(i);
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l;
    if (query == 1) {
      int x; cin >> x;
      int l_b = l / b, r_b = (r - 1) / b;
      if (l_b == r_b) {
        if (l == L[l_b] && r == R[r_b]) {
          need_to_calc[l_b] = true;
          sumX[l_b] += x;
        } else {
          need_to_be_eval[l_b] = true;
          FOR(i, l, r) A[i] += x;
        }
      } else {
        if (l == L[l_b]) {
          need_to_calc[l_b] = true;
          sumX[l_b] += x;
        } else {
          need_to_be_eval[l_b] = true;
          FOR(i, l, R[l_b]) A[i] += x;
        }
        FOR(i, l_b + 1, r_b) {
          need_to_calc[i] = true;
          sumX[i] += x;
        }
        if (r == R[r_b]) {
          need_to_calc[r_b] = true;
          sumX[r_b] += x;
        } else {
          need_to_be_eval[r_b] = true;
          FOR(i, L[r_b], r) A[i] += x;
        }
      }
    } else {
      int l_b = l / b, r_b = (r - 1) / b;
      ll ans = LINF;
      if (l_b == r_b) {
        evaluate(l_b, L[l_b], R[l_b]);
        FOR(i, l, r) chmin(ans, max(A[i], B[i]));
      } else {
        if (l == L[l_b]) {
          if (need_to_be_eval[l_b]) {
            init(l_b);
          } else if (need_to_calc[l_b]) {
            calc_lb(l_b);
          }
          chmin(ans, min(lb[l_b] == -1 ? LINF : ruiB[l_b][lb[l_b]], lb[l_b] + 1 == v[l_b].size() ? LINF : ruiA[l_b][lb[l_b] + 1] + sumX[l_b]));
        } else {
          evaluate(l_b, L[l_b], R[l_b]);
          FOR(i, l, R[l_b]) chmin(ans, max(A[i], B[i]));
        }
        FOR(i, l_b + 1, r_b) {
          if (need_to_be_eval[i]) {
            init(i);
          } else if (need_to_calc[i]) {
            calc_lb(i);
          }
          chmin(ans, min(lb[i] == -1 ? LINF : ruiB[i][lb[i]], lb[i] + 1 == v[i].size() ? LINF : ruiA[i][lb[i] + 1] + sumX[i]));
        }
        if (r == R[r_b]) {
          if (need_to_be_eval[r_b]) {
            init(r_b);
          } else if (need_to_calc[r_b]) {
            calc_lb(r_b);
          }
          chmin(ans, min(lb[r_b] == -1 ? LINF : ruiB[r_b][lb[r_b]], lb[r_b] + 1 == v[r_b].size() ? LINF : ruiA[r_b][lb[r_b] + 1] + sumX[r_b]));
        } else {
          evaluate(r_b, L[r_b], R[r_b]);
          FOR(i, L[r_b], r) chmin(ans, max(A[i], B[i]));
        }
      }
      cout << ans << '\n';
    }
  }
  return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 6568
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
  }
} iosetup;

inline void chmax(ll &a, ll b) { if (a < b) a = b; }
inline void chmin(ll &a, ll b) { if (a > b) a = b; }

const int N = 100000, S = 334, LEN = 300;

int b, b_n, L[S], R[S], len[S];
bool need_to_be_eval[S] = {};

ll A[N], B[N], sumX[S] = {}, ruiA[S][LEN], ruiB[S][LEN];
vector<int> v[S];

int main() {
  int n, q; cin >> n >> q;
  REP(i, n) cin >> A[i] >> B[i];
  b = sqrt(n);
  b_n = (n + b - 1) / b;
  REP(i, b_n) L[i] = b * i;
  REP(i, b_n - 1) R[i] = b * (i + 1);
  R[b_n - 1] = n;
  REP(i, b_n) {
    len[i] = R[i] - L[i];
    v[i].resize(len[i]);
    iota(ALL(v[i]), L[i]);
    sort(ALL(v[i]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
    ruiB[i][0] = B[v[i][0]];
    FOR(j, 1, len[i]) ruiB[i][j] = min(ruiB[i][j - 1], B[v[i][j]]);
    ruiA[i][len[i] - 1] = A[v[i].back()];
    for (int j = len[i] - 2; j >= 0; --j) ruiA[i][j] = min(ruiA[i][j + 1], A[v[i][j]]);
  }
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l;
    if (query == 1) {
      int x; cin >> x;
      int l_b = l / b, r_b = (r - 1) / b;
      if (l_b == r_b) {
        need_to_be_eval[l_b] = true;
        FOR(i, l, r) A[i] += x;
      } else {
        if (l == L[l_b]) {
          sumX[l_b] += x;
        } else {
          need_to_be_eval[l_b] = true;
          FOR(i, l, R[l_b]) A[i] += x;
        }
        FOR(i, l_b + 1, r_b) sumX[i] += x;
        if (r == R[r_b]) {
          sumX[r_b] += x;
        } else {
          need_to_be_eval[r_b] = true;
          FOR(i, L[r_b], r) A[i] += x;
        }
      }
    } else {
      int l_b = l / b, r_b = (r - 1) / b;
      ll ans = LINF;
      if (l_b == r_b) {
        if (sumX[l_b] != 0) {
          FOR(i, L[l_b], R[l_b]) A[i] += sumX[l_b];
          REP(i, len[l_b]) ruiA[l_b][i] += sumX[l_b];
          sumX[l_b] = 0;
        }
        FOR(i, l, r) chmin(ans, max(A[i], B[i]));
      } else {
        if (l == L[l_b]) {
          if (need_to_be_eval[l_b]) {
            sort(ALL(v[l_b]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[l_b][0] = B[v[l_b][0]];
            FOR(i, 1, len[l_b]) ruiB[l_b][i] = min(ruiB[l_b][i - 1], B[v[l_b][i]]);
            ruiA[l_b][len[l_b] - 1] = A[v[l_b].back()];
            for (int i = len[l_b] - 2; i >= 0; --i) ruiA[l_b][i] = min(ruiA[l_b][i + 1], A[v[l_b][i]]);
            need_to_be_eval[l_b] = false;
          }
          int lb = -1, ub = len[l_b];
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[l_b][mid]] - B[v[l_b][mid]] <= -sumX[l_b] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[l_b][lb], lb + 1 == len[l_b] ? LINF : ruiA[l_b][lb + 1] + sumX[l_b]));
        } else {
          if (sumX[l_b] != 0) {
            FOR(i, L[l_b], R[l_b]) A[i] += sumX[l_b];
            REP(i, len[l_b]) ruiA[l_b][i] += sumX[l_b];
            sumX[l_b] = 0;
          }
          FOR(i, l, R[l_b]) chmin(ans, max(A[i], B[i]));
        }
        FOR(i, l_b + 1, r_b) {
          if (need_to_be_eval[i]) {
            sort(ALL(v[i]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[i][0] = B[v[i][0]];
            FOR(j, 1, len[i]) ruiB[i][j] = min(ruiB[i][j - 1], B[v[i][j]]);
            ruiA[i][len[i] - 1] = A[v[i].back()];
            for (int j = len[i] - 2; j >= 0; --j) ruiA[i][j] = min(ruiA[i][j + 1], A[v[i][j]]);
            need_to_be_eval[i] = false;
          }
          int lb = -1, ub = len[i];
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[i][mid]] - B[v[i][mid]] <= -sumX[i] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[i][lb], lb + 1 == len[i] ? LINF : ruiA[i][lb + 1] + sumX[i]));
        }
        if (r == R[r_b]) {
          if (need_to_be_eval[r_b]) {
            sort(ALL(v[r_b]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[r_b][0] = B[v[r_b][0]];
            FOR(i, 1, len[r_b]) ruiB[r_b][i] = min(ruiB[r_b][i - 1], B[v[r_b][i]]);
            ruiA[r_b][len[r_b] - 1] = A[v[r_b].back()];
            for (int i = len[r_b] - 2; i >= 0; --i) ruiA[r_b][i] = min(ruiA[r_b][i + 1], A[v[r_b][i]]);
            need_to_be_eval[r_b] = false;
          }
          int lb = -1, ub = len[r_b];
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[r_b][mid]] - B[v[r_b][mid]] <= -sumX[r_b] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[r_b][lb], lb + 1 == len[r_b] ? LINF : ruiA[r_b][lb + 1] + sumX[r_b]));
        } else {
          if (sumX[r_b] != 0) {
            FOR(i, L[r_b], R[r_b]) A[i] += sumX[r_b];
            REP(i, len[r_b]) ruiA[r_b][i] += sumX[r_b];
            sumX[r_b] = 0;
          }
          FOR(i, L[r_b], r) chmin(ans, max(A[i], B[i]));
        }
      }
      cout << ans << '\n';
    }
  }
  return 0;
}
accuracy: 0.2
time_ms: 1260
memory_kb: 6464
final_rank: 15

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;


int main() {
  const int N = 100000, S = (N + sqrt(N) - 1) / sqrt(N);
  ll A[N], B[N], sumX[S] = {};
  vector<ll> ruiA[S], ruiB[S];
  vector<int> v[S];

  int b, b_n, L[S], R[S];
  bool need_to_be_eval[S] = {};

  int n, q; cin >> n >> q;
  REP(i, n) cin >> A[i] >> B[i];
  b = sqrt(n);
  b_n = (n + b - 1) / b;
  REP(i, b_n) L[i] = b * i;
  REP(i, b_n - 1) R[i] = b * (i + 1);
  R[b_n - 1] = n;
  REP(i, b_n) {
    int sz = R[i] - L[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), L[i]);
  }
  REP(i, b_n) {
    sort(ALL(v[i]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
    ruiB[i][0] = B[v[i][0]];
    FOR(j, 1, ruiB[i].size()) ruiB[i][j] = min(ruiB[i][j - 1], B[v[i][j]]);
    ruiA[i].back() = A[v[i].back()];
    for (int j = int(ruiA[i].size()) - 2; j >= 0; --j) ruiA[i][j] = min(ruiA[i][j + 1], A[v[i][j]]);
  }
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l;
    if (query == 1) {
      int x; cin >> x;
      int l_b = l / b, r_b = (r - 1) / b;
      if (l_b == r_b) {
        if (l == L[l_b] && r == R[r_b]) {
          sumX[l_b] += x;
        } else {
          need_to_be_eval[l_b] = true;
          FOR(i, l, r) A[i] += x;
        }
      } else {
        if (l == L[l_b]) {
          sumX[l_b] += x;
        } else {
          need_to_be_eval[l_b] = true;
          FOR(i, l, R[l_b]) A[i] += x;
        }
        FOR(i, l_b + 1, r_b) sumX[i] += x;
        if (r == R[r_b]) {
          sumX[r_b] += x;
        } else {
          need_to_be_eval[r_b] = true;
          FOR(i, L[r_b], r) A[i] += x;
        }
      }
    } else {
      int l_b = l / b, r_b = (r - 1) / b;
      ll ans = LINF;
      if (l_b == r_b) {
        if (sumX[l_b] != 0) {
          FOR(i, L[l_b], R[l_b]) A[i] += sumX[l_b];
          for (ll &e : ruiA[b]) e += sumX[l_b];
          sumX[l_b] = 0;
        }
        FOR(i, l, r) chmin(ans, max(A[i], B[i]));
      } else {
        if (l == L[l_b]) {
          if (need_to_be_eval[l_b]) {
            sort(ALL(v[l_b]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[l_b][0] = B[v[l_b][0]];
            FOR(i, 1, ruiB[l_b].size()) ruiB[l_b][i] = min(ruiB[l_b][i - 1], B[v[l_b][i]]);
            ruiA[l_b].back() = A[v[l_b].back()];
            for (int i = int(ruiA[l_b].size()) - 2; i >= 0; --i) ruiA[l_b][i] = min(ruiA[l_b][i + 1], A[v[l_b][i]]);
            need_to_be_eval[l_b] = false;
          }
          int lb = -1, ub = v[l_b].size();
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[l_b][mid]] - B[v[l_b][mid]] <= -sumX[l_b] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[l_b][lb], lb + 1 == v[l_b].size() ? LINF : ruiA[l_b][lb + 1] + sumX[l_b]));
        } else {
          if (sumX[l_b] != 0) {
            FOR(i, L[l_b], R[l_b]) A[i] += sumX[l_b];
            for (ll &e : ruiA[l_b]) e += sumX[l_b];
            sumX[l_b] = 0;
          }
          FOR(i, l, R[l_b]) chmin(ans, max(A[i], B[i]));
        }
        FOR(i, l_b + 1, r_b) {
          if (need_to_be_eval[i]) {
            sort(ALL(v[i]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[i][0] = B[v[i][0]];
            FOR(j, 1, ruiB[i].size()) ruiB[i][j] = min(ruiB[i][j - 1], B[v[i][j]]);
            ruiA[i].back() = A[v[i].back()];
            for (int j = int(ruiA[i].size()) - 2; j >= 0; --j) ruiA[i][j] = min(ruiA[i][j + 1], A[v[i][j]]);
            need_to_be_eval[i] = false;
          }
          int lb = -1, ub = v[i].size();
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[i][mid]] - B[v[i][mid]] <= -sumX[i] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[i][lb], lb + 1 == v[i].size() ? LINF : ruiA[i][lb + 1] + sumX[i]));
        }
        if (r == R[r_b]) {
          if (need_to_be_eval[r_b]) {
            sort(ALL(v[r_b]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
            ruiB[r_b][0] = B[v[r_b][0]];
            FOR(i, 1, ruiB[r_b].size()) ruiB[r_b][i] = min(ruiB[r_b][i - 1], B[v[r_b][i]]);
            ruiA[r_b].back() = A[v[r_b].back()];
            for (int i = int(ruiA[r_b].size()) - 2; i >= 0; --i) ruiA[r_b][i] = min(ruiA[r_b][i + 1], A[v[r_b][i]]);
            need_to_be_eval[r_b] = false;
          }
          int lb = -1, ub = v[r_b].size();
          while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (A[v[r_b][mid]] - B[v[r_b][mid]] <= -sumX[r_b] ? lb : ub) = mid;
          }
          chmin(ans, min(lb == -1 ? LINF : ruiB[r_b][lb], lb + 1 == v[r_b].size() ? LINF : ruiA[r_b][lb + 1] + sumX[r_b]));
        } else {
          if (sumX[r_b] != 0) {
            FOR(i, L[r_b], R[r_b]) A[i] += sumX[r_b];
            for (ll &e : ruiA[r_b]) e += sumX[r_b];
            sumX[r_b] = 0;
          }
          FOR(i, L[r_b], r) chmin(ans, max(A[i], B[i]));
        }
      }
      cout << ans << '\n';
    }
  }
  return 0;
}
accuracy: 0.4
time_ms: 1270
memory_kb: 6560
final_rank: 11

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

const int N = 100000, S = (N + sqrt(N) - 1) / sqrt(N);
ll A[N], B[N], sumX[S] = {};
vector<ll> ruiA[S], ruiB[S];
vector<int> v[S];

void evaluate(int b, int l, int r) {
  FOR(i, l, r) A[i] += sumX[b];
  for (ll &e : ruiA[b]) e += sumX[b];
  sumX[b] = 0;
}

void init(int idx) {
  sort(ALL(v[idx]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
  ruiB[idx][0] = B[v[idx][0]];
  FOR(i, 1, ruiB[idx].size()) ruiB[idx][i] = min(ruiB[idx][i - 1], B[v[idx][i]]);
  ruiA[idx].back() = A[v[idx].back()];
  for (int i = int(ruiA[idx].size()) - 2; i >= 0; --i) ruiA[idx][i] = min(ruiA[idx][i + 1], A[v[idx][i]]);
}

template <typename T>
struct SqrtDecomposition {
  int b, b_n;
  vector<int> left, right;
  vector<bool> need_to_be_eval;

  SqrtDecomposition(int n) : b(sqrt(n)) {
    b_n = (n + b - 1) / b;
    left.resize(b_n);
    right.resize(b_n);
    need_to_be_eval.assign(b_n, false);
    REP(i, b_n) {
      left[i] = b * i;
      right[i] = (i + 1 == b_n ? n : b * (i + 1));
    }
  }

  void partial_update(int idx, T val);

  void total_update(int idx, T val);

  void update(int l, int r, T val) {
    int l_b = l / b, r_b = (r - 1) / b;
    if (l_b == r_b) {
      if (l == left[l_b] && r == right[r_b]) {
        total_update(l_b, val);
      } else {
        need_to_be_eval[l_b] = true;
        FOR(i, l, r) partial_update(i, val);
      }
    } else {
      if (l == left[l_b]) {
        total_update(l_b, val);
      } else {
        need_to_be_eval[l_b] = true;
        FOR(i, l, right[l_b]) partial_update(i, val);
      }
      FOR(i, l_b + 1, r_b) total_update(i, val);
      if (r == right[r_b]) {
        total_update(r_b, val);
      } else {
        need_to_be_eval[r_b] = true;
        FOR(i, left[r_b], r) partial_update(i, val);
      }
    }
  }

  void partial_query(int idx, T &val);

  void total_query(int idx, T &val);

  T query(int l, int r, T UNITY) {
    int l_b = l / b, r_b = (r - 1) / b;
    T res = UNITY;
    if (l_b == r_b) {
      FOR(i, l, r) partial_query(i, res);
    } else {
      if (l == left[l_b]) {
        if (need_to_be_eval[l_b]) {
          init(l_b);
          need_to_be_eval[l_b] = false;
        }
        total_query(l_b, res);
      } else {
        FOR(i, l, right[l_b]) partial_query(i, res);
      }
      FOR(i, l_b + 1, r_b) {
        if (need_to_be_eval[i]) {
          init(i);
          need_to_be_eval[i] = false;
        }
        total_query(i, res);
      }
      if (r == right[r_b]) {
        if (need_to_be_eval[r_b]) {
          init(r_b);
          need_to_be_eval[r_b] = false;
        }
        total_query(r_b, res);
      } else {
        FOR(i, left[r_b], r) partial_query(i, res);
      }
    }
    return res;
  }
};

template <typename T>
void SqrtDecomposition<T>::partial_update(int idx, T val) {
  A[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::total_update(int idx, T val) {
  sumX[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::partial_query(int idx, T &val) {
  chmin(val, max(A[idx] + sumX[idx], B[idx]));
}

template <typename T>
void SqrtDecomposition<T>::total_query(int idx, T &val) {
  int lb = -1, ub = v[idx].size();
  while (ub - lb > 1) {
    int mid = (lb + ub) >> 1;
    (A[v[idx][mid]] - B[v[idx][mid]] <= -sumX[idx] ? lb : ub) = mid;
  }
  chmin(val, min(lb == -1 ? LINF : ruiB[idx][lb], lb + 1 == v[idx].size() ? LINF : ruiA[idx][lb + 1] + sumX[idx]));
}

int main() {
  int n, q; cin >> n >> q;
  REP(i, n) cin >> A[i] >> B[i];
  SqrtDecomposition<ll> sd(n);
  REP(i, sd.b_n) {
    int sz = sd.right[i] - sd.left[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), sd.left[i]);
  }
  REP(i, sd.b_n) init(i);
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l;
    if (query == 1) {
      int x; cin >> x;
      sd.update(l, r, x);
    } else {
      cout << sd.query(l, r, LINF) << '\n';
    }
  }
  return 0;
}
accuracy: 0.2
time_ms: 1240
memory_kb: 6616
final_rank: 14

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

vector<ll> A, B, sumX;
vector<vector<ll> > ruiA, ruiB;
vector<vector<int> > v;

void evaluate(int b, int l, int r) {
  FOR(i, l, r) A[i] += sumX[b];
  sumX[b] = 0;
}

void init(int idx) {
  sort(ALL(v[idx]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
  REP(i, ruiB[idx].size()) ruiB[idx][i] = min(i == 0 ? LINF : ruiB[idx][i - 1], B[v[idx][i]]);
  for (int i = ruiA[idx].size() - 1; i >= 0; --i) ruiA[idx][i] = min(i + 1 == ruiA[idx].size() ? LINF : ruiA[idx][i + 1], A[v[idx][i]]);
}

template <typename T>
struct SqrtDecomposition {
  int b, b_n;
  vector<int> left, right;
  vector<bool> need_to_be_eval;

  SqrtDecomposition(int n) : b(sqrt(n)) {
    b_n = (n + b - 1) / b;
    left.resize(b_n);
    right.resize(b_n);
    need_to_be_eval.assign(b_n, false);
    REP(i, b_n) {
      left[i] = b * i;
      right[i] = (i + 1 == b_n ? n : b * (i + 1));
    }
  }

  void partial_update(int idx, T val);

  void total_update(int idx, T val);

  void update(int l, int r, T val) {
    if (r <= l) return;
    int l_b = l / b, r_b = (r - 1) / b;
    if (l_b == r_b) {
      need_to_be_eval[l_b] = true;
      FOR(i, l, r) partial_update(i, val);
    } else {
      need_to_be_eval[l_b] = true;
      FOR(i, l, right[l_b]) partial_update(i, val);
      FOR(i, l_b + 1, r_b) total_update(i, val);
      need_to_be_eval[r_b] = true;
      FOR(i, left[r_b], r) partial_update(i, val);
    }
  }

  void partial_query(int idx, T &val);

  void total_query(int idx, T &val);

  T query(int l, int r, T UNITY) {
    int l_b = l / b, r_b = (r - 1) / b;
    T res = UNITY;
    if (l_b == r_b) {
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      evaluate(l_b, left[l_b], right[l_b]);
      FOR(i, l, r) partial_query(i, res);
    } else if (l < r) {
      evaluate(l_b, left[l_b], right[l_b]);
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      FOR(i, l, right[l_b]) partial_query(i, res);
      FOR(i, l_b + 1, r_b) {
        if (need_to_be_eval[i]) {
          init(i);
          need_to_be_eval[i] = false;
        }
        total_query(i, res);
      }
      evaluate(r_b, left[r_b], right[r_b]);
      if (need_to_be_eval[r_b]) {
        init(r_b);
        need_to_be_eval[r_b] = false;
      }
      FOR(i, left[r_b], r) partial_query(i, res);
    }
    return res;
  }
};

template <typename T>
void SqrtDecomposition<T>::partial_update(int idx, T val) {
  A[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::total_update(int idx, T val) {
  sumX[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::partial_query(int idx, T &val) {
  chmin(val, max(A[idx] + sumX[idx / b], B[idx]));
}

template <typename T>
void SqrtDecomposition<T>::total_query(int idx, T &val) {
  int lb = 0, ub = v[idx].size();
  while (ub - lb > 1) {
    int mid = (lb + ub) / 2;
    (A[v[idx][mid]] - B[v[idx][mid]] <= -sumX[idx] ? lb : ub) = mid;
  }
  chmin(val, min(ruiB[idx][lb], lb + 1 == v[idx].size() ? LINF : ruiA[idx][lb + 1] + sumX[idx]));
}

int main() {
  int n, q; cin >> n >> q;
  A.resize(n);
  B.resize(n);
  REP(i, n) cin >> A[i] >> B[i];
  SqrtDecomposition<ll> sd(n);
  sumX.assign(sd.b_n, 0);
  ruiA.resize(sd.b_n);
  ruiB.resize(sd.b_n);
  v.resize(sd.b_n);
  REP(i, sd.b_n) {
    int sz = sd.right[i] - sd.left[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), sd.left[i]);
  }
  REP(i, sd.b_n) init(i);
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l; --r;
    if (query == 1) {
      int x; cin >> x;
      sd.update(l, r + 1, x);
    } else if (query == 2) {
      cout << sd.query(l, r + 1, LINF) << '\n';
    }

  }
  return 0;
}
accuracy: 0.2
time_ms: 1390
memory_kb: 6480
final_rank: 18

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

vector<ll> A, B, sumX;
vector<vector<ll> > ruiA, ruiB;
vector<vector<int> > v;

void evaluate(int b, int l, int r) {
  FOR(i, l, r) A[i] += sumX[b];
  sumX[b] = 0;
}

void init(int idx) {
  sort(ALL(v[idx]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
  REP(i, ruiB[idx].size()) ruiB[idx][i] = min(i == 0 ? LINF : ruiB[idx][i - 1], B[v[idx][i]]);
  for (int i = ruiA[idx].size() - 1; i >= 0; --i) ruiA[idx][i] = min(i + 1 == ruiA[idx].size() ? LINF : ruiA[idx][i + 1], A[v[idx][i]]);
}

template <typename T>
struct SqrtDecomposition {
  int b, b_n;
  vector<int> left, right;
  vector<bool> need_to_be_eval;

  SqrtDecomposition(int n) : b(sqrt(n)) {
    b_n = (n + b - 1) / b;
    left.resize(b_n);
    right.resize(b_n);
    need_to_be_eval.assign(b_n, false);
    REP(i, b_n) {
      left[i] = b * i;
      right[i] = (i + 1 == b_n ? n : b * (i + 1));
    }
  }

  void partial_update(int idx, T val);

  void total_update(int idx, T val);

  void update(int l, int r, T val) {
    if (r <= l) return;
    int l_b = l / b, r_b = (r - 1) / b;
    if (l_b == r_b) {
      need_to_be_eval[l_b] = true;
      FOR(i, l, r) partial_update(i, val);
    } else {
      need_to_be_eval[l_b] = true;
      FOR(i, l, right[l_b]) partial_update(i, val);
      FOR(i, l_b + 1, r_b) total_update(i, val);
      need_to_be_eval[r_b] = true;
      FOR(i, left[r_b], r) partial_update(i, val);
    }
  }

  void partial_query(int idx, T &val);

  void total_query(int idx, T &val);

  T query(int l, int r, T UNITY) {
    int l_b = l / b, r_b = (r - 1) / b;
    T res = UNITY;
    if (l_b == r_b) {
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      evaluate(l_b, left[l_b], right[l_b]);
      FOR(i, l, r) partial_query(i, res);
    } else if (l < r) {
      evaluate(l_b, left[l_b], right[l_b]);
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      FOR(i, l, right[l_b]) partial_query(i, res);
      FOR(i, l_b + 1, r_b) {
        if (need_to_be_eval[i]) {
          init(i);
          need_to_be_eval[i] = false;
        }
        total_query(i, res);
      }
      evaluate(r_b, left[r_b], right[r_b]);
      if (need_to_be_eval[r_b]) {
        init(r_b);
        need_to_be_eval[r_b] = false;
      }
      FOR(i, left[r_b], r) partial_query(i, res);
    }
    return res;
  }
};

template <typename T>
void SqrtDecomposition<T>::partial_update(int idx, T val) {
  A[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::total_update(int idx, T val) {
  sumX[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::partial_query(int idx, T &val) {
  chmin(val, max(A[idx], B[idx]));
}

template <typename T>
void SqrtDecomposition<T>::total_query(int idx, T &val) {
  int lb = 0, ub = v[idx].size();
  while (ub - lb > 1) {
    int mid = (lb + ub) / 2;
    (A[v[idx][mid]] - B[v[idx][mid]] <= -sumX[idx] ? lb : ub) = mid;
  }
  chmin(val, min(ruiB[idx][lb], lb + 1 == v[idx].size() ? LINF : ruiA[idx][lb + 1] + sumX[idx]));
}

int main() {
  int n, q; cin >> n >> q;
  A.resize(n);
  B.resize(n);
  REP(i, n) cin >> A[i] >> B[i];
  SqrtDecomposition<ll> sd(n);
  sumX.assign(sd.b_n, 0);
  ruiA.resize(sd.b_n);
  ruiB.resize(sd.b_n);
  v.resize(sd.b_n);
  REP(i, sd.b_n) {
    int sz = sd.right[i] - sd.left[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), sd.left[i]);
  }
  REP(i, sd.b_n) init(i);
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l; --r;
    if (query == 1) {
      int x; cin >> x;
      sd.update(l, r + 1, x);
    } else if (query == 2) {
      cout << sd.query(l, r + 1, LINF) << '\n';
    }

  }
  return 0;
}
accuracy: 0.2
time_ms: 1320
memory_kb: 6456
final_rank: 16

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

vector<ll> A, B, sumX;
vector<vector<ll> > ruiA, ruiB;
vector<vector<int> > v;

void evaluate(int b, int l, int r) {
  FOR(i, l, r) A[i] += sumX[b];
  sumX[b] = 0;
}

void init(int idx) {
  sort(ALL(v[idx]), [&](int l, int r) { return A[l] - B[l] < A[r] - B[r]; });
  REP(i, ruiB[idx].size()) ruiB[idx][i] = min(i == 0 ? LINF : ruiB[idx][i - 1], B[v[idx][i]]);
  for (int i = ruiA[idx].size() - 1; i >= 0; --i) ruiA[idx][i] = min(i + 1 == ruiA[idx].size() ? LINF : ruiA[idx][i + 1], A[v[idx][i]]);
}

template <typename T>
struct SqrtDecomposition {
  int b, b_n;
  vector<int> left, right;
  vector<bool> need_to_be_eval;

  SqrtDecomposition(int n) : b(sqrt(n)) {
    b_n = (n + b - 1) / b;
    left.resize(b_n);
    right.resize(b_n);
    need_to_be_eval.assign(b_n, false);
    REP(i, b_n) {
      left[i] = b * i;
      right[i] = (i + 1 == b_n ? n : b * (i + 1));
    }
  }

  void partial_update(int idx, T val);

  void total_update(int idx, T val);

  void update(int l, int r, T val) {
    if (r <= l) return;
    int l_b = l / b, r_b = (r - 1) / b;
    if (l_b == r_b) {
      need_to_be_eval[l_b] = true;
      FOR(i, l, r) partial_update(i, val);
    } else {
      need_to_be_eval[l_b] = true;
      FOR(i, l, right[l_b]) partial_update(i, val);
      FOR(i, l_b + 1, r_b) total_update(i, val);
      need_to_be_eval[r_b] = true;
      FOR(i, left[r_b], r) partial_update(i, val);
    }
  }

  void partial_query(int idx, T &val);

  void total_query(int idx, T &val);

  T query(int l, int r, T UNITY) {
    int l_b = l / b, r_b = (r - 1) / b;
    T res = UNITY;
    if (l_b == r_b) {
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      evaluate(l_b, left[l_b], right[l_b]);
      FOR(i, l, r) partial_query(i, res);
    } else if (l < r) {
      if (need_to_be_eval[l_b]) {
        init(l_b);
        need_to_be_eval[l_b] = false;
      }
      evaluate(l_b, left[l_b], right[l_b]);
      FOR(i, l, right[l_b]) partial_query(i, res);
      FOR(i, l_b + 1, r_b) {
        if (need_to_be_eval[i]) {
          init(i);
          need_to_be_eval[i] = false;
        }
        total_query(i, res);
      }
      if (need_to_be_eval[r_b]) {
        init(r_b);
        need_to_be_eval[r_b] = false;
      }
      evaluate(r_b, left[r_b], right[r_b]);
      FOR(i, left[r_b], r) partial_query(i, res);
    }
    return res;
  }
};

template <typename T>
void SqrtDecomposition<T>::partial_update(int idx, T val) {
  A[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::total_update(int idx, T val) {
  sumX[idx] += val;
}

template <typename T>
void SqrtDecomposition<T>::partial_query(int idx, T &val) {
  chmin(val, max(A[idx], B[idx]));
}

template <typename T>
void SqrtDecomposition<T>::total_query(int idx, T &val) {
  int lb = left[idx], ub = right[idx];
  while (ub - lb > 1) {
    int mid = (lb + ub) / 2;
    (A[mid] - B[mid] <= -sumX[idx] ? lb : ub) = mid;
  }
  chmin(val, min(ruiB[idx][lb - left[idx]], lb + 1 < right[idx] ? LINF : ruiA[idx][lb - left[idx] + 1] + sumX[idx]));
}

int main() {
  int n, q; cin >> n >> q;
  A.resize(n);
  B.resize(n);
  REP(i, n) cin >> A[i] >> B[i];
  SqrtDecomposition<ll> sd(n);
  sumX.assign(sd.b_n, 0);
  ruiA.resize(sd.b_n);
  ruiB.resize(sd.b_n);
  v.resize(sd.b_n);
  REP(i, sd.b_n) {
    int sz = sd.right[i] - sd.left[i];
    ruiA[i].resize(sz);
    ruiB[i].resize(sz);
    v[i].resize(sz);
    iota(ALL(v[i]), sd.left[i]);
  }
  REP(i, sd.b_n) init(i);
  while (q--) {
    int query, l, r; cin >> query >> l >> r; --l; --r;
    if (query == 1) {
      int x; cin >> x;
      sd.update(l, r + 1, x);
    } else if (query == 2) {
      cout << sd.query(l, r + 1, LINF) << '\n';
    }
  }
  return 0;
}
accuracy: 0.2
time_ms: 1120
memory_kb: 6372
final_rank: 12