#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <tuple>
using namespace std;
using u32 = unsigned int;
using u64 = unsigned long long;
using i64 = long long;
using qrt = tuple<u32, u32, u32, u64*>;
struct Line
{
u32 k, b;
Line(u32 _k = 0, u32 _b = 0): k(_k), b(_b) { }
bool operator<(const Line& t) const { return k < t.k; }
u64 val(u64 x) { return k * x + b; }
};
struct Convex
{
vector<Line> cv;
u32 pos;
Convex() { }
Convex(Line x): cv(1u, x), pos() { }
Convex(const vector<Line> &ls, const vector<Line> &rs): pos()
{
decltype(cv) tmp(ls.size() + rs.size());
cv.reserve(tmp.size());
merge(ls.begin(), ls.end(), rs.begin(), rs.end(), tmp.begin());
int s = -1;
for (auto i: tmp) {
while (s > 0 && ((i64)i.b - (i64)cv[s].b) * (cv[s].k - cv[s - 1].k)
>= ((i64)cv[s].b - (i64)cv[s - 1].b) * (i.k - cv[s].k)) {
cv.pop_back(), --s;
}
cv.emplace_back(i), ++s;
}
}
u64 ask(u64 x)
{
u64 ansp = cv[pos].val(x), ansn;
while(pos < cv.size() - 1 && (ansn = cv[pos + 1].val(x)) > ansp) {
pos++;
ansp = ansn;
}
return ansp;
}
};
class ConvexSegmentTree
{
public:
ConvexSegmentTree() { }
ConvexSegmentTree(const vector<pair<u32, Line>>& a): m(1), pos(a.size())
{
while (m < a.size()) m += m;
t.resize(m * 2);
for (u32 i = 0; i < a.size(); i++) pos[i] = a[i].first;
sort(pos.begin(), pos.end());
for (u32 i = 0; i < a.size(); i++) {
t[lower_bound(pos.begin(), pos.end(), a[i].first)
- pos.begin() + m] = Convex(a[i].second);
}
for (u32 i = m - 1; i > 0; i--) {
t[i] = Convex(t[i * 2].cv, t[i * 2 + 1].cv);
}
}
u64 ask(u32 l, u32 r, u32 x)
{
l = lower_bound(pos.begin(), pos.end(), l) - pos.begin();
r = lower_bound(pos.begin(), pos.end(), r) - pos.begin();
u64 res = 0;
for (l += m, r += m; l < r; l /= 2, r /= 2) {
if (l & 1) res = max(res, t[l++].ask(x));
if (r & 1) res = max(res, t[--r].ask(x));
}
return res;
}
private:
u32 m;
vector<u32> pos;
vector<Convex> t;
};
class ChronoSegmentTree
{
public:
ChronoSegmentTree(u32 _n): n(_n), m(1)
{
while (m < n) m += m;
t.resize(m * 2);
q.resize(m * 2);
}
void push_line(u32 l, u32 r, pair<u32, Line> op)
{
for (l += m, r += m; l < r; l /= 2, r /= 2) {
if (l & 1) t[l++].emplace_back(op);
if (r & 1) t[--r].emplace_back(op);
}
}
void push_query(u32 x, qrt qr) { q[x + m].emplace_back(qr); }
void solve()
{
for (u32 i = 0; i < n; i++) if (q[i + m].size()) {
auto [x, l, r, tg] = q[i + m][0];
ConvexSegmentTree sgt(t[i + m]);
*tg = sgt.ask(l, r, x);
}
for (u32 i = m - 1; i > 0; i--) {
q[i].resize(q[i * 2].size() + q[i * 2 + 1].size());
merge(q[i * 2].begin(), q[i * 2].end(),
q[i * 2 + 1].begin(), q[i * 2 + 1].end(), q[i].begin(),
[](const qrt& a, const qrt& b){ return get<0>(a) < get<0>(b); });
ConvexSegmentTree sgt(t[i]);
for (auto [x, l, r, tg]: q[i]) *tg = max(*tg, sgt.ask(l, r, x));
}
}
private:
u32 n, m;
vector<vector<pair<u32, Line>>> t;
vector<vector<qrt>> q;
};
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
u32 n, q;
cin >> n >> q;
vector<Line> l(n);
vector<u32> st(n);
for (auto &[a, b]: l) cin >> a >> b;
vector<u64> ans(q + 1);
ChronoSegmentTree csgt(q + 1);
for (u32 i = 1, o, a, b, c; i <= q; i++) {
cin >> o >> a >> b >> c;
if (o == 1) {
--a;
csgt.push_line(st[a], i, {a, l[a]});
st[a] = i, l[a] = Line(b, c);
}
else {
csgt.push_query(i, qrt(a, b - 1, c, &ans[i]));
}
}
for (u32 i = 0; i < n; i++) csgt.push_line(st[i], q + 1, {i, l[i]});
csgt.solve();
for (u32 i = 1; i <= q; i++) if (ans[i]) cout << ans[i] << '\n';
return 0;
}