#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
using namespace std;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ',' << p.second << ')';
  return os;
}
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];
  }
  os << '}';
  return os;
}
ostream &operator<<(ostream &os, const set<int> &se) {
  os << '{';
  int now = 0;
  for (auto x : se) {
    if (now) {
      os << ',';
    }
    os << x;
    now++;
  }
  os << '}';
  return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &...args) {
  cerr << " " << x;
  debugg(args...);
}
using namespace std;
const int inf = (1 << 30) - 1;
const long long linf = 1LL << 61;
const int MAX = 510000;
int dy[8] = {0, 1, 0, -1, 1, -1, -1, 1};
int dx[8] = {-1, 0, 1, 0, 1, -1, 1, -1};
const double pi = acos(-1);
const double eps = 1e-8;
template <typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T>
inline void print(T &a) {
  int sz = a.size();
  for (auto itr = a.begin(); itr != a.end(); itr++) {
    cout << *itr;
    sz--;
    if (sz) cout << " ";
  }
  cout << "\n";
}
template <typename T1, typename T2>
inline void print2(T1 a, T2 b) {
  cout << a << " " << b << "\n";
}
template <typename T1, typename T2, typename T3>
inline void print3(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << "\n";
}
void mark() {
  cout << "#"
       << "\n";
}
long long pcount(long long x) { return __builtin_popcountll(x); }
const int mod = 1e9 + 7;
template <typename Monoid>
struct Segtree {
  using F = function<Monoid(Monoid, Monoid)>;
  int sz;
  vector<Monoid> seg;
  const F f;
  const Monoid M;
  Segtree(int n, const F f, const Monoid &M) : f(f), M(M) {
    sz = 1;
    while (sz < n) sz <<= 1;
    seg.assign(2 * sz, M);
  }
  void set(int k, const Monoid &x) { seg[k + sz] = x; }
  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
    }
  }
  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
    }
  }
  Monoid query(int a, int b) {
    Monoid L = M, R = M;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = f(L, seg[a++]);
      if (b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }
  Monoid operator[](const int &k) const { return seg[k + sz]; }
  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M0, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M0) : f(M0, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M0 = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }
  template <typename C>
  int find_first(int a, const C &check) {
    Monoid L = M;
    if (a <= 0) {
      if (check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }
  template <typename C>
  int find_last(int b, const C &check) {
    Monoid R = M;
    if (b >= sz) {
      if (check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};
struct T {
  long long lval, rval, llen, rlen, sum, len;
};
T f(T a, T b) {
  T res;
  if (a.lval == -1) return b;
  if (b.lval == -1) return a;
  res.len = a.len + b.len;
  res.lval = a.lval;
  res.rval = b.rval;
  res.sum = a.sum + b.sum;
  if (a.rval <= b.lval) {
    res.sum -= a.rlen * (a.rlen + 1) / 2;
    res.sum -= b.llen * (b.llen + 1) / 2;
    long long L = a.rlen + b.llen;
    res.sum += L * (L + 1) / 2;
  }
  if (a.len == a.llen && b.len == b.rlen && a.rval <= b.lval) {
    res.llen = res.rlen = res.len;
  } else {
    if (a.len == a.llen && a.rval <= b.lval)
      res.llen = a.llen + b.llen;
    else
      res.llen = a.llen;
    if (b.len == b.rlen && a.rval <= b.lval)
      res.rlen = a.rlen + b.rlen;
    else
      res.rlen = b.rlen;
  }
  return res;
}
void solve() {
  int n, q;
  cin >> n >> q;
  vector<long long> a(n);
  for (int i = 0; i < (n); i++) cin >> a[i];
  Segtree<T> seg(n, f, T{-1, -1, 0, 0, 0, 0});
  for (int i = 0; i < (n); i++) seg.set(i, T{a[i], a[i], 1, 1, 1, 1});
  seg.build();
  while (q--) {
    int t, x, y;
    cin >> t >> x >> y;
    x--;
    if (t == 1) {
      seg.update(x, T{y, y, 1, 1, 1, 1});
    } else {
      cout << seg.query(x, y).sum << "\n";
    }
  }
}
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int t = 1;
  while (t--) {
    solve();
  }
}
