#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 300;
struct Rec {
  int s, t, vol;
  Rec(int _s, int _t, int _vol) : s(_s), t(_t), vol(_vol) {}
  Rec() {}
};
int init[MAX_SIZE + 10], desi[MAX_SIZE + 10];
int nodes[MAX_SIZE + 10], fa[MAX_SIZE + 10], dep[MAX_SIZE + 10],
    to[MAX_SIZE * 2 + 10], nxt[MAX_SIZE * 2 + 10], en;
int father[MAX_SIZE + 10];
int n, m, lim;
bool vis[MAX_SIZE + 10];
int seq[MAX_SIZE + 10], sn;
long long size[MAX_SIZE + 10];
vector<Rec> ans;
int findFather(int a) {
  if (father[a] != a) father[a] = findFather(father[a]);
  return father[a];
}
inline void addEdge(int f, int t) {
  ++en;
  to[en] = t;
  nxt[en] = nodes[f];
  nodes[f] = en;
}
void dfs(int cur) {
  vis[cur] = true;
  seq[++sn] = cur;
  for (int e = nodes[cur]; e; e = nxt[e]) {
    if (!vis[to[e]]) {
      fa[to[e]] = cur;
      dep[to[e]] = dep[cur] + 1;
      dfs(to[e]);
    }
  }
}
inline int min(int a, int b) { return a < b ? a : b; }
int path[MAX_SIZE + 10], pn;
int A[MAX_SIZE + 10], an, B[MAX_SIZE + 10], bn;
void findPath(int s, int t) {
  an = bn = 0;
  while (s != t) {
    if (dep[s] > dep[t]) {
      A[++an] = s;
      s = fa[s];
    } else {
      B[++bn] = t;
      t = fa[t];
    }
  }
  A[++an] = s;
  for (int i = 1; i <= an; i++) path[i] = A[i];
  for (int i = 1; i <= bn; i++) path[an + bn - i + 1] = B[i];
  pn = an + bn;
}
void trans(int s, int t, int vol) {
  if (t == s + 1) {
    init[path[s]] -= vol;
    init[path[t]] += vol;
    ans.push_back(Rec(path[s], path[t], vol));
    return;
  }
  int tt = min(init[path[t - 1]], vol);
  init[path[t - 1]] -= tt;
  init[path[t]] += tt;
  ans.push_back(Rec(path[t - 1], path[t], tt));
  trans(s, t - 1, vol);
  init[path[t - 1]] -= vol - tt;
  init[path[t]] += vol - tt;
  ans.push_back(Rec(path[t - 1], path[t], vol - tt));
}
void work() {
  int p1 = 1, p2 = 1;
  while (p1 <= sn && desi[seq[p1]] >= init[seq[p1]]) ++p1;
  while (p2 <= sn && desi[seq[p2]] <= init[seq[p2]]) ++p2;
  while (p1 <= sn && p2 <= sn) {
    findPath(seq[p1], seq[p2]);
    trans(1, pn,
          min(init[seq[p1]] - desi[seq[p1]], desi[seq[p2]] - init[seq[p2]]));
    while (p1 <= sn && desi[seq[p1]] >= init[seq[p1]]) ++p1;
    while (p2 <= sn && desi[seq[p2]] <= init[seq[p2]]) ++p2;
  }
}
int main() {
  scanf("%d%d%d", &n, &lim, &m);
  for (int i = 1; i <= n; i++) scanf("%d", init + i);
  for (int i = 1; i <= n; i++) scanf("%d", desi + i);
  for (int i = 1; i <= n; i++) father[i] = i;
  for (int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    if (findFather(a) != findFather(b)) {
      father[findFather(a)] = findFather(b);
      addEdge(a, b);
      addEdge(b, a);
    }
  }
  for (int i = 1; i <= n; i++) size[findFather(i)] += desi[i] - init[i];
  for (int i = 1; i <= n; i++)
    if (size[i] != 0) {
      printf("NO\n");
      return 0;
    }
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      sn = 0;
      dfs(i);
      work();
    }
  }
  printf("%d\n", ans.size());
  for (vector<Rec>::iterator it = ans.begin(); it != ans.end(); it++)
    printf("%d %d %d\n", it->s, it->t, it->vol);
  return 0;
}
