// verification-helper: PROBLEM https://judge.yosupo.jp/problem/point_set_range_composite
#include "src/datastructure/segment_tree.hpp"
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
int const MOD = 998244353;
int main() {
int n, q;
cin >> n >> q;
vector<pair<long long, long long>> ab(n);
for (auto &[a, b] : ab) cin >> a >> b;
auto f = [](pair<long long, long long> a, pair<long long, long long> b) {
return pair(b.first * a.first % MOD,
(b.first * a.second % MOD + b.second) % MOD);
};
SegmentTree seg(f, pair<long long, long long>{1LL, 0LL});
seg.init(n);
seg.build(ab);
while (q--) {
int com;
cin >> com;
if (com) {
int l, r, x;
cin >> l >> r >> x;
auto [a, b] = seg.find(l, r);
cout << (a * x % MOD + b) % MOD << endl;
} else {
int p, c, d;
cin >> p >> c >> d;
seg.update(p, {c, d});
}
}
return 0;
}
#line 1 "test/datastructure/segment_tree/yosupo_point_set_range_composite.test.cpp"
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/point_set_range_composite
#line 1 "src/datastructure/segment_tree.hpp"
#include <vector>
template<class T, class F>
class SegmentTree { // 0-indexed
private:
int n_{};
std::vector<T> tree;
F f; // function<T(T, T)>
T ti;
public:
SegmentTree(F f, T ti) : f(f), ti(ti) {}
void init(int n) {
n_ = 1;
while (n_ < n) n_ *= 2;
tree.assign(2 * n_, ti);
}
void build(std::vector<T> const &v) {
int const N = v.size();
init(N);
for (int i = 0; i < N; ++i) tree[n_ + i] = v[i];
for (int i = n_ - 1; i > 0; --i) tree[i] = f(tree[2 * i], tree[2 * i + 1]);
}
void update(int i, T const &x) {
i += n_;
tree[i] = x;
while (i >>= 1) tree[i] = f(tree[2 * i], tree[2 * i + 1]);
}
T find(int l, int r) { // [l, r)
l += n_, r += n_;
T ll = ti, rr = ti;
while (l < r) {
if (l & 1) ll = f(ll, tree[l++]);
if (r & 1) rr = f(tree[--r], rr);
l >>= 1, r >>= 1;
}
return f(ll, rr);
}
T at(int i) { return tree[i + n_]; }
};
#line 4 "test/datastructure/segment_tree/yosupo_point_set_range_composite.test.cpp"
#include <iostream>
#include <utility>
#line 8 "test/datastructure/segment_tree/yosupo_point_set_range_composite.test.cpp"
using namespace std;
int const MOD = 998244353;
int main() {
int n, q;
cin >> n >> q;
vector<pair<long long, long long>> ab(n);
for (auto &[a, b] : ab) cin >> a >> b;
auto f = [](pair<long long, long long> a, pair<long long, long long> b) {
return pair(b.first * a.first % MOD,
(b.first * a.second % MOD + b.second) % MOD);
};
SegmentTree seg(f, pair<long long, long long>{1LL, 0LL});
seg.init(n);
seg.build(ab);
while (q--) {
int com;
cin >> com;
if (com) {
int l, r, x;
cin >> l >> r >> x;
auto [a, b] = seg.find(l, r);
cout << (a * x % MOD + b) % MOD << endl;
} else {
int p, c, d;
cin >> p >> c >> d;
seg.update(p, {c, d});
}
}
return 0;
}