#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:200000000")
using namespace std;
const long long oo = 1LL << 60;
const long long kNumMoves = 4;
const long long kMoves[kNumMoves][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int n, v, e;
vector<int> a, b;
vector<vector<int> > conn, edges;
vector<int> ansX, ansY, ansD;
vector<int> topSort;
vector<int> seen;
void DFS_Topological(int node) {
  if (seen[node]) return;
  seen[node] = 1;
  for (int i = 0; i < int(n); ++i) {
    if (edges[node][i] && !seen[i]) {
      DFS_Topological(i);
      conn[node].push_back(i);
      conn[i].push_back(node);
    }
  }
  topSort.push_back(node);
}
int AddTransfusionStep(int src, int dest, int delta) {
  int mxMoveOut = min(a[src], delta);
  int mxMoveIn = min(v - a[dest], mxMoveOut);
  a[src] -= mxMoveIn;
  a[dest] += mxMoveIn;
  if (mxMoveIn)
    ansX.push_back(src + 1), ansY.push_back(dest + 1), ansD.push_back(mxMoveIn);
  return mxMoveIn;
}
int Transfuse_Out(int node, int dest, int delta) {
  if (!delta || seen[node] || seen[dest]) return 0;
  int step1 = AddTransfusionStep(node, dest, delta);
  if (step1 == delta) return delta;
  for (int i = 0; i < int(conn[dest].size()); ++i) {
    int newDest = conn[dest][i];
    if (newDest == node) continue;
    if (seen[newDest]) continue;
    AddTransfusionStep(dest, newDest, v);
    Transfuse_Out(dest, newDest, v);
    AddTransfusionStep(dest, newDest, v);
  }
  int step2 = AddTransfusionStep(node, dest, delta - step1);
  return step1 + step2;
}
int Transfuse_In(int node, int dest, int delta) {
  if (!delta || seen[node] || seen[dest]) return 0;
  int step1 = AddTransfusionStep(dest, node, delta);
  if (step1 == delta) return delta;
  for (int i = 0; i < int(conn[dest].size()); ++i) {
    int newDest = conn[dest][i];
    if (newDest == node) continue;
    if (seen[newDest]) continue;
    AddTransfusionStep(newDest, dest, v);
    Transfuse_In(dest, newDest, v);
    AddTransfusionStep(newDest, dest, v);
  }
  int step2 = AddTransfusionStep(dest, node, delta - step1);
  return step1 + step2;
}
bool Transfuse(int node) {
  int delta = a[node] - b[node];
  if (delta > 0) {
    for (int i = 0; i < int(conn[node].size()); ++i) {
      int dest = conn[node][i];
      if (seen[dest]) continue;
      delta -= Transfuse_Out(node, dest, delta);
    }
    return (delta == 0 && a[node] == b[node]);
  } else if (delta < 0) {
    delta = -delta;
    for (int i = 0; i < int(conn[node].size()); ++i) {
      int dest = conn[node][i];
      if (seen[dest]) continue;
      delta -= Transfuse_In(node, dest, delta);
    }
    return (delta == 0 && a[node] == b[node]);
  }
  return true;
}
bool FindTransfusions() {
  seen.clear();
  seen.resize(n, 0);
  for (int i = 0; i < int(n); ++i) DFS_Topological(i);
  seen.clear();
  seen.resize(n, 0);
  for (int i = 0; i < int(n); ++i) {
    if (!Transfuse(topSort[i])) return false;
    seen[topSort[i]] = 1;
  }
  return true;
}
int main() {
  cin >> n >> v >> e;
  a.resize(n), b.resize(n);
  for (int i = 0; i < int(n); ++i) cin >> a[i];
  for (int i = 0; i < int(n); ++i) cin >> b[i];
  conn.resize(n);
  edges.resize(n, vector<int>(n, 0));
  for (int i = 0; i < int(e); ++i) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    edges[x][y] = edges[y][x] = 1;
  }
  if (FindTransfusions()) {
    cout << ansX.size() << endl;
    for (int i = 0; i < int(ansX.size()); ++i)
      cout << ansX[i] << " " << ansY[i] << " " << ansD[i] << endl;
  } else {
    cout << "NO";
  }
  int i;
  cin >> i;
  return 0;
}
