#include <bits/stdc++.h>
using namespace std;
const int maxn = 200500;
const int inf = 2e9;
const double eps = 1e-8;
const int base = 1073676287;
int w[maxn];
int c[maxn];
vector<pair<int, int> > edge[maxn];
vector<pair<pair<int, int>, pair<int, int> > > allEdges;
int usedEdges[maxn];
int anc[maxn];
int SZ[maxn];
int tin[maxn];
int tout[maxn];
int timer = 1;
pair<int, int> up[maxn][20];
void init() {
  for (int j = 0; j < maxn; j++) anc[j] = j, SZ[j] = 1, tout[j] = inf;
  for (int j = 0; j < maxn; j++)
    for (int i = 0; i < 20; i++) up[j][i] = make_pair(0, 0);
  for (int j = 0; j < maxn; j++) usedEdges[j] = false;
}
int findSet(int v) { return v == anc[v] ? v : anc[v] = findSet(anc[v]); }
void unionSets(int u, int v) {
  u = findSet(u);
  v = findSet(v);
  if (SZ[u] < SZ[v]) swap(u, v);
  SZ[u] += SZ[v];
  anc[v] = u;
}
void dfs(int v, int p, int cost) {
  tin[v] = ++timer;
  up[v][0] = make_pair(p, cost);
  for (int i = 1; i < 20; i++) {
    up[v][i].first = up[up[v][i - 1].first][i - 1].first;
    up[v][i].second =
        max(up[v][i - 1].second, up[up[v][i - 1].first][i - 1].second);
  }
  for (size_t i = 0; i < edge[v].size(); ++i) {
    int to = edge[v][i].first;
    if (to != p && usedEdges[edge[v][i].second])
      dfs(to, v, w[edge[v][i].second]);
  }
  tout[v] = ++timer;
}
bool upper(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }
int lca(int a, int b) {
  if (upper(a, b)) return a;
  if (upper(b, a)) return b;
  for (int i = 19; i >= 0; --i)
    if (!upper(up[a][i].first, b)) a = up[a][i].first;
  return up[a][0].first;
}
int goUp(int u, int v) {
  if (u == v) return 0;
  int curAns = 0;
  for (int i = 19; i >= 0; --i)
    if (!upper(up[u][i].first, v)) {
      curAns = max(curAns, up[u][i].second);
      u = up[u][i].first;
    }
  return max(curAns, up[u][0].second);
}
int main() {
  srand(time(0));
  init();
  int n, m;
  scanf("%d%d", &n, &m);
  for (int j = 0; j < m; j++) scanf("%d", &w[j]);
  for (int j = 0; j < m; j++) scanf("%d", &c[j]);
  int S;
  for (int j = 0; j < m; j++) {
    int u, v;
    scanf("%d%d", &u, &v);
    edge[u].push_back(make_pair(v, j));
    edge[v].push_back(make_pair(u, j));
    allEdges.push_back(make_pair(make_pair(w[j], j), make_pair(u, v)));
  }
  scanf("%d", &S);
  sort(allEdges.begin(), allEdges.end());
  long long sum = 0LL;
  for (int j = 0; j < m; j++) {
    int u = allEdges[j].second.first;
    int v = allEdges[j].second.second;
    int num = allEdges[j].first.second;
    if (findSet(v) != findSet(u)) {
      usedEdges[num] = true;
      unionSets(u, v);
      sum += 1LL * allEdges[j].first.first;
    }
  }
  dfs(1, 0, 0);
  long long ans = sum;
  int road = -1;
  for (int j = 0; j < m; j++) {
    int num = allEdges[j].first.second;
    if (usedEdges[num]) {
      if (ans >= sum - 1LL * S / c[num]) {
        ans = min(ans, sum - 1LL * S / c[num]);
        road = num;
      }
      continue;
    }
    long long curSum = sum;
    curSum += 1LL * w[num];
    curSum -= 1LL * S / c[num];
    int u = allEdges[j].second.first;
    int v = allEdges[j].second.second;
    int c = lca(u, v);
    int maxW = 0;
    maxW = max(maxW, goUp(u, c));
    maxW = max(maxW, goUp(v, c));
    curSum -= maxW;
    if (curSum <= ans) {
      ans = curSum;
      road = num;
    }
  }
  cout << ans << endl;
  w[road] -= S / c[road];
  init();
  for (int j = 0; j < m; j++) {
    int num = allEdges[j].first.second;
    if (num == road) {
      int u = allEdges[j].second.first;
      int v = allEdges[j].second.second;
      unionSets(u, v);
      usedEdges[num] = true;
      allEdges[j].first.first = w[road];
      break;
    }
  }
  sort(allEdges.begin(), allEdges.end());
  for (int j = 0; j < m; j++) {
    int u = allEdges[j].second.first;
    int v = allEdges[j].second.second;
    int num = allEdges[j].first.second;
    if (findSet(v) != findSet(u)) {
      usedEdges[num] = true;
      unionSets(u, v);
    }
  }
  for (int j = 0; j < m; j++)
    if (usedEdges[j]) printf("%d %d\n", j + 1, w[j]);
  return 0;
}
