#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000000 + 7;
int addm(int& a, int b) { return (a += b) < mod ? a : a -= mod; }
template <class T, class U>
bool smin(T& a, U b) {
  return a > b ? (a = b, 1) : 0;
}
template <class T, class U>
bool smax(T& a, U b) {
  return a < b ? (a = b, 1) : 0;
}
long long p10[10];
long long tct[10][1];
int nu[10];
template <class T, class U>
struct SegmentTree {
  T I, t[4];
  int N, h;
  vector<T> A;
  SegmentTree(const vector<T>& data, T I = T())
      : I(I),
        N(data.size()),
        h(sizeof(int) * 8 - __builtin_clz(N)),
        A(2 * N, I) {
    copy(data.begin(), data.end(), A.begin() + N);
    for (int i = N - 1; i; i--) op(i);
  }
  void op(int i) { A[i].op(A[2 * i], A[2 * i + 1]); }
  void prop(int i) {
    A[2 * i].us(A[i].U);
    A[2 * i + 1].us(A[i].U);
    A[i].NU();
  }
  void push(int i) {
    for (int j = h; j; j--) prop(i >> j);
  }
  void update(int l, int r, U v) {
    push(l += N);
    push((r += N) - 1);
    bool cl = 0, cr = 0;
    for (; l < r; l /= 2, r /= 2) {
      if (cl) op(l - 1);
      if (cr) op(r);
      if (l & 1) A[l++].us(v), cl = 1;
      if (r & 1) A[--r].us(v), cr = 1;
    }
    if (l == 1 && cr)
      op(1);
    else
      for (l--; r > 0; l /= 2, r /= 2) {
        if (cl && l) op(l);
        if (cr && (!cl || (l != r && r != 1))) op(r);
      }
  }
  long long query(int l, int r) {
    push(l += N);
    push((r += N) - 1);
    long long res = 0;
    for (; l < r; l /= 2, r /= 2) {
      if (l & 1) res += A[l++].a;
      if (r & 1) res += A[--r].a;
    }
    return res;
  }
};
struct Up {
  int a[10];
  Up() { iota(a, a + 10, 0); }
};
struct ST {
  long long a = 0;
  long long ct[10][1] = {{}};
  Up U;
  ST() {
    a = 0;
    fill(ct[0], ct[10], 0);
  }
  void op(ST& b, ST& c) {
    a = b.a + c.a;
    for (int i = 0; i < 10; i++)
      for (int j = 0; j < 1; j++) {
        ct[i][j] = b.ct[i][j] + c.ct[i][j];
      }
  }
  void us(Up& u) {
    fill(tct[0], tct[10], 0);
    a = 0;
    for (int i = 0; i < 10; i++)
      for (int j = 0; j < 1; j++) {
        tct[u.a[i]][j] += ct[i][j];
        a += u.a[i] * p10[j] * ct[i][j];
      }
    copy(tct[0], tct[10], ct[0]);
    for (int i = 0; i < 10; i++) nu[i] = u.a[U.a[i]];
    copy(nu, nu + 10, U.a);
  }
  void NU() { iota(U.a, U.a + 10, 0); }
};
int n, q, a[100000];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  p10[0] = 1;
  for (int i = 1; i < 10; i++) p10[i] = 10 * p10[i - 1];
  cin >> n >> q;
  vector<ST> data(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    data[i].a = a[i];
    for (int j = 0; a[i]; j++) {
      data[i].ct[a[i] % 10][0] += p10[j];
      a[i] /= 10;
    }
  }
  SegmentTree<ST, Up> st(data);
  for (int z = 0; z < q; z++) {
    int t, l, r;
    cin >> t >> l >> r;
    l--;
    if (t == 1) {
      Up u;
      int first, second;
      cin >> first >> second;
      u.a[first] = second;
      st.update(l, r, u);
    } else
      cout << st.query(l, r) << '\n';
  }
}
