#include <bits/stdc++.h>
using namespace std;
int A = 10;
const int INF = 1000 * 1000 * 1000 + 1000;
const long long BAD = 1LL << 60;
struct Datum {
 public:
  Datum() : data(A, make_pair(INF, INF)) {}
  Datum(int x) : data(A, make_pair(INF, INF)) { add(x); }
  void add(int x) {
    int n = x;
    int idx = 0;
    while (n > 0) {
      int d = n % 10;
      if (d != 0) {
        update(idx, x);
      }
      n /= 10;
      ++idx;
    }
  }
  Datum operator+(const Datum& other) const {
    Datum res = *this;
    for (int i = 0; i < A; ++i) {
      int x = other.data[i].first;
      int y = other.data[i].second;
      res.update(i, x);
      res.update(i, y);
    }
    return res;
  }
  Datum& operator+=(const Datum& other) {
    *this = *this + other;
    return *this;
  }
  void update(int idx, int x) {
    auto& P = data[idx];
    if (P.first > x) {
      swap(P.first, x);
    }
    if (P.second > x) {
      swap(P.second, x);
    }
  }
  long long get() {
    long long res = BAD;
    for (auto& P : data) {
      if (P.first < INF && P.second < INF) {
        res = min(res, P.first + 0LL + P.second);
      }
    }
    return res;
  }
  vector<pair<int, int>> data;
};
class SegmentTree {
 public:
  SegmentTree(int _n = 1) { init(_n); }
  void init(int _n) {
    n = _n;
    N = n << 1;
    h = 0;
    while (1 << h < N) {
      ++h;
    }
    data.clear();
    data.resize(N);
  }
  void build(vector<int>& A) {
    int sz = A.size();
    init(sz);
    for (int i = 0; i < n; ++i) {
      data[i + n].add(A[i]);
    }
    for (int i = n - 1; i > 0; --i) {
      data[i] = data[i << 1] + data[i << 1 | 1];
    }
  }
  void update(int x, int v) {
    x += n;
    data[x] = Datum(v);
    for (int p = x >> 1; p > 0; p >>= 1) {
      data[p] = data[p << 1] + data[p << 1 | 1];
    }
  }
  long long query(int l, int r) {
    l += n;
    r += n;
    long long res = BAD;
    Datum D;
    while (l <= r) {
      if (l & 0x1) {
        D += data[l++];
      }
      if ((r & 0x1) == 0) {
        D += data[r--];
      }
      l >>= 1;
      r >>= 1;
    }
    res = D.get();
    return res >= BAD ? -1 : res;
  }

 private:
  int n;
  int N;
  int h;
  vector<Datum> data;
};
class Solution {
 public:
  void init(vector<int>& A) { st.build(A); }
  void update(int x, int v) { st.update(x, v); }
  long long query(int l, int r) {
    if (l > r) {
      return -1;
    }
    if (l == r) {
      return -1;
    }
    return st.query(l, r);
  }

 private:
  SegmentTree st;
};
int main(int argc, char** argv) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  Solution sol;
  int n, m;
  cin >> n >> m;
  vector<int> A(n);
  for (int i = 0; i < n; ++i) {
    cin >> A[i];
  }
  sol.init(A);
  for (int i = 0; i < m; ++i) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, v;
      cin >> x >> v;
      --x;
      sol.update(x, v);
    } else {
      int l, r;
      cin >> l >> r;
      --l, --r;
      cout << sol.query(l, r) << "\n";
    }
  }
  return 0;
}
