/*input

*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <iomanip>
#include <climits>
#define mod 1000000007

// templates
#define all(v) v.begin(),v.end()
#define F first
#define S second
#define sz(x) (int)x.size()
#define po(x,y)   fixed<<setprecision(y)<<x
#define ss(s) scanf(" %[^\n]%*c", s)
#define ps(s) printf("%s\n",s)
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double lld;

void sc(int&n) {int number; scanf("%d", &number); n = number;}
void sc(ll&n) {ll number; scanf("%lld", &number); n = number;}
void _print(ll t) {printf("%lld", t);}
void _print(int t) {printf("%d", t);}
void _print(string t) {cout << t;}
void _print(char t) {printf("%c\n", t);}
void _print(lld t) {cout << t;}
void _print(double t) {cout << t;}
void _print(ull t) {cout << t;}

template <class T, class V> void _print(pair <T, V> p);
template <class T> void _print(vector <T> v);
template <class T> void _print(set <T> v);
template <class T, class V> void _print(map <T, V> v);
template <class T> void _print(multiset <T> v);
template <class T, class V> void _print(pair <T, V> p) {cout << "{"; _print(p.F); cout << ","; _print(p.S); cout << "}";}
template <class T> void _print(vector <T> v) {cout << "vec->[ "; for (T i : v) {_print(i); cout << " ";} cout << "]";}
template <class T> void _print(set <T> v) {cout << "set->[ "; for (T i : v) {_print(i); cout << " ";} cout << "]";}
template <class T> void _print(multiset <T> v) {cout << "multiset->[ "; for (T i : v) {_print(i); cout << " ";} cout << "]";}
template <class T, class V> void _print(map <T, V> v) {cout << "map->[ "; for (auto i : v) {_print(i); cout << " ";} cout << "]";}

const ll inf = (ll)1e17 + 10;
const int N = (int)1e5 + 10;
vector<array<ll, 3>>adj[N];

void bfs(int n) {

	vector<ll>dist(n + 1, 0);
	for (int i = 0; i <= n; ++i)
	{
		dist[i] = inf;
	}
	set<array<ll, 2>>pq;
	dist[0] = 0;
	pq.insert({0, 0});
	while (!pq.empty()) {

		auto [t, node] = *pq.begin();
		pq.erase(pq.begin());
		for (auto c : adj[node]) {
			ll cost = 0;
			ll sq = 0;
			cost = t + c[1] + (c[2] / (t + 1));
			sq = sqrt(c[2]);
			if (sq * sq != c[2])sq++;
			sq--;
			if (t < sq) {
				cost = min(cost, sq + c[1] + (c[2] / (sq + 1)));
			}
			if (dist[c[0]] > cost) {
				pq.erase({dist[c[0]], c[0]});
				dist[c[0]] = cost;
				pq.insert({dist[c[0]], c[0]});

			}

		}
	}
	if (dist[n - 1] == inf)dist[n - 1] = -1;
	_print(dist[n - 1]);
}
void solve()
{
	int n, m;
	sc(n), sc(m);
	for (int i = 0; i < m; ++i)
	{
		ll u, v, c, d;
		sc(u), sc(v), sc(c), sc(d);
		u--, v--;
		adj[u].push_back({v, c, d});
		adj[v].push_back({u, c, d});
	}
	bfs(n);
}

int main()
{
//#ifndef ONLINE_JUDGE
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
//#endif
	int t = 1;
	// sc(t);
	while (t--) {
		solve();
	}
	return 0;

}
#include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(v) v.begin(), v.end()
template<class T>bool chmax(T& a, const T& b) { if (a<b) { a=b; return 1;} return 0;}
template<class T>bool chmin(T& a, const T& b) { if (b<a) { a=b; return 1;} return 0;}

int main() {
    string S1, S2, S3;
    cin >> S1 >> S2 >> S3;

    set<char> se;
    vector<int> ch;
    string T = S1 + S2 + S3;
    rep(i, T.size()) {
        if (!se.count(T[i])) ch.push_back(T[i] - 'a');
        se.insert(T[i]);
    }
    if (ch.size() > 10) {
        cout << "UNSOLVABLE" << endl;
        return 0;
    }

    vector<int> alp(26, -1);
    vector<int> num = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    vector<int> R1, R2, R3;
    rep(i, S1.size()) R1.push_back(S1[i] - 'a');
    rep(i, S2.size()) R2.push_back(S2[i] - 'a');
    rep(i, S3.size()) R3.push_back(S3[i] - 'a');

    int l1 = S1.size(), l2 = S2.size(), l3 = S3.size();
    do {
        rep(i, ch.size()) alp[ch[i]] = num[i];
        ll N1 = 0, N2 = 0, N3 = 0;
        if (alp[R1[0]] == 0) continue;
        if (alp[R2[0]] == 0) continue;
        if (alp[R3[0]] == 0) continue;
        rep(i, l1) N1 += alp[R1[l1-i-1]] * pow(10, i);
        rep(i, l2) N2 += alp[R2[l2-i-1]] * pow(10, i);
        rep(i, l3) N3 += alp[R3[l3-i-1]] * pow(10, i);
        if (N1 == 0 || N2 == 0 || N3 == 0) continue;
        if (N1 + N2 == N3) {
            cout << N1 << endl << N2 << endl << N3 << endl;
            return 0;
        }
    } while (next_permutation(all(num)));

    cout << "UNSOLVABLE" << endl;
}