#include <bits/stdc++.h>
using namespace std;
const int B = 27397, MOD = 1e9 + 7;
const int B1 = 33941, MOD1 = 1e9 + 9;
int n, q;
struct Node {
  int nxt[11];
  long long sum[11];
  Node() {
    for (int i = 0; i < 10; ++i) nxt[i] = i;
    memset(sum, 0, sizeof sum);
  }
};
class Tournament {
 private:
  int offset, lo, hi, x, y;
  int nxt_left[11], nxt_right[11];
  long long new_sum[11];
  vector<Node> tree;
  void merge(int node) {
    for (int i = 0; i < 10; ++i)
      tree[node].sum[i] = tree[2 * node].sum[i] + tree[2 * node + 1].sum[i];
  }
  void propagate(int node) {
    if (node < offset) {
      for (int i = 0; i < 10; ++i) {
        nxt_left[i] = tree[node].nxt[tree[2 * node].nxt[i]];
        nxt_right[i] = tree[node].nxt[tree[2 * node + 1].nxt[i]];
      }
      for (int i = 0; i < 10; ++i) {
        tree[2 * node].nxt[i] = nxt_left[i];
        tree[2 * node + 1].nxt[i] = nxt_right[i];
      }
    }
    memset(new_sum, 0, sizeof new_sum);
    for (int i = 0; i < 10; ++i)
      new_sum[tree[node].nxt[i]] += tree[node].sum[i];
    for (int i = 0; i < 10; ++i) {
      tree[node].sum[i] = new_sum[i];
      tree[node].nxt[i] = i;
    }
  }
  void update(int node, int from, int to) {
    propagate(node);
    if (to <= lo || hi <= from) return;
    if (from >= lo && to <= hi) {
      tree[node].nxt[x] = y;
      propagate(node);
      return;
    }
    update(2 * node, from, (from + to) / 2);
    update(2 * node + 1, (from + to) / 2, to);
    merge(node);
  }
  long long query(int node, int from, int to) {
    propagate(node);
    if (to <= lo || hi <= from) return 0;
    if (from >= lo && to <= hi) {
      long long ret = 0;
      for (int i = 0; i < 10; ++i) ret += (long long)i * tree[node].sum[i];
      return ret;
    }
    long long left = query(2 * node, from, (from + to) / 2);
    long long right = query(2 * node + 1, (from + to) / 2, to);
    return left + right;
  }

 public:
  Tournament(int n) {
    for (offset = 1; offset <= n; offset <<= 1)
      ;
    tree.resize(2 * offset);
  }
  void insert(int i, int val) {
    i += offset;
    int coef = 1;
    while (val > 0) {
      tree[i].sum[val % 10] += (long long)coef;
      coef *= 10;
      val /= 10;
    }
    for (i >>= 1; i > 0; i >>= 1) merge(i);
  }
  void update(int l, int r, int _x, int _y) {
    lo = l;
    hi = r;
    x = _x;
    y = _y;
    update(1, 0, offset);
  }
  long long query(int l, int r) {
    lo = l;
    hi = r;
    return query(1, 0, offset);
  }
};
int main(void) {
  scanf("%d%d", &n, &q);
  Tournament T(n);
  for (int i = 0; i < n; ++i) {
    int x;
    scanf("%d", &x);
    T.insert(i, x);
  }
  for (int i = 0; i < q; ++i) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int l, r, x, y;
      scanf("%d%d%d%d", &l, &r, &x, &y);
      --l;
      if (x == y) continue;
      T.update(l, r, x, y);
      continue;
    }
    int l, r;
    scanf("%d%d", &l, &r);
    --l;
    printf("%lld\n", T.query(l, r));
  }
  return 0;
}
