#include <bits/stdc++.h>
using std::min;
const int N = 300069, M = 600069;
template <typename TP>
inline void read(TP &_t) {
  TP _r = 0, _f = 1;
  char _c = getchar();
  while (_c < '0' || _c > '9') {
    if (_c == '-') _f = -1;
    _c = getchar();
  }
  while (_c >= '0' && _c <= '9') {
    _r = _r * 10 + _c - '0';
    _c = getchar();
  }
  _t = _r * _f;
}
struct sumireko {
  int to, ne;
  long long w1, w2;
} e[M];
int he[N], ecnt;
void addline(int f, int t, long long w1, long long w2) {
  e[++ecnt].to = t;
  e[ecnt].ne = he[f];
  e[ecnt].w1 = w1, e[ecnt].w2 = w2;
  he[f] = ecnt;
}
int n;
long long scost[N];
void gsc1(int x, int f) {
  for (int i = he[x], t = e[i].to; i; i = e[i].ne, t = e[i].to)
    if (t != f)
      gsc1(t, x), scost[x] = min(scost[x], scost[t] + e[i].w1 + e[i].w2);
}
void gsc2(int x, int f) {
  for (int i = he[x], t = e[i].to; i; i = e[i].ne, t = e[i].to)
    if (t != f)
      scost[t] = min(scost[t], scost[x] + e[i].w1 + e[i].w2), gsc2(t, x);
}
long long dp[N][4];
void gdp(int x, int f) {
  for (int i = he[x], t = e[i].to; i; i = e[i].ne, t = e[i].to)
    if (t != f)
      dp[t][0] = min(e[i].w1, e[i].w2 + scost[x] + scost[t]),
      dp[t][1] = min(e[i].w2 + scost[t], e[i].w1 + scost[x]),
      dp[t][2] = min(scost[x] + e[i].w2, e[i].w1 + scost[t]),
      dp[t][3] = min(e[i].w2, e[i].w1 + scost[x] + scost[t]), gdp(t, x);
}
void get_switch_cost() { gsc1(1, 0), gsc2(1, 0), gdp(1, 0); }
int fa[N];
int T;
void find(int x) {
  if (fa[x] != fa[fa[x]]) {
    find(fa[x]);
    int f = fa[x];
    dp[0][0] = dp[0][1] = dp[0][2] = dp[0][3] = 0;
    dp[0][0] = min(dp[x][0] + dp[f][0], dp[x][1] + dp[f][2]);
    dp[0][1] = min(dp[x][0] + dp[f][1], dp[x][1] + dp[f][3]);
    dp[0][2] = min(dp[x][2] + dp[f][0], dp[x][3] + dp[f][2]);
    dp[0][3] = min(dp[x][3] + dp[f][3], dp[x][2] + dp[f][1]);
    memcpy(dp[x], dp[0], sizeof(dp[x]));
    fa[x] = fa[fa[x]];
  }
}
struct ques {
  int ne, id;
} q[M << 1];
int qh[N], qcnt;
void addques(int f, int id) {
  q[++qcnt].id = id;
  q[qcnt].ne = qh[f];
  qh[f] = qcnt;
}
int qt[M << 1][2], qs[M << 1];
struct gat {
  int id, ne;
} g[M << 1];
int gh[N], gcnt;
void addgat(int f, int id) {
  g[++gcnt].id = id;
  g[gcnt].ne = gh[f];
  gh[f] = gcnt;
}
bool vv[N];
long long ans[M];
void dfs(int x, int f) {
  vv[x] = 1;
  for (int i = qh[x], t; i; i = q[i].ne) {
    t = qt[q[i].id][1];
    if (vv[t]) find(t), addgat(fa[t], q[i].id);
  }
  for (int i = he[x], t = e[i].to; i; i = e[i].ne, t = e[i].to)
    if (t != f) dfs(t, x), fa[t] = x;
  for (int i = gh[x], id; i; i = g[i].ne) {
    id = g[i].id;
    if (qt[id][1] != x) {
      int xi = qt[id][0], yi = qt[id][1];
      int xp = qs[id] >> 1, yp = qs[id] & 1;
      find(xi), find(yi);
      ans[id > T ? id - T : id] =
          min(dp[xi][xp << 1] + dp[yi][yp << 1],
              dp[xi][(xp << 1) | 1] + dp[yi][(yp << 1) | 1]);
    } else
      find(qt[id][0]), ans[id > T ? id - T : id] = dp[qt[id][0]][qs[id]];
  }
}
int xi, yi, xp, yp;
long long wi1, wi2;
signed main() {
  read(n);
  for (int i = 1; i <= n; i++) read(scost[i]), fa[i] = i;
  for (int i = 1; i < n; i++)
    read(xi), read(yi), read(wi1), read(wi2), addline(xi, yi, wi1, wi2),
        addline(yi, xi, wi1, wi2);
  get_switch_cost();
  read(T);
  for (int i = 1; i <= T; i++) {
    read(xi), read(yi);
    xp = (xi & 1) ^ 1, xi = xi + 1 >> 1;
    yp = (yi & 1) ^ 1, yi = yi + 1 >> 1;
    qt[i][0] = qt[i + T][1] = xi;
    qt[i][1] = qt[i + T][0] = yi;
    qs[i] = (xp << 1) | yp, qs[i + T] = (yp << 1) | xp;
    if (xi == yi) {
      ans[i] = xp == yp ? 0 : scost[xi];
      continue;
    }
    addques(xi, i), addques(yi, i + T);
  }
  dfs(1, 0);
  for (int i = 1; i <= T; i++) printf("%I64d\n", ans[i]);
  return 0;
}
