#include <bits/stdc++.h>
using ll = long long;
using vi = std::vector<int>;
using vvi = std::vector<vi>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
template <typename T>
std::vector<T> vec(int l, T e) {
  return std::vector<T>(l, e);
}
template <typename T>
using MaxHeap = std::priority_queue<T>;
template <typename T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& v) {
  int sz = v.size();
  s << "\n";
  for (int(i) = (0); (i) < (sz); ++(i)) {
    s << v[i];
    if (i < sz - 1) {
      s << "\t";
    }
  }
  s << "\n";
  return s;
}
template <typename T>
std::ostream& operator<<(std::ostream& s,
                         const std::vector<std::vector<T>>& v) {
  for (auto&& w : v) {
    s << w;
  }
  return s;
}
template <typename T>
std::ostream& operator<<(std::ostream& s, const std::deque<T>& v) {
  int sz = v.size();
  s << "\n";
  for (int(i) = (0); (i) < (sz); ++(i)) {
    s << v[i];
    if (i < sz - 1) {
      s << "\t";
    }
  }
  s << "\n";
  return s;
}
template <typename T>
std::ostream& operator<<(std::ostream& s, const std::deque<std::deque<T>>& v) {
  for (auto&& w : v) {
    s << w;
  }
  return s;
}
template <typename T>
std::ostream& operator<<(std::ostream& s, const std::set<T>& v) {
  s << "\n";
  for (auto&& elm : v) {
    s << elm << "\t";
  }
  s << "\n";
  return s;
}
inline void scan(int& a) { scanf("%d", &a); }
inline void scan(ll& a) { scanf("%lld", &a); }
inline void scan(char& a) { scanf(" %c", &a); }
inline void scan(double& a) { scanf("%lf", &a); }
template <typename T>
inline void scan(std::vector<T>& v) {
  for (auto&& sv : v) {
    scan(sv);
  }
}
template <typename First, typename... Args>
inline void scan(First& f, Args&... args) {
  scan(f);
  scan(args...);
}
inline void scan(std::string& s) {
  char BUF[3000000];
  scanf(" %s", BUF);
  s = std::string(BUF);
}
inline void print(int a) { printf("%d\n", a); }
inline void print(ll a) { printf("%lld\n", a); }
inline void print(double a) { printf("%.12f\n", a); }
inline void print(std::string s) { std::cout << s << "\n"; }
using namespace std;
void no_sol() {
  print(-1);
  exit(0);
}
void print_sol(vi color, vi weight) {
  int n = color.size();
  for (int(i) = (0); (i) < (n); ++(i)) {
    assert(color[i] == 1 || color[i] == 2);
    char c = " WB"[color[i]];
    printf("%c", c);
  }
  printf("\n");
  int m = weight.size();
  for (int(i) = (0); (i) < (m); ++(i)) {
    assert(weight[i] > 0);
    print(weight[i]);
  }
}
struct Edge {
  int idx, u, v;
  int opponent(int w) { return w ^ u ^ v; }
};
int main() {
  int n, m;
  scan(n, m);
  vi d(n);
  scan(d);
  vector<vector<Edge>> edges(n);
  for (int(i) = (0); (i) < (m); ++(i)) {
    int u, v;
    scan(u, v);
    --u;
    --v;
    auto edge = Edge({i, u, v});
    edges[u].push_back(edge);
    edges[v].push_back(edge);
  }
  vvi ds(n, vi(2));
  for (int(i) = (0); (i) < (n); ++(i)) {
    ds[i][0] = d[i];
    ds[i][1] = i;
  }
  map<int, int> dcnt;
  for (int(i) = (0); (i) < (n); ++(i)) {
    dcnt[d[i]] += 1;
  }
  vi color(n, 0);
  vi weight(m, 0);
  deque<int> progress(n, 0);
  MinHeap<vi> pq;
  for (int(i) = (0); (i) < (n); ++(i)) {
    if (dcnt[ds[i][0]] >= 2) {
      pq.push(ds[i]);
      progress[ds[i][1]] = 1;
    }
  }
  for (int(i) = (0); (i) < (n); ++(i)) {
    if (pq.empty()) {
      no_sol();
    }
    auto dsi = pq.top();
    pq.pop();
    int u = dsi[1];
    assert(progress[u] == 1);
    progress[u] = 2;
    bool connectivity = false;
    for (auto edge : edges[u]) {
      int v = edge.opponent(u);
      if ((progress[v] == 2 && d[v] <= d[u]) ||
          (progress[v] == 1 && d[v] == d[u])) {
        connectivity = true;
        break;
      }
    }
    if (!connectivity) {
      no_sol();
    }
    int colors = 0;
    for (auto edge : edges[u]) {
      int v = edge.opponent(u);
      if (progress[v] < 2) {
        continue;
      }
      assert(weight[edge.idx] == 0);
      assert(d[v] <= d[u]);
      weight[edge.idx] = d[u];
      colors |= color[v];
    }
    color[u] = 1;
    if (colors == 1) {
      color[u] = 2;
    }
    for (auto edge : edges[u]) {
      int v = edge.opponent(u);
      if (progress[v] == 0) {
        pq.push({d[v], v});
        progress[v] = 1;
      }
    }
  }
  print_sol(color, weight);
  return 0;
}
