#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <istream>
#include <iterator>
#include <sstream>
#include <list>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <iomanip>
using namespace std;

#define BR "\n"
#define REP(i, n) for(int (i)=0;(i)<(n);++(i))
#define ALL(cont) begin(cont),end(cont)
#define AS_MOD(a, b) ((((a) % (b) ) + (b)) % (b))
#define FEACH(it, cont) for(auto (it) = begin(cont); it!=end(cont);++it)
#define FEACHR(it, cont) for(auto (it) = rbegin(cont); it!=rend(cont);++it)
#define pb push_back
#define pob pop_back
#define fi first
#define se second
#define getll() ([](){ll s;scanf("%lld", &s);return s;})()
#define getld() ([](){ld s;scanf("%Lf", &s);return s;})()
#define prl(P) printf("%lld", P)
#define prd(P) printf("%.10Lf", P)
#define pr(P) printf(P)
#define MAX(V, T) V=max(V,T)

#define DumpArray(cont, from, to) for(int __i=from;__i<to;++__i) {cout<<"(" <<__i<<": " << cont[__i]<<")";} cout<<endl;

/*
 * ***_bound(6)
 * 5 6 6 6 6 6 7 7 7
 *   ^lower    ^upper
 * void reverse(c.begin(), c.end())
 *
 * graph
 * seg tree
 * dp
 * brute force
 */
struct Comparator{
    int operator()(int l, int r) const {
        return r<l;
    }
};
//set<int, Comparator> S;

struct Vec{
    double v[2];
    string to_s(){
        return "("+to_string(v[0])+","+to_string(v[1])+")";
    }
    double& operator[](int t){
        return v[t];
    }
    Vec operator+(Vec t) {
        return {v[0]+t[0],v[1]+t[1]};
    }
    Vec& operator+=(Vec t) {
        v[0]+=t[0];v[1]+=t[1];
        return *this;
    }
    Vec operator-(Vec t) {
        return {v[0]-t[0],v[1]-t[1]};
    }
    Vec& operator-=(Vec t) {
        v[0]-=t[0];v[1]-=t[1];
        return *this;
    }
    Vec operator*(double t) {
        return {v[0]*t,v[1]*t};
    }
    Vec& operator*=(double t) {
        v[0]*=t;v[1]*=t;
        return *this;
    }
    double operator*(Vec t) {
        return v[0]*t[0]+v[1]*t[1];
    }
    Vec operator-(){
        return {-v[0],-v[1]};
    }
    static Vec Z;
};
Vec Vec::Z={0,0};

typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef vector<P> VP;
typedef pair<ll,ll> RP;
ll N,M;
vector<RP> D;
vector<vector<ll> > G;
ll INF=1000*1000*1000;
map<RP,ll> en;
vector<bool> solved;
vector<ll> edges;
vector<bool> white;
vector<RP> DO;
RP to_e(ll s,ll t) {
    return {min(s,t),max(s,t)};
}
void no(){
    cout<<-1<<endl;
    exit(0);
}
int main() {
    cin >> N >>M;
    solved.resize(N,false);
    D.resize(N);
    edges.resize(M,INF);
    white.resize(N,false);
    REP(i,N) {
        cin >> D[i].fi;
        D[i].se=i;
    }
    G.resize(N);
    REP(i,M) {
        ll u,v;
        cin >> u>>v;--u;--v;
        if (u>v)swap(u,v);
        en[{u,v}]=i;
        G[u].pb(v);
        G[v].pb(u);
    }
    DO=D;
    sort(ALL(D));
    for(int i=0;i<D.size();++i){
        RP p=D[i];
        if (solved[p.se])continue;
        bool s=false;
        for(ll n:G[p.se]){
            if (solved[n]) {
                white[p.se]=!white[n];
                solved[p.se]=true;
                edges[en[to_e(p.se,n)]]=p.fi;
                s=true;
                break;
            }
        }
        if (!s) {
            bool t=false;
            for(ll n:G[p.se]) {
                if(p.fi==DO[n].fi){
                    solved[p.se]=solved[n]=true;
                    white[p.se]=true;
                    white[n]=false;
                    edges[en[to_e(p.se,n)]]=p.fi;
                    t=true;
                }
            }
            if (!t)no();
        }
    }
    REP(i,N)
        cout<< ((white[i])?"W":"B");
    cout<<endl;
    REP(i,M)
        cout<<edges[i]<<endl;
    return 0;
}


Measured memory_bytes: 27520