#include <bits/stdc++.h>
using namespace std;
template <class T>
void debug(T a, T b) {
  ;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
namespace std {
template <class S, class T>
ostream& operator<<(ostream& out, const pair<S, T>& a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
}  // namespace std
long long int readL() {
  long long int res;
  scanf("%I64d", &res);
  return res;
}
void printL(long long int res) { printf("%I64d", res); }
struct segtree {
  struct uf {
    static const int MAXN = 11;
    int par[MAXN];
    void init() {
      for (int i = 0; i < (MAXN); ++i) par[i] = i;
    }
    void unite(int a, int b) {
      for (int i = 0; i < (MAXN); ++i)
        if (par[i] == b) par[i] = a;
    }
  };
  int n;
  uf root[400005];
  long long int sum[400005][10];
  void init(int n_, int* ar) {
    n = 1;
    while (n < n_) n <<= 1;
    for (int i = 0; i < (n * 2); ++i) {
      root[i].init();
    }
    for (int i = 0; i < (n_); ++i) {
      int ex = 1;
      int tmp = ar[i];
      while (tmp) {
        sum[i + n - 1][tmp % 10] += ex;
        tmp /= 10;
        ex *= 10;
      }
    }
    for (int i = n - 2; i >= 0; --i) {
      for (int j = 0; j < (10); ++j)
        sum[i][j] = sum[i * 2 + 1][j] + sum[i * 2 + 2][j];
    }
  }
  void push(int id) {
    long long int tmp1[10] = {0}, tmp2[10] = {0};
    for (int i = 0; i < (10); ++i) {
      int x = root[id].par[i];
      tmp1[x] += sum[id * 2 + 1][i];
      tmp2[x] += sum[id * 2 + 2][i];
    }
    auto fix = [&](int& x) { x = root[id].par[x]; };
    for (int i = 0; i < (10); ++i) {
      fix(root[id * 2 + 2].par[i]);
      fix(root[id * 2 + 1].par[i]);
    }
    for (int i = 0; i < (10); ++i) {
      sum[id * 2 + 1][i] = tmp1[i];
      sum[id * 2 + 2][i] = tmp2[i];
    }
    root[id].init();
  }
  long long int query(int a, int b, int i, int l, int r) {
    if (a <= l && r <= b) {
      long long int res = 0;
      for (int j = 0; j < (10); ++j) res += sum[i][j] * j;
      return res;
    }
    if (b <= l || r <= a) return 0;
    int md = (l + r) >> 1;
    push(i);
    return query(a, b, i * 2 + 1, l, md) + query(a, b, i * 2 + 2, md, r);
  }
  void merge(int a, int b, int i, int l, int r, int x, int y) {
    if (a <= l && r <= b) {
      if (x != y) {
        root[i].unite(x, y);
        sum[i][x] += sum[i][y];
        sum[i][y] = 0;
      }
      return;
    }
    if (b <= l || r <= a) return;
    int md = (l + r) >> 1;
    push(i);
    merge(a, b, i * 2 + 1, l, md, x, y);
    merge(a, b, i * 2 + 2, md, r, x, y);
    for (int j = 0; j < (10); ++j)
      sum[i][j] = sum[i * 2 + 1][j] + sum[i * 2 + 2][j];
  }
};
segtree seg;
int n, q;
int ar[100005];
int main() {
  cin >> n >> q;
  for (int i = 0; i < (n); ++i) scanf("%d", &ar[i]);
  seg.init(n, ar);
  for (int i = 0; i < (q); ++i) {
    int t, l, r;
    scanf("%d%d%d", &t, &l, &r);
    --l;
    if (t == 1) {
      int x, y;
      scanf("%d%d", &x, &y);
      seg.merge(l, r, 0, 0, seg.n, y, x);
    } else {
      long long int res = seg.query(l, r, 0, 0, seg.n);
      printL(res);
      puts("");
    }
  }
  return 0;
}
