#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
#pragma GCC target("avx,tune=native")
using namespace std;
int n, m;
int outerValues[200013];
int helper[4];
struct SegtreeMax {
  pair<int, int> *values;
  int length;
  SegtreeMax() {}
  SegtreeMax(int len) {
    length = len;
    values = new pair<int, int>[4 * len];
    for (int i = 0; i < 4 * len; i++) {
      values[i] = make_pair(1000000000, 1000000000);
    }
  }
  void update(int index, int value, int i = 1, int left = 0,
              int right = 200013 - 1) {
    if (right < index || index < left || right < left) return;
    if (left == right) {
      values[i] = make_pair(value, 1000000000);
      return;
    }
    int mid = (left + right) / 2;
    update(index, value, 2 * i, left, mid);
    update(index, value, 2 * i + 1, mid + 1, right);
    int v1 = values[2 * i].first;
    int v2 = values[2 * i].second;
    int v3 = values[2 * i + 1].first;
    int v4 = values[2 * i + 1].second;
    helper[0] = v1;
    helper[1] = v2;
    helper[2] = v3;
    helper[3] = v4;
    int best = 1000000000;
    int bestIndex = -1;
    for (int i = 0; i < 4; i++) {
      if (helper[i] < best) {
        best = helper[i];
        bestIndex = i;
      }
    }
    int temp2 = 1000000000;
    for (int i = 0; i < 4; i++) {
      if (bestIndex == i) continue;
      temp2 = min(temp2, helper[i]);
    }
    values[i] = make_pair(best, temp2);
  }
  pair<int, int> query(int start, int end, int i, int left, int right) {
    if (right < start || end < left || right < left)
      return make_pair(1000000000, 1000000000);
    if (start <= left && right <= end) {
      return values[i];
    }
    int mid = (left + right) / 2;
    pair<int, int> p1 = query(start, end, 2 * i, left, mid);
    pair<int, int> p2 = query(start, end, 2 * i + 1, mid + 1, right);
    int v1 = p1.first;
    int v2 = p1.second;
    int v3 = p2.first;
    int v4 = p2.second;
    helper[0] = v1;
    helper[1] = v2;
    helper[2] = v3;
    helper[3] = v4;
    int best = 1000000000;
    int bestIndex = -1;
    for (int i = 0; i < 4; i++) {
      if (helper[i] < best) {
        best = helper[i];
        bestIndex = i;
      }
    }
    int temp2 = 1000000000;
    for (int i = 0; i < 4; i++) {
      if (bestIndex == i) continue;
      temp2 = min(temp2, helper[i]);
    }
    return make_pair(best, temp2);
  }
};
SegtreeMax digits[10];
int main() {
  if (fopen("FILENAME.in", "r")) {
    freopen("FILENAME.in", "r", stdin);
    freopen("FILENAME.out", "w", stdout);
  }
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < 9; i++) {
    digits[i] = SegtreeMax(n);
  }
  for (int i = 0; i < n; i++) {
    int v;
    cin >> v;
    int original = v;
    int power = 100000000;
    for (int j = 0; j < 9; j++) {
      if (v / power > 0) {
        digits[j].update(i, original, 1, 0, n - 1);
        v %= power;
      }
      power /= 10;
    }
    outerValues[i] = original;
  }
  while (m--) {
    int option;
    cin >> option;
    if (option == 1) {
      int i, x;
      cin >> i >> x;
      i--;
      int v = outerValues[i];
      int power = 100000000;
      for (int j = 0; j < 9; j++) {
        if (v / power > 0) {
          digits[j].update(i, 1000000000, 1, 0, n - 1);
          v %= power;
        }
        power /= 10;
      }
      v = x;
      power = 100000000;
      for (int j = 0; j < 9; j++) {
        if (v / power > 0) {
          digits[j].update(i, x, 1, 0, n - 1);
          v %= power;
        }
        power /= 10;
      }
      outerValues[i] = x;
    } else {
      int l, r;
      cin >> l >> r;
      l--;
      r--;
      int answer = 2 * 1000000000 + 1;
      for (int j = 0; j < 9; j++) {
        pair<int, int> p = digits[j].query(l, r, 1, 0, n - 1);
        if (p.first == 1000000000 || p.second == 1000000000) continue;
        answer = min(answer, p.first + p.second);
      }
      cout << (answer >= (2 * 1000000000 + 1) ? -1 : answer) << '\n';
    }
  }
}
