#include <bits/stdc++.h>
using namespace std;
const int INF = (int)1e+9;
const int N = 105;
struct Edge {
  int to, rev, cap;
};
int n, m;
int A[N], B[N];
int source, sink;
vector<Edge> G[N << 1];
int ans[N][N];
inline void addEdge(int u, int v, int _cap) {
  Edge a = {v, (int)(G[v]).size(), _cap};
  Edge b = {u, (int)(G[u]).size(), 0};
  G[u].push_back(a);
  G[v].push_back(b);
}
int dist[N << 1];
pair<int, int> par[N << 1];
inline void BFS() {
  for (int i = source; i <= sink; i++) {
    dist[i] = INF;
    par[i] = {-1, -1};
  }
  queue<int> q;
  dist[source] = 0;
  q.push(source);
  while (!q.empty()) {
    int cur = q.front();
    q.pop();
    for (int i = 0; i < (int)(G[cur]).size(); i++) {
      Edge e = G[cur][i];
      if (dist[cur] + 1 < dist[e.to] && e.cap > 0) {
        dist[e.to] = dist[cur] + 1;
        q.push(e.to);
        par[e.to] = {cur, i};
      }
    }
  }
}
inline int MaxFlow() {
  int ret = 0;
  while (1) {
    BFS();
    if (dist[sink] == INF) break;
    int cur = sink, mins = INF;
    while (cur != source) {
      pair<int, int> prev = par[cur];
      mins = min(mins, G[prev.first][prev.second].cap);
      cur = prev.first;
    }
    cur = sink;
    while (cur != source) {
      pair<int, int> prev = par[cur];
      G[prev.first][prev.second].cap -= mins;
      G[cur][G[prev.first][prev.second].rev].cap += mins;
      cur = prev.first;
    }
    ret += mins;
  }
  return ret;
}
int main() {
  scanf("%d %d", &n, &m);
  sink = 2 * n + 1;
  int before = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &A[i]);
    before += A[i];
    addEdge(source, i, A[i]);
    addEdge(i, i + n, INF);
  }
  int after = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &B[i]);
    addEdge(i + n, sink, B[i]);
    after += B[i];
  }
  int u, v;
  for (int i = 1; i <= m; i++) {
    scanf("%d %d", &u, &v);
    addEdge(u, v + n, INF);
    addEdge(v, u + n, INF);
  }
  int mf = MaxFlow();
  if (mf != after || mf != before) {
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for (int cur = 1; cur <= n; cur++) {
    for (int i = 0; i < (int)(G[cur]).size(); i++) {
      Edge e = G[cur][i];
      if (e.to == source) continue;
      assert(e.to >= n + 1 && e.to <= 2 * n);
      ans[cur][e.to - n] = INF - e.cap;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      printf("%d%c", ans[i][j], j == n ? '\n' : ' ');
    }
  }
  return 0;
}
