#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
T div_floor(T a, T b) {
  if (b < 0) a *= -1, b *= -1;
  return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
  if (b < 0) a *= -1, b *= -1;
  return a > 0 ? (a - 1) / b + 1 : a / b;
}
constexpr long long mod = 1e9 + 7;
constexpr long long INF = mod * mod;
constexpr int MAX = 100010;
struct edge {
  int id, to, cost;
  edge(int id, int to, int cost) : id(id), to(to), cost(cost) {}
};
typedef struct UnionFindTree {
  vector<int> par;
  vector<pair<int, int> > ord;
  UnionFindTree(int n, vector<int> &d) {
    par.resize(n, -1);
    ord.resize(n);
    for (int((i)) = (int)(0); ((i)) < (int)((n)); ++((i))) ord[i] = {d[i], i};
  }
  bool is_root(int x) { return par[x] < 0; }
  int find(int x) {
    if (is_root(x)) return x;
    return par[x] = find(par[x]);
  }
  int size(int x) { return -par[find(x)]; }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (size(x) < size(y)) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    ord[x] = min(ord[x], ord[y]);
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
} UF;
int ans[2 * MAX];
vector<edge> G[MAX], H[MAX];
void dfs(int v, edge pe, string &s, vector<int> &d) {
  if (pe.id < 0) {
    s[v] = 'B';
    for (auto e : H[v]) dfs(e.to, {e.id, v, -1}, s, d);
  } else {
    int pv = pe.to;
    if (d[v] == d[pv]) {
      s[v] = (s[pv] == 'B' ? 'W' : 'B');
      ans[pe.id] = d[v];
    } else {
      s[v] = s[pv];
      ans[pe.id] = d[v] - d[pv];
    }
    for (auto e : H[v])
      if (e.to != pv) {
        dfs(e.to, {e.to, v, -1}, s, d);
      }
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vector<int> d(n);
  for (int((i)) = (int)(0); ((i)) < (int)((n)); ++((i))) scanf("%d", &d[i]);
  UF uf(n, d);
  for (int((i)) = (int)(0); ((i)) < (int)((m)); ++((i))) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u;
    --v;
    G[u].emplace_back(i, v, 1e9);
    G[v].emplace_back(i, u, 1e9);
  }
  for (int((i)) = (int)(0); ((i)) < (int)((n)); ++((i))) {
    pair<int, int> tmp = {d[i], mod};
    edge te = {-1, -1, -1};
    for (auto &e : G[i])
      if (chmin(tmp, uf.ord[e.to])) te = e;
    if (te.to < 0) {
      puts("-1");
      return 0;
    }
    H[te.to].emplace_back(te.id, i, -1);
    uf.unite(i, te.to);
  }
  string s;
  for (int((i)) = (int)(0); ((i)) < (int)((n)); ++((i))) s += '#';
  fill(ans, ans + m, 1e9);
  for (int((i)) = (int)(0); ((i)) < (int)((n)); ++((i)))
    if (uf.ord[uf.find(i)].second == i) {
      dfs(i, {-1, -1, -1}, s, d);
    }
  cout << s << "\n";
  for (int((i)) = (int)(0); ((i)) < (int)((m)); ++((i))) printf("%d\n", ans[i]);
}
