#include<bits/stdc++.h>

using namespace std;
using ll = long long;
using vs = vector<string>;
using vi = vector<int>;
using vl = vector<ll>;
using vb = vector<bool>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vpi = vector<pair<int, int>>;
using vpl = vector<pair<ll, ll>>;
using ld = double;

#define	sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define ins insert
#define nl "\n"

const ll MOD = 998244353;


ll add(ll x, ll y) {
	x += y;
	if (x >= MOD) return x - MOD;
	return x;
}
ll sub(ll x, ll y) {
	x -= y;
	if (x < 0) return x + MOD;
	return x;
}
ll mult(ll x, ll y) {
	return (x * y) % MOD;
}

template<typename T> T signum(T a) { 
    return (a > 0) - (a < 0); 
}

template<typename T> T cmp(T a, T b) { 
    return signum(a-b); 
}

template<typename T> bool mins(T& lhs , T& rhs) {
    if (rhs < lhs) {
        lhs = rhs;
        return true;
    }

    return false;
}

template<typename T> bool maxs(T& lhs , T& rhs) {
    if (rhs > lhs) {
        lhs = rhs;
        return true;
    }

    return false;
}


const int MAX = INT_MAX;

void gks(int tc) {
    printf("Case #%d: ", tc);
};


int main() {
    string s1, s2, s3;
    cin>>s1;
    cin>>s2;
    cin>>s3;
    string p = "0123456789";

    set<char> a;
    for (auto x : s1) a.insert(x);
    for (auto x : s2) a.insert(x);
    for (auto x : s3) a.insert(x);
    if (a.size() >= 11)        {
        cout<<"UNSOLVABLE";
        return 0;
    }


    bool f = false;
    do {

        map<char, int> my_map;
        //if (p[0] == '0') continue;
        int i = 0;
        for (auto x : a) {
            my_map[x] = p[i++];
        }

        string i1;
        for (auto x : s1) {
            i1.append(1, my_map[x]);
        }

        if (i1 == "0") continue;
        string i2;
        for (auto x : s2) {
            i2.append(1, my_map[x]);
        }

        if (i2 == "0") continue;
        string i3;
        for (auto x : s3) {
            i3.append(1, my_map[x]);
        }

        if (i3 == "0") continue;

        ll j1 = stoll(i1);
        ll j2 = stoll(i2);
        ll j3 = stoll(i3);


        /*
        if (p == "0267495183") {
            cout<<j1<<nl<<j2<<nl<<j3<<nl;
        }
        */

        if (j1 + j2 == j3 && i1[0] != '0' && i2[0] != '0' && i3[0] != '0') {
            f = true;
            cout<<j1<<nl<<j2<<nl<<j3<<nl;
            break;
        }
                   
    }while (next_permutation(p.begin(), p.end()));
    
    if (!f) {
        cout<<"UNSOLVABLE"<<nl;
    }

   return 0;
}

// doot diddly donger cuckerino Hahahahahah


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
//#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vi = vector<int>;

#define all(x)  (x).begin(), (x).end()
const ld PI = acos(-1);

template <typename T> inline T mini(T& x, T y) { return x = min(x, y); }
template <typename T> inline T maxi(T& x, T y) { return x = max(x, y); }
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
template <typename T, typename U>
std::ostream& operator<<(std::ostream& stream, const pair<T, U>& p) {
  return stream << p.first << " " << p.second;
}
template <typename T>
std::ostream& operator<<(std::ostream& out, const vector<T>& vec) {
  for (const T& x: vec) out << x << ' ';
  return out;
}
template <typename T>
std::istream& operator>>(std::istream& in, vector<T>& vec) {
  for (auto& x: vec) in >> x;
  return in;
}



class MEX {
  struct MEXNode {
    MEXNode *children[2];
    bool is_full = false;
    int cnt = 0;
  
  public:
    MEXNode() {
      children[0] = nullptr;
      children[1] = nullptr;
    }
  };
private:
  
  inline MEXNode *nonnull(MEXNode *& n) {
    if (!n) n = new MEXNode();
    return n;
  }
  
  void insert(int val, int level, MEXNode *n) {
    if (level == -1) {
      n->cnt++;
      n->is_full = true;
      return;
    }
    
    int cur_bit = (val & (1 << level)) >> level;
    insert(val, level - 1, nonnull(n->children[cur_bit]));
    
    n->is_full = nonnull(n->children[0])->is_full && nonnull(n->children[1])->is_full;
    n->cnt = nonnull(n->children[0])->cnt + nonnull(n->children[1])->cnt;
  }
  
  // Remove an integer from the set
  void remove(int val, int level, MEXNode *n) {
    if (level == -1) {
      n->cnt--;
      n->is_full = n->cnt > 0;
      return;
    }
    
    int cur_bit = (val & (1 << level)) >> level;
    remove(val, level - 1, nonnull(n->children[cur_bit]));
    
    n->is_full = nonnull(n->children[0])->is_full && nonnull(n->children[1])->is_full;
    n->cnt = nonnull(n->children[0])->cnt + nonnull(n->children[1])->cnt;
  }
  
  // Find the minimum element >=x that isn't present in the set
  int get(int val, int level, MEXNode *n) {
    if (n->is_full) {
      return -1;
    } else if (n->cnt == 0) {
      return val;
    }
    
    int cur_bit = (val & (1 << level)) >> level;
    int ans = get(val, level - 1, nonnull(n->children[cur_bit]));
    if (cur_bit == 0 && ans == -1) {
      ans = get((val >> level << level) | (1 << level), level - 1, nonnull(n->children[1]));
    }
    
    return ans;
  }
  
  MEXNode root_node;
public:
  
  void insert(int x) {
    insert(x, 31, &root_node);
  }
  void remove(int x) {
    remove(x, 31, &root_node);
  }
  int get(int x) {
    return get(x, 31, &root_node);
  }
};

class CNeqMin {
public:
  
  void solve(std::istream& cin, std::ostream& cout) {
    int n;
    cin >> n;
    MEX mex;
    for (int i = 0; i < n; ++i) {
      int x;
      cin >> x;
      mex.insert(x);
      cout << mex.get(0) << '\n';
    }
  }
};

int32_t main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
	CNeqMin solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}
