#include <bits/stdc++.h>
using namespace std;
vector<long long> items;
long long n_cnt = 1;
long long n;
struct node {
  map<long long, pair<priority_queue<long long>, priority_queue<long long>>>
      some;
  vector<tuple<long long, long long, long long>> ans;
  void change(long long past, long long future, long long pos) {
    some[future].first.push(-pos);
    some[future].second.push(pos);
  }
  void push(long long k, long long v) {
    some[k].first.push(-v);
    some[k].second.push(v);
  }
  pair<long long, long long> getTop(long long k) {
    auto &p = some[k];
    while (!p.first.empty() && items[-p.first.top()] != k) p.first.pop();
    while (!p.second.empty() && items[p.second.top()] != k) p.second.pop();
    if (p.first.empty()) {
      return {-1, -1};
    }
    return {-some[k].first.top(), some[k].second.top()};
  }
};
vector<node> seg_tr;
void build_tr(vector<long long> v) {
  n_cnt = 1;
  items = v;
  while (n_cnt < v.size()) n_cnt *= 2;
  n = n_cnt * 2;
  seg_tr.resize(n);
  for (long long i = 0; i < v.size(); ++i) {
    seg_tr[i + n_cnt].push(items[i], i);
  }
  long long l = n_cnt;
  long long r = n;
  while (l != 1) {
    for (long long i = l; i < r; ++i) {
      long long to = i / 2;
      if (i % 2 == 0)
        seg_tr[to].some = seg_tr[i].some;
      else
        for (auto &p : seg_tr[i].some) {
          auto t = p.second.first;
          while (!t.empty()) {
            seg_tr[to].some[p.first].first.push(t.top());
            t.pop();
          }
          t = p.second.second;
          while (!t.empty()) {
            seg_tr[to].some[p.first].second.push(t.top());
            t.pop();
          }
        }
    }
    l /= 2;
    r /= 2;
  }
}
void change(long long pos, long long to) {
  long long past = items[pos];
  long long future = to;
  items[pos] = future;
  int tpos = pos;
  pos += n_cnt;
  while (pos != 0) {
    seg_tr[pos].change(past, future, tpos);
    pos /= 2;
  }
}
long long query(long long l, long long r) {
  l += n_cnt;
  r += n_cnt;
  map<long long, pair<long long, long long>> ans;
  vector<long long> to_del;
  while (l < r) {
    if (l % 2 == 1) {
      for (auto &p : seg_tr[l].some) {
        long long ta, tb;
        tie(ta, tb) = seg_tr[l].getTop(p.first);
        if (ta == -1) {
          to_del.push_back(p.first);
          continue;
        }
        if (ans.count(p.first)) {
          long long a, b;
          tie(a, b) = ans[p.first];
          a = min(a, ta);
          b = max(b, tb);
          ans[p.first] = {a, b};
        } else {
          ans[p.first] = {ta, tb};
        }
      }
      l++;
      for (auto &x : to_del) {
        seg_tr[l].some.erase(x);
      }
      to_del.clear();
    }
    if (r % 2 == 1) {
      for (auto &p : seg_tr[r - 1].some) {
        long long ta, tb;
        tie(ta, tb) = seg_tr[r - 1].getTop(p.first);
        if (ta == -1) {
          to_del.push_back(p.first);
          continue;
        }
        if (ans.count(p.first)) {
          long long a, b;
          tie(a, b) = ans[p.first];
          a = min(a, ta);
          b = max(b, tb);
          ans[p.first] = {a, b};
        } else {
          ans[p.first] = {ta, tb};
        }
      }
      r--;
      for (auto &x : to_del) {
        seg_tr[r].some.erase(x);
      }
      to_del.clear();
    }
    if (l >= r) break;
    l /= 2;
    r /= 2;
  }
  long long ans_ll = 0;
  for (auto &p : ans) {
    ans_ll += p.second.second - p.second.first;
  }
  return ans_ll;
}
int main() {
  long long n, m;
  cin >> n >> m;
  vector<long long> v(n);
  for (auto &x : v) cin >> x;
  build_tr(v);
  for (int i = 0; i < m; ++i) {
    int t;
    cin >> t;
    if (t == 1) {
      int p, x;
      cin >> p >> x;
      p--;
      change(p, x);
    } else {
      int l, r;
      cin >> l >> r;
      l--;
      cout << query(l, r) << endl;
    }
  }
  return 0;
}
