#include <bits/stdc++.h>
using namespace std;
int n, qu, A[100005];
struct BIT {
  struct node {
    long long cnt[10];
    int tobe[10];
    node() {
      memset(cnt, 0, sizeof(cnt));
      for (int i = 0; i < 10; i++) tobe[i] = i;
    }
  };
  vector<node> tree;
  BIT(int V) : tree(8 * V) {}
  void build(int x, int L, int R, int idx, int num, long long contri) {
    if (idx < L || R < idx) return;
    if (L == idx && idx == R) {
      tree[x].cnt[num] += contri;
      return;
    }
    int mid = (L + R) >> 1;
    build(x + x, L, mid, idx, num, contri);
    build(x + x + 1, mid + 1, R, idx, num, contri);
  }
  void maketree(int x, int L, int R) {
    if (L == R) return;
    int mid = (L + R) >> 1;
    maketree(x + x, L, mid);
    maketree(x + x + 1, mid + 1, R);
    tree[x] = merge(tree[x + x], tree[x + x + 1]);
  }
  node merge(node a, node b) {
    node ret;
    for (int i = 0; i < 10; i++) {
      ret.cnt[i] += a.cnt[i];
      ret.cnt[i] += b.cnt[i];
    }
    return ret;
  }
  void push(int x, int L, int R) {
    long long tmp[10] = {
        0,
    };
    long long tmp2[10] = {
        0,
    };
    for (int i = 0; i < 10; i++) {
      tmp[i] = tree[x].tobe[tree[x + x].tobe[i]];
      tmp2[i] = tree[x].tobe[tree[x + x + 1].tobe[i]];
    }
    for (int i = 0; i < 10; i++) {
      tree[x + x].tobe[i] = tmp[i];
      tree[x + x + 1].tobe[i] = tmp2[i];
    }
    memset(tmp, 0, sizeof(tmp));
    for (int i = 0; i < 10; i++) {
      tmp[tree[x].tobe[i]] += tree[x].cnt[i];
    }
    for (int i = 0; i < 10; i++) {
      tree[x].cnt[i] = tmp[i];
      tree[x].tobe[i] = i;
    }
  }
  void update(int x, int L, int R, int le, int ri, int from, int to) {
    push(x, L, R);
    if (ri < L || R < le) return;
    if (le <= L && R <= ri) {
      tree[x].tobe[from] = to;
      push(x, L, R);
      return;
    }
    int mid = (L + R) >> 1;
    push(x, L, R);
    update(x + x, L, mid, le, ri, from, to);
    update(x + x + 1, mid + 1, R, le, ri, from, to);
    tree[x] = merge(tree[x + x], tree[x + x + 1]);
  }
  long long query(int x, int L, int R, int le, int ri) {
    push(x, L, R);
    if (ri < L || R < le) return 0;
    if (le <= L && R <= ri) {
      push(x, L, R);
      long long ret = 0;
      for (int i = 0; i < 10; i++) ret += (long long)i * tree[x].cnt[i];
      return ret;
    }
    push(x, L, R);
    int mid = (L + R) >> 1;
    long long ret = query(x + x, L, mid, le, ri);
    ret += query(x + x + 1, mid + 1, R, le, ri);
    return ret;
  }
};
int ty[100005], l[100005], r[100005], x[100005], y[100005];
long long ans[100005];
int main() {
  scanf("%d %d", &n, &qu);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &A[i]);
  }
  for (int ite = 1; ite <= qu; ite++) {
    scanf("%d %d %d", &ty[ite], &l[ite], &r[ite]);
    if (ty[ite] == 1) {
      scanf("%d %d", &x[ite], &y[ite]);
    }
  }
  BIT bit(n);
  for (int i = 1; i <= n; i++) {
    long long contri = 1;
    while (A[i] != 0) {
      bit.build(1, 1, n, i, A[i] % 10, contri);
      A[i] /= 10;
      contri *= 10;
    }
  }
  bit.maketree(1, 1, n);
  for (int i = 1; i <= qu; i++) {
    if (ty[i] == 1) {
      bit.update(1, 1, n, l[i], r[i], x[i], y[i]);
    } else {
      long long key = bit.query(1, 1, n, l[i], r[i]);
      ans[i] += key;
    }
  }
  for (int i = 1; i <= qu; i++) {
    if (ty[i] == 2) cout << ans[i] << endl;
  }
}
