#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <complex>

class edge{
  public:

  long long int to, index;

  edge(long long int t, long long int i){
    to = t;
    index = i;
  }
  
};

long long int fill_weight_color(std::vector<std::vector<class edge> > &G_des, std::vector<long long int> &D, std::vector<long long int> &color, std::vector<long long int> &weight, long long int i);

int main(){

  // read problem
  long long int N, M, tmp1, tmp2;
  std::vector<long long int> D;
  scanf("%lld%lld", &N, &M);
  for(long long int i = 0; i < N; i++){
    scanf("%lld", &tmp1);
    D.push_back(tmp1);
  }

  std::vector<std::vector<class edge> > G(N);
  for(long long int i = 0; i < M; i++){
    scanf("%lld%lld", &tmp1, &tmp2);
    G[tmp1-1].push_back(edge(tmp2-1, i));
    G[tmp2-1].push_back(edge(tmp1-1, i));
  }

  /*std::cerr << "N: " << N << " M: " << M << std::endl;
  std::cerr << "G:" << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cerr << i << ": ";
    for(long long int j = 0; j < G[i].size(); j++){
      std::cerr << G[i][j].to << " ";
    }std::cerr << std::endl;
  }*/

  // make G_des, G_same
  std::vector<std::vector<class edge> > G_des(N), G_same(N);
  for(long long int i = 0; i < N; i++){
    for(long long int j = 0; j < G[i].size(); j++){
      if(D[i] > D[G[i][j].to]){
        G_des[i].push_back(G[i][j]);
      }
      else if(D[i] == D[G[i][j].to]){
        G_same[i].push_back(G[i][j]);
      }
    }
  }

  std::cerr << "G_des, G_same is made" << std::endl;

  // solve problem
  std::vector<long long int> color(N);
  std::vector<long long int> weight(M);
  for(long long int i = 0; i < N; i++){
    color[i] = -1;
  }
  for(long long int i = 0; i < M; i++){
    weight[i] = -1;
  }

  std::cerr << "color, weight are prepared" << std::endl;

  // check possibility and initialize
  long long int possible = 1;
  for(long long int i = 0; i < N; i++){
    // local minimum whose color has not been determined
    if(G_des[i].size() == 0 && color[i] == -1){
      // impossible
      if(G_same[i].size() == 0){
        possible = 0;
        i = N;
        break;
      }
      // determine color
      if(color[G_same[i][0].to] == -1){
        color[i] = 0;
        color[G_same[i][0].to] = 1;
        weight[G_same[i][0].index] = D[i];
      }
      else{
        color[i] = (color[G_same[i][0].to]+1)%2;
        weight[G_same[i][0].index] = D[i];
      }
    }
  }

  std::cerr << "color, weight are initialized" << std::endl;

  // if impossible
  if(possible == 0){
    std::cerr << "Answer: " << std::endl;
    std::cout << "-1" << std::endl;
    return 0;
  }

  // determine color and weight
  for(long long int i = 0; i < N; i++){
    fill_weight_color(G_des, D, color, weight, i);
  }

  std::cerr << "color, weight are filled" << std::endl;

  // print answer
  std::cerr << "Answer: " << std::endl;

  for(long long int i = 0; i < N; i++){
    if(color[i] == 0){
      std::cout << "B";
    }
    else{
      std::cout << "W";
    }
  }std::cout << std::endl;

  for(long long int i = 0; i < M; i++){
    if(weight[i] < 0){
      std::cout << "1000000000" << std::endl;
    }
    else{
      std::cout << weight[i] << std::endl;
    }
  }

  return 0;
  
}

long long int fill_weight_color(std::vector<std::vector<class edge> > &G_des, std::vector<long long int> &D, std::vector<long long int> &color, std::vector<long long int> &weight, long long int i){

  // if node i is already painted
  if(color[i] >= 0){
    return color[i];
  }

  // determine weight
  weight[G_des[i][0].index] = D[i] - D[G_des[i][0].to];
  // determine color
  long long int col;
  col = fill_weight_color(G_des, D, color, weight, G_des[i][0].to);
  color[i] = col;

  return col;
}

Measured memory_bytes: 28916