Problem: Ostap is preparing to play chess again and this time he is about to prepare. Thus, he was closely monitoring one recent chess tournament. There were m players participating and each pair of players played exactly one game. The victory gives 2 points, draw — 1 points, lose — 0 points.

Ostap is lazy, so he never tries to remember the outcome of each game. Instead, he computes the total number of points earned by each of the players (the sum of his points in all games which he took part in), sort these value in non-ascending order and then remembers first n integers in this list.

Now the Great Strategist Ostap wonders whether he remembers everything correct. He considers that he is correct if there exists at least one tournament results table such that it will produce the given integers. That means, if we count the sum of points for each player, sort them and take first n elements, the result will coincide with what Ostap remembers. Can you check if such table exists?

Input

The first line of the input contains two integers m and n (1 ≤ n ≤ m ≤ 3000) — the number of participants of the tournament and the number of top results Ostap remembers.

The second line contains n integers, provided in non-ascending order — the number of points earned by top participants as Ostap remembers them. It's guaranteed that this integers are non-negative and do not exceed 2·m.

Output

If there is no tournament such that Ostap can obtain the given set of integers using the procedure described in the statement, then print "no" in the only line of the output. Otherwise, the first line of the output should contain the word "yes". Next m lines should provide the description of any valid tournament. Each of these lines must contain m characters 'X', 'W', 'D' and 'L'. Character 'X' should always be located on the main diagonal (and only there), that is on the i-th position of the i-th string. Character 'W' on the j-th position of the i-th string means that the i-th player won the game against the j-th. In the same way character 'L' means loose and 'D' means draw.

The table you print must be consistent and the points earned by best n participants should match the memory of Ostap. If there are many possible answers, print any of them.

Examples

Input

5 5
8 6 4 2 0


Output

yes
XWWWW
LXWWW
LLXWW
LLLXW
LLLLX


Input

5 1
9


Output

no

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <typename... As>
struct tpl : public std::tuple<As...> {
  using std::tuple<As...>::tuple;
  template <typename T = tuple<As...>>
  typename tuple_element<0, T>::type const& x() const {
    return get<0>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<0, T>::type& x() {
    return get<0>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<1, T>::type const& y() const {
    return get<1>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<1, T>::type& y() {
    return get<1>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<2, T>::type const& z() const {
    return get<2>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<2, T>::type& z() {
    return get<2>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<3, T>::type const& w() const {
    return get<3>(*this);
  }
  template <typename T = tuple<As...>>
  typename tuple_element<3, T>::type& w() {
    return get<3>(*this);
  }
};
using llu = long long unsigned;
using pii = tpl<int, int>;
using piii = tpl<int, int, int>;
using piiii = tpl<int, int, int, int>;
using vi = vector<int>;
using vii = vector<pii>;
using viii = vector<piii>;
using vvi = vector<vi>;
using vvii = vector<vii>;
using vviii = vector<viii>;
template <class T>
using min_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
using max_queue = priority_queue<T>;
template <size_t... I>
struct my_index_sequence {
  using type = my_index_sequence;
  static constexpr array<size_t, sizeof...(I)> value = {{I...}};
};
namespace my_index_sequence_detail {
template <typename I, typename J>
struct concat;
template <size_t... I, size_t... J>
struct concat<my_index_sequence<I...>, my_index_sequence<J...>>
    : my_index_sequence<I..., (sizeof...(I) + J)...> {};
template <size_t N>
struct make_index_sequence
    : concat<typename make_index_sequence<N / 2>::type,
             typename make_index_sequence<N - N / 2>::type>::type {};
template <>
struct make_index_sequence<0> : my_index_sequence<> {};
template <>
struct make_index_sequence<1> : my_index_sequence<0> {};
}  // namespace my_index_sequence_detail
template <class... A>
using my_index_sequence_for =
    typename my_index_sequence_detail::make_index_sequence<sizeof...(A)>::type;
template <class T, size_t... I>
void print_tuple(ostream& s, T const& a, my_index_sequence<I...>) {
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0 ? "" : ", ") << get<I>(a)), 0)...};
}
template <class T>
ostream& print_collection(ostream& s, T const& a);
template <class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a);
template <class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a);
template <class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a);
template <class T, size_t I>
ostream& operator<<(ostream& s, array<T, I> const& a) {
  return print_collection(s, a);
}
template <class T>
ostream& operator<<(ostream& s, vector<T> const& a) {
  return print_collection(s, a);
}
template <class T, class U>
ostream& operator<<(ostream& s, multimap<T, U> const& a) {
  return print_collection(s, a);
}
template <class T>
ostream& operator<<(ostream& s, multiset<T> const& a) {
  return print_collection(s, a);
}
template <class T, class U>
ostream& operator<<(ostream& s, map<T, U> const& a) {
  return print_collection(s, a);
}
template <class T>
ostream& operator<<(ostream& s, set<T> const& a) {
  return print_collection(s, a);
}
template <class T>
ostream& print_collection(ostream& s, T const& a) {
  s << '[';
  for (auto it = begin(a); it != end(a); ++it) {
    s << *it;
    if (it != prev(end(a))) s << " ";
  }
  return s << ']';
}
template <class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a) {
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}
template <class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a) {
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}
template <class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a) {
  return s << "(" << get<0>(a) << ", " << get<1>(a) << ")";
}
namespace std {
namespace {
template <class T>
inline void hash_combine(size_t& seed, T const& v) {
  seed ^= hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template <class Tuple, size_t Index = tuple_size<Tuple>::value - 1>
struct HashValueImpl {
  static void apply(size_t& seed, Tuple const& tuple) {
    HashValueImpl<Tuple, Index - 1>::apply(seed, tuple);
    hash_combine(seed, get<Index>(tuple));
  }
};
template <class Tuple>
struct HashValueImpl<Tuple, 0> {
  static void apply(size_t& seed, Tuple const& tuple) {
    hash_combine(seed, get<0>(tuple));
  }
};
}  // namespace
template <typename... TT>
struct hash<tuple<TT...>> {
  size_t operator()(tuple<TT...> const& tt) const {
    size_t seed = 0;
    HashValueImpl<tuple<TT...>>::apply(seed, tt);
    return seed;
  }
};
template <typename... TT>
struct hash<tpl<TT...>> {
  size_t operator()(tpl<TT...> const& tt) const {
    size_t seed = 0;
    HashValueImpl<tuple<TT...>>::apply(seed, tt);
    return seed;
  }
};
}  // namespace std
int read_positive() {
  char c;
  int x = 0;
  do {
    c = getchar();
  } while (c < '0' || c > '9');
  while (c >= '0' && c <= '9') {
    x = 10 * x + (c - '0');
    c = getchar();
  }
  return x;
}
struct MaxFlow {
  struct Edge {
    short from, to, index;
    int cap, flow;
    Edge(int from, int to, int cap, int flow, int index)
        : from(from), to(to), cap(cap), flow(flow), index(index) {}
  };
  int N;
  vector<vector<Edge>> G;
  vector<int> excess;
  vector<int> dist, active, count;
  queue<int> Q;
  MaxFlow(int N = 0)
      : N(N), G(N), excess(N), dist(N), active(N), count(2 * N) {}
  int addNode() {
    N += 1;
    G.emplace_back();
    excess.emplace_back();
    dist.emplace_back();
    active.emplace_back();
    count.emplace_back();
    count.emplace_back();
    return N - 1;
  }
  Edge* addEdge(int from, int to, int cap) {
    G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
    Edge* e = &G[from].back();
    if (from == to) G[from].back().index++;
    G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    return e;
  }
  void enqueue(int v) {
    if (!active[v] && excess[v] > 0) {
      active[v] = true;
      Q.push(v);
    }
  }
  void push(Edge& e) {
    int amt = min(excess[e.from], e.cap - e.flow);
    if (dist[e.from] <= dist[e.to] || amt == 0) return;
    e.flow += amt;
    G[e.to][e.index].flow -= amt;
    excess[e.to] += amt;
    excess[e.from] -= amt;
    enqueue(e.to);
  }
  void gap(int k) {
    for (int v = 0; v < (int)(N); ++v) {
      if (dist[v] < k) continue;
      count[dist[v]]--;
      dist[v] = max(dist[v], N + 1);
      count[dist[v]]++;
      enqueue(v);
    }
  }
  void relabel(int v) {
    count[dist[v]]--;
    dist[v] = 2 * N;
    for (Edge& e : G[v])
      if (e.cap - e.flow > 0) {
        dist[v] = min(dist[v], dist[e.to] + 1);
      }
    count[dist[v]]++;
    enqueue(v);
  }
  void discharge(int v) {
    for (int i = 0; excess[v] > 0 && i < (int)G[v].size(); ++i) push(G[v][i]);
    if (excess[v] > 0) {
      if (count[dist[v]] == 1) {
        gap(dist[v]);
      } else {
        relabel(v);
      }
    }
  }
  int flow(int s, int t) {
    count[0] = N - 1;
    count[N] = 1;
    dist[s] = N;
    active[s] = active[t] = true;
    for (Edge& e : G[s]) {
      excess[s] += e.cap;
      push(e);
    }
    while (!Q.empty()) {
      int v = Q.front();
      Q.pop();
      active[v] = false;
      discharge(v);
    }
    int totflow = 0;
    for (Edge& e : G[s]) totflow += e.flow;
    return totflow;
  }
};
int A[3000];
char R[3000][3000];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int tot = n * (n - 1);
  for (int i = 0; i < (int)(m); ++i) {
    cin >> A[i];
    tot -= A[i];
  }
  for (int i = (m); i <= (int)(n - 1); ++i) {
    A[i] = A[i - 1];
  }
  if (tot < 0) {
    cout << "no" << endl;
    return 0;
  }
  MaxFlow G(2 + 2 * n + 1);
  int S = 0;
  int T = 1;
  int T2 = 2 + 2 * n;
  G.addEdge(T2, T, tot);
  for (int i = 0; i < (int)(n); ++i) {
    G.addEdge(S, 2 + i, 2 * (n - 1 - i));
    for (int j = (i); j <= (int)(n - 1); ++j) {
      G.addEdge(2 + i, 2 + n + j, (i == j) ? (2 * (n - 1)) : 2);
    }
    G.addEdge(2 + n + i, (i < m) ? T : T2, A[i]);
  }
  int f = G.flow(S, T);
  if (f != n * (n - 1)) {
    cout << "no" << endl;
    return 0;
  }
  for (int i = 0; i < (int)(n); ++i) R[i][i] = 'X';
  for (int i = 0; i < (int)(n); ++i)
    for (auto const& e : G.G[2 + i]) {
      int j = e.to - 2 - n;
      if (i == j) continue;
      if (!(j >= 0 && j < n)) continue;
      if (e.flow == 2) {
        R[i][j] = 'L';
        R[j][i] = 'W';
      } else if (e.flow == 1) {
        R[i][j] = R[j][i] = 'D';
      } else {
        R[i][j] = 'W';
        R[j][i] = 'L';
      }
    }
  cout << "yes" << endl;
  for (int i = 0; i < (int)(n); ++i) {
    for (int j = 0; j < (int)(n); ++j) {
      cout << R[i][j];
    }
    cout << '\n';
  }
  cout << flush;
  return 0;
}