#include <bits/stdc++.h>
using namespace std;
template <typename COST = double>
struct graph {
  vector<int> dest;
  vector<vector<int> > adj;
  int inv(int a) { return a ^ 0x1; }
  graph(int n = 0) {
    adj.resize(n);
    imb.resize(n);
  }
  int arc(int i, int j, long long u = 1, COST c = 0) {
    dest.push_back(j);
    adj[i].push_back(((int)(dest).size()) - 1);
    dest.push_back(i);
    adj[j].push_back(((int)(dest).size()) - 1);
    cap.push_back(u);
    cap.push_back(0);
    cost.push_back(c);
    cost.push_back(-c);
    return ((int)(dest).size()) - 2;
  }
  vector<long long> cap, flow;
  int orig(int a) { return dest[inv(a)]; }
  long long capres(int a) { return cap[a] - flow[a]; }
  vector<int> curAdj, d;
  bool MFbfs(int s, int t) {
    d.assign(((int)(adj).size()), INT_MAX / 2);
    curAdj = vector<int>(((int)(adj).size()));
    d[s] = 0;
    queue<int> Q;
    Q.push(s);
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      for (auto i : adj[u]) {
        int v = dest[i];
        if (capres(i) > 0 && d[v] == INT_MAX / 2) {
          d[v] = d[u] + 1;
          Q.push(v);
        }
      }
    }
    return d[t] != INT_MAX / 2;
  }
  long long MFdfs(int u, int t, long long f) {
    if (u == t) return f;
    for (int &i = curAdj[u]; i < adj[u].size(); ++i) {
      int ar = adj[u][i], v = dest[ar];
      if (d[v] != d[u] + 1 || capres(ar) == 0) continue;
      long long tmpF = MFdfs(v, t, min(f, capres(ar)));
      if (tmpF) {
        flow[ar] += tmpF;
        flow[inv(ar)] -= tmpF;
        return tmpF;
      }
    }
    return 0;
  }
  long long maxflow(int ini, int end) {
    flow.assign(((int)(dest).size()), 0);
    while (MFbfs(ini, end))
      while (MFdfs(ini, end, LLONG_MAX / 2))
        ;
    long long F = 0;
    for (int a : adj[ini]) F += flow[a];
    return F;
  }
  vector<int> mincut(int ini) {
    vector<int> ans;
    vector<bool> mark(((int)(adj).size()), false);
    mark[ini] = true;
    ans.push_back(ini);
    for (int pos = 0; pos < ans.size(); ++pos) {
      int x = ans[pos];
      for (int ar : adj[x])
        if (capres(ar) > 0) {
          int y = dest[ar];
          if (mark[y]) continue;
          ans.push_back(y);
          mark[y] = true;
        }
    }
    return ans;
  }
  vector<long long> imb;
  vector<COST> cost, pot;
  long long delta;
  COST rescost(int a) { return cost[a] + pot[orig(a)] - pot[dest[a]]; }
  bool MCFdijkstra() {
    priority_queue<pair<COST, pair<int, int> > > q;
    vector<int> ent(((int)(adj).size()), -2);
    vector<COST> dist(((int)(adj).size()), INFINITY);
    for (int u = 0; u < ((int)(adj).size()); ++u)
      if (imb[u] >= delta) q.push(make_pair(0, make_pair(u, -1)));
    while (!q.empty()) {
      int u = q.top().second.first, f = q.top().second.second;
      COST d = -q.top().first;
      q.pop();
      if (ent[u] != -2) continue;
      dist[u] = d;
      ent[u] = f;
      for (int a : adj[u])
        if (capres(a) >= delta)
          q.push(make_pair(-(dist[u] + rescost(a)), make_pair(dest[a], a)));
    }
    for (int u = 0; u < ((int)(adj).size()); ++u)
      if (ent[u] != -2 && imb[u] <= -delta) {
        for (int v = 0; v < ((int)(adj).size()); ++v) pot[v] += dist[v];
        for (int a = ent[u]; a != -1; a = ent[orig(a)]) {
          flow[a] += delta;
          flow[inv(a)] -= delta;
          imb[dest[a]] += delta;
          imb[orig(a)] -= delta;
        }
        return true;
      }
    return false;
  }
  COST mincostflow() {
    pot.resize(((int)(adj).size()));
    flow.resize(((int)(dest).size()));
    for (delta = 0x40000000; delta > 0; delta /= 2) {
      for (int a = 0; a < ((int)(dest).size()); ++a) {
        int u = orig(a), v = dest[a];
        if (capres(a) >= delta && cmp(rescost(a)) < 0) {
          imb[u] -= capres(a);
          imb[v] += capres(a);
          flow[inv(a)] -= capres(a);
          flow[a] += capres(a);
        }
      }
      while (MCFdijkstra())
        ;
    }
    COST C = 0;
    for (int a = 0; a < ((int)(dest).size()); ++a)
      if (flow[a] > 0) C += flow[a] * cost[a];
    return C;
  }
  vector<int> depth;
  vector<bool> artp, bridge;
  vector<int> least;
  int dfs_artpbridge(int u, int ent) {
    int nf = 0;
    for (int a : adj[u]) {
      int v = dest[a];
      if (depth[v] == -1) {
        least[v] = depth[v] = depth[u] + 1;
        dfs_artpbridge(v, a);
        nf++;
        if (least[v] >= depth[u]) {
          artp[u] = true;
          if (least[v] == depth[v]) bridge[a] = bridge[inv(a)] = true;
        } else
          least[u] = min(least[u], least[v]);
      } else if (inv(a) != ent)
        least[u] = min(least[u], depth[v]);
    }
    return nf;
  }
  void artpbridge() {
    artp = vector<bool>(((int)(adj).size()), false);
    bridge = vector<bool>(((int)(dest).size()), false);
    depth = vector<int>(((int)(adj).size()), -1);
    least = vector<int>(((int)(adj).size()), -1);
    for (int i = 0; i < ((int)(adj).size()); ++i)
      if (depth[i] == -1) {
        least[i] = depth[i] = 0;
        if (dfs_artpbridge(i, -1) < 2) artp[i] = false;
      }
  }
  vector<int> ord, rep;
  int transp(int a) { return (a & 0x1); }
  void dfs_topsort(int u) {
    for (int a : adj[u]) {
      int v = dest[a];
      if (!transp(a) && depth[v] == -1) {
        depth[v] = depth[u] + 1;
        dfs_topsort(v);
      }
    }
    ord.push_back(u);
  }
  void dfs_compfortcon(int u, int ent) {
    rep[u] = ent;
    for (int a : adj[u]) {
      int v = dest[a];
      if (transp(a) && rep[v] == -1) dfs_compfortcon(v, ent);
    }
  }
  void compfortcon() {
    depth = vector<int>(((int)(adj).size()), -1);
    ord.clear();
    for (int u = 0; u < ((int)(adj).size()); ++u)
      if (depth[u] == -1) {
        depth[u] = 0;
        dfs_topsort(u);
      }
    rep = vector<int>(((int)(adj).size()), -1);
    for (int i = ((int)(adj).size()) - 1; i >= 0; i--)
      if (rep[ord[i]] == -1) dfs_compfortcon(ord[i], ord[i]);
  }
  vector<int> match;
  int dfs_match(int node, int m) {
    if (match[node] == m) return 0;
    match[node] = m;
    for (int ar : adj[node]) {
      int j = dest[ar];
      if (match[j] == -1 || dfs_match(match[j], m)) {
        match[j] = node;
        return 1;
      }
    }
    return 0;
  }
  int bipartite_match(int k) {
    int N = ((int)(adj).size());
    match = vector<int>(N, -1);
    int ans = 0;
    for (int i = 0; i < k; ++i) ans += dfs_match(i, i);
    for (int i = 0; i < k; ++i) match[i] = -1;
    for (int i = k; i < N; ++i)
      if (match[i] != -1) match[match[i]] = i;
    return ans;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  int N, M;
  cin >> N >> M;
  graph<> g(2 * N + 2);
  long long a, b, totA = 0, totB = 0;
  for (int i = 1; i <= N; i++) {
    cin >> a;
    totA += a;
    g.arc(0, i, a);
  }
  for (int i = 1; i <= N; i++) {
    cin >> b;
    totB += b;
    g.arc(N + i, 2 * N + 1, b);
  }
  if (totA != totB) {
    cout << "NO\n";
    return 0;
  }
  long long tot = totA;
  for (int i = 1; i <= N; i++) {
    g.arc(i, N + i, LLONG_MAX / 2);
  }
  for (int e = 0; e < M; e++) {
    cin >> a >> b;
    g.arc(a, N + b, LLONG_MAX / 2);
    g.arc(b, N + a, LLONG_MAX / 2);
  }
  long long res = g.maxflow(0, 2 * N + 1);
  res = 0;
  vector<int> cut = g.mincut(0);
  vector<bool> isCut(g.adj.size(), false);
  for (int x : cut) isCut[x] = true;
  for (int e = 0; e < g.dest.size(); e++) {
    int u = g.orig(e), v = g.dest[e];
    if (isCut[u] && !isCut[v]) res += g.cap[e];
  }
  if (res != tot) {
    cout << "NO\n";
    return 0;
  }
  vector<vector<long long> > out(N, vector<long long>(N));
  for (int e = 0; e < g.dest.size(); ++e) {
    int u = g.orig(e), v = g.dest[e];
    long long f = g.flow[e];
    if (f > 0 && (1 <= u && u <= N) && (N + 1 <= v && v <= 2 * N)) {
      out[u - 1][v - N - 1] += f;
    }
  }
  cout << "YES\n";
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cout << out[i][j] << " ";
    }
    cout << "\n";
  }
  return 0;
}
