// セグメント木
//   モノイド (S, fs), 単位元 es で構築する.
//   半開区間 [l, r) で操作する.
//   木の実装は 1-indexed.
//   計算量:
//     構築       O(n)
//     一点更新   O(log n)
//     区間クエリ O(log n)
#include<functional>
#include<vector>
template<typename S> class SegmentTree {
 public:
  using FS = std::function<S(S, S)>;
  SegmentTree(int n, FS fs, S es) : n(size(n)), fs(fs), es(es), dat(size(n) << 1, es) {}
  void update(int k, S x) {
    dat[k += n] = x;
    while(k = parent(k)) dat[k] = fs(dat[lchild(k)], dat[rchild(k)]);
  }
  S query(int a, int b) const {
    auto vl = es, vr = es;
    for(auto l = a + n, r = b + n; l < r; l = parent(l), r = parent(r)) {
      if(l&1) vl = fs(vl, dat[l++]);
      if(r&1) vr = fs(dat[--r], vr);
    }
    return fs(vl, vr);
  }
 private:
  constexpr int size(int n) const {return n & (n - 1) ? size(n + (n & -n)) : n;}
  inline int parent(int k) const {return (k >> 1);}
  inline int lchild(int k) const {return (k << 1);}
  inline int rchild(int k) const {return (k << 1) | 1;}
  int n;
  std::vector<S> dat;
  FS fs;
  S es;
};

// 遅延伝播セグメント木
//   モノイド (S, fs), (E, fe) と作用 fa: S × E → S で構築する.
//   半開区間 [l, r) で操作する.
//   木の実装は 1-indexed.
//   計算量:
//     構築       O(n)
//     区間更新   O(log n)
//     区間クエリ O(log n)
#include<functional>
#include<vector>
template<typename S, typename E = S> class SegmentTreeLP {
 public:
  using FS = std::function<S(S, S)>;
  using FA = std::function<S(S, E)>;
  using FE = std::function<E(E, E)>;
  SegmentTreeLP(int n, FS fs, FA fa, FE fe, S es, E ee) : n(size(n)), fs(fs), fa(fa), fe(fe), es(es), ee(ee), dat(size(n) << 1, es), laz(size(n) << 1, ee), height(lsb(size(n))) {}
  void update(int a, int b, E x) {
    if(a >= b) return;
    thrust(a += n);
    thrust(b += n - 1);
    for(auto l = a, r = b + 1; l < r; l = parent(l), r = parent(r)) {
      if(l&1) laz[l] = fe(laz[l], x), ++l;
      if(r&1) --r, laz[r] = fe(laz[r], x);
    }
    recalc(a);
    recalc(b);
  }
  void set(int a, S x) {
    thrust(a += n);
    dat[a] = x;
    laz[a] = ee;
    recalc(a);
  }
  S query(int a, int b) {
    thrust(a += n);
    thrust(b += n - 1);
    auto vl = es, vr = es;
    for(auto l = a, r = b + 1; l < r; l = parent(l), r = parent(r)) {
      if(l&1) vl = fs(vl, reflect(l++));
      if(r&1) vr = fs(reflect(--r), vr);
    }
    return fs(vl, vr);
  }
 private:
  constexpr int size(int n) const {return n & (n - 1) ? size(n + (n & -n)) : n;}
  inline int lsb(int n) {return n & 1 ? 0 : 1 + lsb(n >> 1);}
  inline int parent(int k) const {return (k >> 1);}
  inline int lchild(int k) const {return (k << 1);}
  inline int rchild(int k) const {return (k << 1) | 1;}
  inline S reflect(int k) const {return fa(dat[k], laz[k]);}
  inline void propagate(int k) {
    if(laz[k] == ee) return;
    laz[lchild(k)] = fe(laz[lchild(k)], laz[k]);
    laz[rchild(k)] = fe(laz[rchild(k)], laz[k]);
    dat[k] = reflect(k);
    laz[k] = ee;
  }
  inline void thrust(int k) {for(auto i = height; i; --i) propagate(k >> i);}
  inline void recalc(int k) {while(k >>= 1) dat[k] = fs(reflect(lchild(k)), reflect(rchild(k)));}
  int n, height;
  FS fs;
  FA fa;
  FE fe;
  S es;
  E ee;
  std::vector<S> dat;
  std::vector<E> laz;
};

// 遅延伝播動的セグメント木
//   モノイド (S, fs), (E, fe) と作用 fa: S × E → S で構築する.
//   半開区間 [l, r) で操作する.
//   計算量:
//     構築       O(1)
//     区間更新   O(log n)
//     区間クエリ O(log n)
//     二分探索   O(log^2 n)
#include<functional>
#include<iostream>
#include<memory>
template<typename S, typename E = S> class SegmentTreeDLP {
 public:
  using FS = std::function<S(S, S)>;
  using FA = std::function<S(S, E)>;
  using FE = std::function<E(E, E)>;
  SegmentTreeDLP(int n, FS fs, FA fa, FE fe, S es, E ee) : n(n), fs(fs), fa(fa), fe(fe), es(es), ee(ee), root(std::make_unique<Node>(es,ee)) {}
  void update(int a, int b, E x) {update(a, b, x, root, 0, n);}
  S query(int a, int b) {return query(a, b, root, 0, n);}
  int lower_bound(int a, int b, const std::function<bool(S)>& check) {return lower_bound(a, b, check, root, 0, n);}
  void debug() {traverse(root, 0, 0, n);}
  void traverse(const auto& node, int d, int l, int r) {
    propagate(node);
    auto m = (l + r) / 2;
    if(l+1!=r) traverse(node->rchild, d + 1, l, m);
    for(auto i = 0; i < d; ++i) std::cout << "    ";
    std::cout << node->val << ", " << node->laz << std::endl;
    if(l+1!=r) traverse(node->lchild, d + 1, m, r);
  }
 private:
  struct Node {
    S val;
    E laz;
    std::unique_ptr<Node> lchild, rchild;
    Node(S val, E laz) : val(val), laz(laz) {}
  };
  inline S reflect(const auto& n) {return fa(n->val, n->laz);}
  inline void propagate(const auto& n) {
    if(not n->lchild) n->lchild = std::make_unique<Node>(es, ee);
    if(not n->rchild) n->rchild = std::make_unique<Node>(es, ee);
    if(n->laz == ee) return;
    n->lchild->laz = fe(n->lchild->laz, n->laz);
    n->rchild->laz = fe(n->rchild->laz, n->laz);
    n->val = reflect(n);
    n->laz = ee;
  }
  void update(int a, int b, E x, const auto &n, int l, int r) {
    propagate(n);
    if(b <= l || r <= a) return;
    if(a <= l && r <= b) {
      n->laz = fe(n->laz, x);
      propagate(n);
      return;
    }
    auto m = (l + r) / 2;
    update(a, b, x, n->lchild, l, m);
    update(a, b, x, n->rchild, m, r);
    n->val = fs(reflect(n->lchild), reflect(n->rchild));
  }
  S query(int a, int b, const auto &n, int l, int r) {
    propagate(n);
    if(b <= l || r <= a) return es;
    if(a <= l && r <= b) return reflect(n);
    auto m = (l + r) / 2;
    auto vl = query(a, b, n->lchild, l, m);
    auto vr = query(a, b, n->rchild, m, r);
    return fs(vl, vr);
  }
  int lower_bound(int a, int b, const auto& check, const auto& node, int l, int r) {
    propagate(node);
    if(b <= l || r <= a) return n;
    if(!check(reflect(node))) return n;
    if(l + 1 == r) return l;
    auto m = (l + r) / 2;
    auto i = lower_bound(a, b, check, node->lchild, l, m);
    if(i != n) return i;
    return lower_bound(a, b, check, node->rchild, m, r);
  }
  int n;
  std::unique_ptr<Node> root;
  FS fs;
  FA fa;
  FE fe;
  S es;
  E ee;
};

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

struct S {
  int v, size;
  bool operator==(const S& o) const {return v != o.v;}
  friend ostream& operator<<(ostream& os, const S& s) {return os << s.v;}
};
using E = int;
auto fs = [&](S l, S r) {return S{l.v + r.v, l.size + r.size};};
auto fa = [&](S l, E r) {return S{l.v + r * l.size, l.size};};
auto fe = [&](E l, E r) {return l + r;};
auto es = S{0, 1};
auto ee = 0;

int main() {
  int n, q;
  cin >> n >> q;

  SegmentTreeDLP<S,E> RSQ(n+1, fs, fa, fe, es, ee);
  for(auto i=0; i<q; ++i) {
    int com, x, y;
    cin >> com >> x >> y;
    if(com == 0) {
      RSQ.update(x,x+1,y);
    } else {
      cout << RSQ.query(x,y+1) << endl;
    }
  }
}



Measured memory_bytes: 20824