#include <bits/stdc++.h>
using namespace std;
const int N = 310000, M = N << 1, K = M << 1;
struct node {
  long long f[2][2];
} data[K];
int n, hd[N], noedg = 1, nxt[M], to[M], lt[K], rt[K], fa[N], top[N], size[N],
              son[N], seg[N], rev[N], cnt = 1, q, dep[N];
long long w[N], val[M][2], valNode[N][2];
template <class T>
inline void read(T &x) {
  x = 0;
  char ch = getchar(), w = 0;
  while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
  x = w ? -x : x;
  return;
}
template <class T>
inline T min(T &a, T &b) {
  return a < b ? a : b;
}
inline void addEdg(int x, int y, long long w0, long long w1) {
  nxt[++noedg] = hd[x], to[noedg] = y, hd[x] = noedg;
  val[noedg][0] = w0, val[noedg][1] = w1;
  return;
}
void dfs1(int now) {
  size[now] = 1;
  for (register int i = hd[now]; i; i = nxt[i]) {
    if (to[i] == fa[now]) continue;
    valNode[to[i]][0] = val[i][0], valNode[to[i]][1] = val[i][1],
    fa[to[i]] = now, dep[to[i]] = dep[now] + 1, dfs1(to[i]);
    size[now] += size[to[i]],
        w[now] = min(w[now], w[to[i]] + val[i][0] + val[i][1]);
    son[now] = size[son[now]] > size[to[i]] ? son[now] : to[i];
  }
  return;
}
void dfs2(int now) {
  if (son[now]) {
    seg[son[now]] = ++cnt, rev[cnt] = son[now], top[son[now]] = top[now];
    w[son[now]] =
        min(w[son[now]], w[now] + valNode[son[now]][0] + valNode[son[now]][1]),
    dfs2(son[now]);
  }
  for (register int i = hd[now]; i; i = nxt[i]) {
    if (to[i] == fa[now] || to[i] == son[now]) continue;
    seg[to[i]] = ++cnt, rev[cnt] = to[i], top[to[i]] = to[i];
    w[to[i]] = min(w[to[i]], w[now] + val[i][0] + val[i][1]), dfs2(to[i]);
  }
  return;
}
inline node update(const node &l, const node &r) {
  node k;
  k.f[0][0] = min(r.f[0][0] + l.f[0][0], r.f[0][1] + l.f[1][0]);
  k.f[0][1] = min(r.f[0][0] + l.f[0][1], r.f[0][1] + l.f[1][1]);
  k.f[1][0] = min(r.f[1][0] + l.f[0][0], r.f[1][1] + l.f[1][0]);
  k.f[1][1] = min(r.f[1][0] + l.f[0][1], r.f[1][1] + l.f[1][1]);
  return k;
}
void build(int k) {
  if (lt[k] == rt[k]) {
    int now = rev[lt[k]];
    data[k].f[0][0] =
        min(valNode[now][0], w[now] + valNode[now][1] + w[fa[now]]);
    data[k].f[0][1] =
        min(valNode[now][0] + w[fa[now]], w[now] + valNode[now][1]);
    data[k].f[1][0] =
        min(valNode[now][1] + w[fa[now]], w[now] + valNode[now][0]);
    data[k].f[1][1] =
        min(valNode[now][1], w[now] + valNode[now][0] + w[fa[now]]);
    return;
  }
  int mid = (lt[k] + rt[k]) >> 1, l = k << 1, r = (k << 1) + 1;
  lt[l] = lt[k], rt[l] = mid, lt[r] = mid + 1, rt[r] = rt[k];
  build(l), build(r), data[k] = update(data[l], data[r]);
  return;
}
inline node query(int k, int x, int y) {
  if (lt[k] >= x && rt[k] <= y) return data[k];
  int mid = (lt[k] + rt[k]) >> 1, l = k << 1, r = (k << 1) + 1;
  if (x <= mid && y > mid) return update(query(l, x, y), query(r, x, y));
  return query(x <= mid ? l : r, x, y);
}
inline long long queryTree(int x, int y) {
  long long sumx[2], sumy[2], sum[2];
  int a = x & 1, b = y & 1;
  x >>= 1, y >>= 1, sumx[a] = sumy[b] = 0, sumx[a ^ 1] = w[x],
                    sumy[b ^ 1] = w[y];
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y), swap(sumx, sumy);
    node tmp = query(1, seg[top[x]], seg[x]);
    sum[0] = min(sumx[0] + tmp.f[0][0], sumx[1] + tmp.f[1][0]);
    sum[1] = min(sumx[0] + tmp.f[0][1], sumx[1] + tmp.f[1][1]);
    sumx[0] = min(sum[0], sum[1] + w[fa[top[x]]]),
    sumx[1] = min(sum[1], sum[0] + w[fa[top[x]]]);
    x = fa[top[x]];
  }
  if (dep[x] < dep[y]) swap(x, y), swap(sumx, sumy);
  if (x != y) {
    node tmp = query(1, seg[y] + 1, seg[x]);
    sum[0] = min(sumx[0] + tmp.f[0][0], sumx[1] + tmp.f[1][0]);
    sum[1] = min(sumx[0] + tmp.f[0][1], sumx[1] + tmp.f[1][1]);
    sumx[0] = min(sum[0], sum[1] + w[y]), sumx[1] = min(sum[1], sum[0] + w[y]);
  }
  return min(min(sumx[0] + sumy[0], sumx[1] + sumy[1]),
             min(sumx[0] + sumy[1], sumx[1] + sumy[0]) + w[y]);
}
int main() {
  int x, y;
  long long w0, w1;
  read(n);
  for (register int i = 1; i <= n; ++i) read(w[i]);
  for (register int i = 1; i < n; ++i) {
    read(x), read(y), read(w0), read(w1);
    addEdg(x, y, w0, w1), addEdg(y, x, w0, w1);
  }
  lt[1] = top[1] = seg[1] = rev[1] = 1, rt[1] = n;
  dfs1(1), dfs2(1), build(1), read(q);
  while (q--) read(x), read(y), printf("%I64d\n", queryTree(x + 1, y + 1));
  return 0;
}
