#include <bits/stdc++.h>
const int N = 200010;
const long long INF = 1ll << 60;
const int inf = 0x3f3f3f3f;
struct Node {
  Node() {
    sum_ = INF;
    for (int i = 0; i < 9; ++i) mi_[i] = INF;
  }
  long long sum_;
  long long mi_[9];
};
class SegmentTree {
 public:
  SegmentTree() {}
  void Init(int n, int v[]) {
    n_ = n;
    Build(1, n, 1, v);
  }
  void ChangeSingle(int l, int r, int rt, int id, int x) {
    if (l == r) {
      Update(rt, x);
      return;
    }
    int m = (l + r) >> 1;
    if (id <= m) {
      ChangeSingle(l, m, rt << 1, id, x);
    } else {
      ChangeSingle(m + 1, r, rt << 1 | 1, id, x);
    }
    Up(rt);
  }
  Node ValInterval(int l, int r, int rt, int L, int R) {
    if (L > R) {
      return Node();
    }
    if (L <= l && r <= R) {
      return node[rt];
    }
    int m = (l + r) >> 1;
    int ans = 0ll;
    if (m < L)
      return ValInterval(m + 1, r, rt << 1 | 1, L, R);
    else if (m >= R)
      return ValInterval(l, m, rt << 1, L, R);
    else {
      Node node1 = ValInterval(m + 1, r, rt << 1 | 1, L, R);
      Node node2 = ValInterval(l, m, rt << 1, L, R);
      return Merge(node1, node2);
    }
  }

 private:
  void Build(int l, int r, int rt, int v[]) {
    if (l == r) {
      node[rt].sum_ = INF;
      Update(rt, v[l]);
      return;
    }
    int m = (l + r) >> 1;
    Build(l, m, rt << 1, v);
    Build(m + 1, r, rt << 1 | 1, v);
    Up(rt);
  }
  void Update(int rt, int x) {
    long long tmp = x;
    for (int i = 0; i < 9; ++i) {
      node[rt].mi_[i] = (x % 10 == 0 ? INF : tmp);
      x /= 10;
    }
  }
  void Up(int rt) { node[rt] = Merge(node[rt << 1], node[rt << 1 | 1]); }
  Node Merge(Node& node1, Node& node2) {
    Node node_new;
    node_new.sum_ = std::min(node1.sum_, node2.sum_);
    for (int i = 0; i < 9; ++i) {
      node_new.mi_[i] = std::min(node1.mi_[i], node2.mi_[i]);
      if (node1.mi_[i] != INF && node2.mi_[i] != INF) {
        node_new.sum_ = std::min(node_new.sum_, node1.mi_[i] + node2.mi_[i]);
      }
    }
    return node_new;
  }
  int n_;
  Node node[N << 2 | 1];
} seg;
int t;
int n, m;
int a[N];
int b[N];
int c[N], d[N];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
  }
  seg.Init(n, a);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d%d", &b[i], &c[i], &d[i]);
    if (b[i] == 1)
      seg.ChangeSingle(1, n, 1, c[i], d[i]);
    else {
      long long tmp = seg.ValInterval(1, n, 1, c[i], d[i]).sum_;
      printf("%lld\n", tmp == INF ? -1 : tmp);
    }
  }
  return 0;
}
