#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))
#define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i))
#define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i))
#define ALL(x) std::begin(x), std::end(x)
#define dump(x) cerr << #x " = " << x << endl
using namespace std;
template <class T> using reversed_priority_queue = priority_queue<T, vector<T>, greater<T> >;
template <class T, class U> inline void chmax(T & a, U const & b) { a = max<T>(a, b); }
template <class T, class U> inline void chmin(T & a, U const & b) { a = min<T>(a, b); }
template <typename X, typename T> auto make_table(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto make_table(X x, Y y, Z z, Zs... zs) { auto cont = make_table(y, z, zs...); return vector<decltype(cont)>(x, cont); }
template <typename T> istream & operator >> (istream & in, vector<T> & xs) { REP (i, xs.size()) { in >> xs[i]; } return in; }
template <typename T> ostream & operator << (ostream & out, const vector<T> & xs) { REP (i, xs.size()) { if (i) { out << ' '; } out << xs[i]; } return out; }

const pair<string, vector<int64_t> > FAILURE = {};

pair<string, vector<int64_t> > solve(int n, int m, const vector<int64_t> & d, const vector<pair<int, int> > & edges) {
    // make the adjacency list
    vector<vector<pair<int, int> > > g(n);
    REP (i, m) {
        int x, y; tie(x, y) = edges[i];
        g[x].emplace_back(y, i);
        g[y].emplace_back(x, i);
    }
    REP (x, n) {
        sort(ALL(g[x]), [&](pair<int, int> edge1, pair<int, int> edge2) {
            return make_pair(d[edge1.first], edge1.first) < make_pair(d[edge2.first], edge2.first);
        });
    }

    //
    string color(n, '\0');
    vector<int64_t> cost(m, 1000000000);

    // find the initial edge
    vector<int> order(n);
    iota(ALL(order), 0);
    sort(ALL(order), [&](int x, int y) { return make_pair(d[x], x) < make_pair(d[y], y); });
    for (int x : order) {
        if (color[x]) continue;
        int y, i; tie(y, i) = g[x][0];
        if (d[y] < d[x]) {
            color[x] = color[y];
            cost[i] = d[x] - d[y];
        } else if (d[x] == d[y]) {
            if (color[y]) {
                color[x] = color[y] ^ 'B' ^ 'W';
            } else {
                color[x] = 'B';
                color[y] = 'W';
            }
            cost[i] = d[x];
        } else {
            return FAILURE;
        }
    }

    // check
    if (n <= 100) {
        vector<vector<int64_t> > dist(n, vector<int64_t>(n, INT64_MAX));
        REP (x, n) {
            dist[x][x] = 0;
            for (auto edge : g[x]) {
                int y, i; tie(y, i) = edge;
                assert (1 <= cost[i] and cost[i] <= 1000000000);
                dist[x][y] = cost[i];
            }
        }
        REP(z, n) REP(x, n) REP(y, n) {
            if (dist[x][z] != INT64_MAX and dist[z][y] != INT64_MAX) {
                chmin(dist[x][y], dist[x][z] + dist[z][y]);
            }
        }
        REP (x, n) {
            assert (color[x] == 'B' or color[x] == 'W');
            int64_t e = INT64_MAX;
            REP (y, n) if (color[y] != color[x]) {
                chmin(e, dist[x][y]);
            }
            assert (d[x] == e);
        }
    }

    return make_pair(color, cost);
}

int main() {
    int n, m; cin >> n >> m;
    vector<int64_t> d(n); cin >> d;
    vector<pair<int, int> > edges(m);
    REP (i, m) {
        int u, v; cin >> u >> v;
        -- u;
        -- v;
        edges[i] = make_pair(u, v);
    }
    string color; vector<int64_t> cost;
    tie(color, cost) = solve(n, m, d, edges);
    if (color.empty()) {
        cout << -1 << endl;
    } else {
        cout << color << endl;
        REP (i, m) {
            cout << cost[i] << endl;
        }
    }
    return 0;
}


Measured memory_bytes: 14336