/*
ID: espr1t
TASK: 
KEYWORDS: 
*/

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <map>

using namespace std;
FILE* in = stdin; FILE* out = stdout;

const int MAX = 100001;
const int EDG = 200002;


struct Node {
    int id;
    int dist;
    int color;
    bool connected;
    
    Node() {
        color = 1;
        connected = false;
    }
    
    bool operator < (const Node& r) const {
        return dist != r.dist ? dist < r.dist : id < r.id;
    }
};

int n, m;
Node a[MAX];
int nidx[MAX];
int edges[EDG][2];
vector <int> v[MAX];
map < pair <int, int>, int > ans;

bool solve() {
    for (int node = 0; node < n; node++) {
//        fprintf(stderr, "At node %d (dist = %d)\n", a[node].id + 1, a[node].dist);
        for (int i = 0; i < (int)v[node].size(); i++) {
            if (v[node][i] < node) {
                if (a[v[node][i]].dist < a[node].dist) {
                    if (!a[v[node][i]].connected)
                        return false;
                    if (!a[node].connected) {
                        a[node].connected = true;
                        a[node].color = a[v[node][i]].color;
                        ans[{v[node][i], node}] = a[node].dist - a[v[node][i]].dist;
    //                    fprintf(stderr, "  >> adding edge (%d, %d) with price %d\n",
    //                         a[v[node][i]].id + 1, a[node].id + 1, a[node].dist - a[v[node][i]].dist);
                    }
                } else if (a[v[node][i]].dist == a[node].dist) {
                    if (a[node].connected && !a[v[node][i]].connected) {
                        a[v[node][i]].connected = true;
                        a[v[node][i]].color = !a[node].color;
                        ans[{v[node][i], node}] = a[node].dist;
                    } else if (!a[node].connected && a[v[node][i]].connected) {
                        a[node].connected = true;
                        a[node].color = !a[v[node][i]].color;
                        ans[{v[node][i], node}] = a[node].dist;
                    } else if (!a[node].connected && !a[v[node][i]].connected) {
                        a[node].connected = a[v[node][i]].connected = true;
                        a[node].color = !a[v[node][i]].color;
                        ans[{v[node][i], node}] = a[node].dist;
    //                    fprintf(stderr, "  >> adding edge (%d, %d) with price %d\n",
    //                         a[v[node][i]].id + 1, a[node].id + 1, a[node].dist);
                    }
                }
            }
        }
//        fprintf(stderr, "  >> color of node %d: %d\n", a[node].id + 1, a[node].color);
    }
    for (int node = 0; node < n; node++)
        if (!a[node].connected) return false;
    return true;
}

int main(void) {
	// in = fopen("E.in", "rt");
	
	fscanf(in, "%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
	    a[i].id = i;
	    fscanf(in, "%d", &a[i].dist);
    }
    sort(a, a + n);
    for (int i = 0; i < n; i++)
        nidx[a[i].id] = i;
    
    for (int i = 0; i < m; i++) {
        fscanf(in, "%d %d", &edges[i][0], &edges[i][1]);
        edges[i][0] = nidx[edges[i][0] - 1];
        edges[i][1] = nidx[edges[i][1] - 1];
        if (edges[i][0] > edges[i][1]) {
            swap(edges[i][0], edges[i][1]);
        }
        v[edges[i][0]].push_back(edges[i][1]);
        v[edges[i][1]].push_back(edges[i][0]);
    }
	
	if (solve()) {
	    string colors(n, '?');
    	for (int i = 0; i < n; i++)
    	   colors[a[i].id] = a[i].color ? 'B' : 'W';
    	fprintf(out, "%s\n", colors.c_str());
    	for (int i = 0; i < m; i++) {
    	    auto it = ans.find({edges[i][0], edges[i][1]});
    	    if (it != ans.end()) {
    	        fprintf(out, "%d\n", it->second);
            } else {
                fprintf(out, "%d\n", 1000000000);
            }
        }
    } else {
        fprintf(out, "-1\n");
    }
	
	return 0;
}

Measured memory_bytes: 18176