#include <bits/stdc++.h>
using namespace std;
class SegmentTree {
  using value_t = array<pair<int, int>, 9>;
  size_t size;
  size_t base;
  vector<value_t> flatTree;

 public:
  SegmentTree(const vector<int>& a) {
    size = a.size();
    for (base = 1; base < size; base *= 2) {
    }
    flatTree.resize(base * 2);
    for (size_t i = 0; i < size; ++i) {
      flatTree[base + i] = int_to_valt(a[i]);
    }
    for (size_t i = 0; i < base; ++i) {
      update_node_value(base - i - 1);
    }
  }
  int query(int from, int to) {
    value_t q;
    query_internal(1, from, to, 0, base, q);
    int msum = -1;
    for (int i = 0; i < 9; ++i) {
      if (q[i].first != 0 && q[i].second != 0) {
        int s = q[i].first + q[i].second;
        if (msum == -1 || s < msum) {
          msum = s;
        }
      }
    }
    return msum;
  }
  void set_at(int at, int val) { set_at_internal(1, at, 0, base, val); }

 private:
  void upsort(pair<int, int>& a, int v) {
    if (v == 0) return;
    if (a.first == 0) {
      a.first = v;
    } else if (a.second == 0) {
      a.second = v;
    } else if (a.first > v) {
      a.first = v;
    }
    if (a.first < a.second) swap(a.first, a.second);
  }
  value_t int_to_valt(int x) {
    value_t r;
    for (int i = 0, q = x; i < 9; ++i) {
      int d = q % 10;
      q /= 10;
      if (d != 0) {
        r[i].first = x;
      }
    }
    return r;
  }
  void combine_function(value_t& a, const value_t& b) {
    for (int i = 0; i < 9; ++i) {
      upsort(a[i], b[i].first);
      upsort(a[i], b[i].second);
    }
  }
  void update_node_value(size_t idx) {
    flatTree[idx] = flatTree[idx * 2];
    combine_function(flatTree[idx], flatTree[idx * 2 + 1]);
  }
  void query_internal(size_t idx, int ql, int qr, int sl, int sr,
                      value_t& res) {
    if (ql <= sl && sr <= qr) {
      combine_function(res, flatTree[idx]);
      return;
    }
    if (sr <= ql || qr <= sl) {
      return;
    }
    int sm = (sl + sr) / 2;
    query_internal(idx * 2, ql, qr, sl, sm, res);
    query_internal(idx * 2 + 1, ql, qr, sm, sr, res);
  }
  void set_at_internal(size_t idx, int q, int sl, int sr, int val) {
    if (sl + 1 == sr) {
      flatTree[idx] = int_to_valt(val);
      return;
    }
    int sm = (sl + sr) / 2;
    if (q < sm) {
      set_at_internal(idx * 2, q, sl, sm, val);
    } else {
      set_at_internal(idx * 2 + 1, q, sm, sr, val);
    }
    update_node_value(idx);
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> a(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }
  SegmentTree tree(a);
  for (int i = 0; i < m; ++i) {
    int t, l, r;
    cin >> t >> l >> r;
    --l;
    if (t == 1) {
      tree.set_at(l, r);
    } else {
      cout << tree.query(l, r) << endl;
    }
  }
}
