#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
const double PI = acos(-1);
template <class T>
constexpr T INF() {
  return ::std::numeric_limits<T>::max();
}
template <class T>
constexpr T HINF() {
  return INF<T>() / 2;
}
template <typename T_char>
T_char TL(T_char cX) {
  return tolower(cX);
};
template <typename T_char>
T_char TU(T_char cX) {
  return toupper(cX);
};
const int vy[] = {-1, -1, -1, 0, 1, 1, 1, 0},
          vx[] = {-1, 0, 1, 1, 1, 0, -1, -1};
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int popcnt(unsigned long long n) {
  int cnt = 0;
  for (int i = 0; i < 64; i++)
    if ((n >> i) & 1) cnt++;
  return cnt;
}
int d_sum(LL n) {
  int ret = 0;
  while (n > 0) {
    ret += n % 10;
    n /= 10;
  }
  return ret;
}
int d_cnt(LL n) {
  int ret = 0;
  while (n > 0) {
    ret++;
    n /= 10;
  }
  return ret;
}
LL gcd(LL a, LL b) {
  if (b == 0) return a;
  return gcd(b, a % b);
};
LL lcm(LL a, LL b) {
  LL g = gcd(a, b);
  return a / g * b;
};
struct INIT {
  INIT() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cout << fixed << setprecision(13);
  }
} INIT;
struct UnionFind {
  UnionFind(size_t size) {
    for (int i = 0; i < (int)size; i++) {
      par.emplace_back(i);
      rnk.emplace_back(0);
    }
  }
  vector<int> par, rnk;
  int root(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = root(par[x]);
  }
  bool is_root(int x) { return root(x) == x; }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rnk[x] == rnk[y]) rnk[x]++;
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
};
int n, m;
int d[202020];
vector<pair<int, int>> Graph[202020];
map<pair<int, int>, int> get_index;
int ans[202020];
int dis[202020];
bool isok[202020];
int main() {
  cin >> n >> m;
  for (LL i = (0); i < (n); i++) cin >> d[i];
  for (LL i = (0); i < (m); i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    get_index[make_pair(u, v)] = get_index[make_pair(v, u)] = i;
    Graph[u].emplace_back(make_pair(v, 0));
    Graph[v].emplace_back(make_pair(u, 0));
  }
  int root = 0;
  bool flg = true;
  while (flg) {
    flg = false;
    for (auto to : Graph[root]) {
      if (!flg && d[root] > d[to.first]) {
        root = to.first;
        flg = true;
      }
    }
  }
  vector<pair<int, int>> v;
  d[root] = 0;
  for (LL i = (0); i < (n); i++)
    if (i != root) v.emplace_back(make_pair(d[i], i));
  sort((v).begin(), (v).end());
  for (LL i = (0); i < (m); i++) ans[i] = -1;
  UnionFind uf(n);
  queue<pair<int, int>> q;
  q.push(make_pair(root, -1));
  isok[root] = true;
  while (!q.empty()) {
    int cur = q.front().first;
    int pre = q.front().second;
    q.pop();
    for (auto to : Graph[cur]) {
      if (to.first == pre) continue;
      if (uf.same(cur, to.first)) continue;
      if (d[to.first] <= d[cur]) continue;
      ans[get_index[make_pair(cur, to.first)]] = d[to.first] - d[cur];
      uf.unite(cur, to.first);
      q.push(make_pair(to.first, pre));
      isok[to.first] = true;
    }
  }
  for (LL i = (0); i < (n); i++) {
    if (!isok[i]) {
      cout << -1 << endl;
      return 0;
    }
  }
  for (LL i = (0); i < (n); i++) {
    if (i == root)
      cout << 'W';
    else
      cout << 'B';
  }
  cout << endl;
  for (LL i = (0); i < (m); i++) {
    cout << (ans[i] == -1 ? 1000000000 : ans[i]) << endl;
  }
}
