#include <bits/stdc++.h>
using namespace std;
struct node {
  int remap[10];
  long long contrib[10] = {0};
  int from = 0, to = 0;
  int has_new_val = false;
  int lleaf = 0, rleaf = 0;
  void init() {
    for (int i = 0; i <= 9; i++) remap[i] = i;
  }
  void split(node& l, node& r) {
    if (has_new_val) {
      int mleaf = (lleaf + rleaf) / 2;
      l.update_single_node(remap, lleaf, mleaf);
      r.update_single_node(remap, mleaf, rleaf);
      has_new_val = false;
      for (int i = 0; i <= 9; i++) remap[i] = i;
    }
  }
  void merge(node& l, node& r) {
    for (int j = 0; j <= 9; j++) contrib[j] = l.contrib[j] + r.contrib[j];
  }
  void update_single_node(int new_remap[], int lleaf, int rleaf) {
    long long new_contrib[10] = {0};
    for (int i = 0; i <= 9; i++) {
      new_contrib[new_remap[i]] += contrib[i];
      remap[i] = new_remap[remap[i]];
    }
    for (int i = 0; i <= 9; i++) {
      contrib[i] = new_contrib[i];
    }
    this->has_new_val = true;
    this->lleaf = lleaf;
    this->rleaf = rleaf;
  }
} tree[2 * int(1 << 17)];
struct node identity;
node range_query(int root, int lleaf, int rleaf, int u, int v) {
  if (u <= lleaf && rleaf <= v) return tree[root];
  int mid = (lleaf + rleaf) / 2, lchild = root * 2, rchild = lchild + 1;
  tree[root].split(tree[lchild], tree[rchild]);
  node lans = identity, rans = identity;
  for (int i = 0; i <= 9; i++)
    if (lans.remap[i] != i || rans.remap[i] != i) cout << "problem" << endl;
  if (u < mid) lans = range_query(lchild, lleaf, mid, u, v);
  if (v > mid) rans = range_query(rchild, mid, rleaf, u, v);
  tree[root].merge(tree[lchild], tree[rchild]);
  node ans;
  ans.merge(lans, rans);
  return ans;
}
void range_update(int root, int lleaf, int rleaf, int u, int v, int remap[]) {
  if (u <= lleaf && rleaf <= v)
    return tree[root].update_single_node(remap, lleaf, rleaf);
  int mid = (lleaf + rleaf) / 2, lchild = root * 2, rchild = lchild + 1;
  tree[root].split(tree[lchild], tree[rchild]);
  if (u < mid) range_update(lchild, lleaf, mid, u, v, remap);
  if (v > mid) range_update(rchild, mid, rleaf, u, v, remap);
  tree[root].merge(tree[lchild], tree[rchild]);
}
void build_tree() {
  for (int i = int(1 << 17) - 1; i > 0; i--)
    tree[i].merge(tree[i << 1], tree[i << 1 | 1]);
}
node range_query(int u, int v) {
  return range_query(1, int(1 << 17), 2 * int(1 << 17), int(1 << 17) + u,
                     int(1 << 17) + v);
}
void range_update(int u, int v, int remap[]) {
  return range_update(1, int(1 << 17), 2 * int(1 << 17), int(1 << 17) + u,
                      int(1 << 17) + v, remap);
}
int main() {
  int n, q;
  scanf("%d%d", &(n), &(q));
  for (int i = 1; i < 2 * int(1 << 17); i++) tree[i].init();
  identity.init();
  for (int i = 0; i < n; i++) {
    int a;
    scanf("%d", &(a));
    long long p = 1;
    while (a > 0) {
      tree[int(1 << 17) + i].contrib[a % 10] += p;
      a /= 10;
      p *= 10;
    }
  }
  build_tree();
  for (int i = 1; i <= q; i++) {
    int m, l, r, x = 0, y = 0;
    scanf("%d%d%d", &(m), &(l), &(r));
    if (m == 1) {
      scanf("%d%d", &(x), &(y));
      if (x != y) {
        int remap[10];
        for (int i = 0; i <= 9; i++) remap[i] = i;
        remap[x] = y;
        range_update(l - 1, r, remap);
      }
    } else {
      node res = range_query(l - 1, r);
      long long ans = 0;
      for (int j = 1; j <= 9; j++) {
        ans += (long long)res.contrib[j] * j;
      }
      cout << ans << endl;
    }
  }
  return 0;
}
