#include <bits/stdc++.h>
using namespace std;
const long long N = 2e5 + 5, inf = 1e18;
long long n;
string vals[N];
string A, B, pattern;
string add;
long long dp[15][2][2][15];
string get_smallest(string s) {
  if (s[0] == '?') s[0] = '1';
  for (char &ch : s)
    if (ch == '?') ch = '0';
  return s;
}
long long go(long long pos, bool bigA, bool smallB, long long id) {
  if (id == (long long)(pattern.size())) return 1;
  long long &ans = dp[pos][bigA][smallB][id];
  if (~ans) return ans;
  ans = 0;
  for (long long i = 0; i < 10; i++) {
    if (!bigA && i < A[pos] - '0') continue;
    if (!smallB && i > B[pos] - '0') continue;
    if (pattern[id] == '?' || (pattern[id] - '0' == i))
      ans |= go(pos + 1, bigA || (i > A[pos] - '0'),
                smallB || (i < B[pos] - '0'), id + 1);
  }
  return ans;
}
void trace(long long pos, bool bigA, bool smallB, long long id) {
  if (id == (long long)(pattern.size())) return;
  long long ans = go(pos, bigA, smallB, id);
  for (long long i = 0; i < 10; i++) {
    if (!bigA && i < A[pos] - '0') continue;
    if (!smallB && i > B[pos] - '0') continue;
    if (pattern[id] == '?' || (pattern[id] - '0' == i)) {
      long long get = go(pos + 1, bigA || (i > A[pos] - '0'),
                         smallB || (i < B[pos] - '0'), id + 1);
      if (ans == get) {
        add.push_back((char)(i + '0'));
        return trace(pos + 1, bigA || (i > A[pos] - '0'),
                     smallB || (i < B[pos] - '0'), id + 1);
      }
    }
  }
}
void fk() {
  cout << "NO\n";
  exit(0);
}
string find_best(string L, string R) {
  memset(dp, -1, sizeof(dp));
  if ((long long)(L.size()) != (long long)(R.size())) fk();
  if ((long long)(L.size()) != (long long)(pattern.size())) fk();
  A = L, B = R;
  reverse(A.begin(), A.end());
  while ((long long)(A.size()) < (long long)(B.size())) A.push_back('0');
  reverse(A.begin(), A.end());
  long long ans = 0;
  for (long long i = 0; i < 10; i++) {
    if (i < A[0] - '0') continue;
    if (i > B[0] - '0') continue;
    if (pattern[0] == '?' || (pattern[0] - '0' == i))
      ans |= go(1, i > A[0] - '0', i < B[0] - '0', 1);
  }
  if (!ans) {
    cout << "NO\n";
    exit(0);
  }
  add.clear();
  for (long long i = 0; i < 10; i++) {
    if (i < A[0] - '0') continue;
    if (i > B[0] - '0') continue;
    if (pattern[0] == '?' || (pattern[0] - '0' == i)) {
      long long get = go(1, i > A[0] - '0', i < B[0] - '0', 1);
      if (get == ans) {
        add.push_back((char)(i + '0'));
        trace(1, i > A[0] - '0', i < B[0] - '0', 1);
        break;
      }
    }
  }
  if ((long long)(add.size()) != (long long)(pattern.size())) fk();
  return add;
}
string get_best(string one, string two) {
  assert((long long)(one.size()) == (long long)(two.size()));
  long long len = (long long)(one.size());
  pattern = two;
  string big;
  for (long long i = 1; i <= len; i++) big.push_back('9');
  long long L = stoll(one) + 1;
  string ret = find_best(to_string(L), big);
  return ret;
}
bool chk(string one_, string two_) {
  if ((long long)(one_.size()) > (long long)(two_.size())) return false;
  if ((long long)(one_.size()) < (long long)(two_.size())) return true;
  return one_ < two_;
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (long long i = 1; i <= n; i++) {
    cin >> vals[i];
  }
  vals[1] = get_smallest(vals[1]);
  for (long long i = 2; i <= n; i++) {
    if ((long long)(vals[i - 1].size()) < (long long)(vals[i].size()))
      vals[i] = get_smallest(vals[i]);
    else if ((long long)(vals[i - 1].size()) > (long long)(vals[i].size())) {
      cout << "NO\n";
      return 0;
    } else {
      vals[i] = get_best(vals[i - 1], vals[i]);
    }
  }
  bool ok = true;
  for (long long i = 2; i <= n; i++) ok &= chk(vals[i - 1], vals[i]);
  if (!ok) {
    cout << "NO\n";
  } else {
    cout << "YES\n";
    for (long long i = 1; i <= n; i++) {
      cout << vals[i] << '\n';
    }
  }
}
