#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
int tot;
long long w[maxn], edge1[maxn * 2], edge2[maxn * 2], f[maxn][4], ans[maxn * 2];
int prt[maxn], vis[maxn];
int ver[maxn * 2], Next[maxn * 2], head[maxn];
struct node {
  int x, y, op, id;
};
vector<pair<int, int> > query[maxn];
vector<int> query_id[maxn];
vector<node> q[maxn];
void Add(int x, int y, long long z1, long long z2) {
  ver[++tot] = y;
  edge1[tot] = z1;
  edge2[tot] = z2;
  Next[tot] = head[x];
  head[x] = tot;
}
template <class T>
inline void read(T &res) {
  char c;
  T flag = 1;
  while ((c = getchar()) < '0' || c > '9')
    if (c == '-') flag = -1;
  res = c - '0';
  while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
  res *= flag;
}
void dfs1(int u, int ff) {
  for (int i = head[u]; i; i = Next[i]) {
    int v = ver[i];
    if (v == ff) continue;
    dfs1(v, u);
    w[u] = min(w[u], w[v] + edge1[i] + edge2[i]);
  }
}
void dfs2(int u, int ff) {
  for (int i = head[u]; i; i = Next[i]) {
    int v = ver[i];
    if (v == ff) continue;
    w[v] = min(w[v], w[u] + edge1[i] + edge2[i]);
    dfs2(v, u);
  }
}
void dfs3(int u, int ff) {
  for (int i = head[u]; i; i = Next[i]) {
    int v = ver[i];
    if (v == ff) continue;
    f[v][0] = min(edge1[i], edge2[i] + w[u] + w[v]);
    f[v][1] = min(edge1[i] + w[u], w[v] + edge2[i]);
    f[v][2] = min(edge2[i] + w[u], w[v] + edge1[i]);
    f[v][3] = min(edge2[i], w[v] + edge1[i] + w[u]);
    dfs3(v, u);
  }
}
void getpa(int x) {
  if (prt[prt[x]] == prt[x]) return;
  getpa(prt[x]);
  int rt = prt[x];
  f[0][0] = min(f[x][0] + f[rt][0], f[x][1] + f[rt][2]);
  f[0][1] = min(f[x][1] + f[rt][3], f[x][0] + f[rt][1]);
  f[0][2] = min(f[x][2] + f[rt][0], f[x][3] + f[rt][2]);
  f[0][3] = min(f[x][3] + f[rt][3], f[x][2] + f[rt][1]);
  memcpy(f[x], f[0], sizeof(f[0]));
  prt[x] = prt[prt[x]];
}
void dfs4(int u) {
  vis[u] = 1;
  for (int i = 0; i < (int)query[u].size(); i++) {
    int v = query[u][i].first, op = query[u][i].second;
    int id = query_id[u][i];
    if (vis[v]) {
      getpa(v);
      q[prt[v]].push_back((node){u, v, op, id});
    }
  }
  for (int i = head[u]; i; i = Next[i]) {
    int v = ver[i];
    if (vis[v]) continue;
    dfs4(v);
    prt[v] = u;
  }
  for (int i = 0; i < (int)q[u].size(); i++) {
    int x = q[u][i].x, y = q[u][i].y;
    int op = q[u][i].op, id = q[u][i].id;
    int opy = op & 1, opx = (op >> 1) & 1;
    if (x == u || y == u) {
      if (x == u)
        getpa(y), ans[id] = f[y][(opy << 1) | opx];
      else
        getpa(x), ans[id] = f[x][(opx << 1) | opy];
    } else {
      getpa(x);
      getpa(y);
      ans[id] = min(f[x][opx << 1] + f[y][opy << 1],
                    f[x][(opx << 1) | 1] + f[y][(opy << 1) | 1]);
    }
  }
}
int main() {
  int n, x, y, m;
  long long w1, w2;
  read(n);
  for (int i = 1; i <= n; i++) read(w[i]), prt[i] = i;
  for (int i = 1; i < n; i++) {
    read(x);
    read(y);
    read(w1);
    read(w2);
    Add(x, y, w1, w2);
    Add(y, x, w1, w2);
  }
  dfs1(1, 0);
  dfs2(1, 0);
  dfs3(1, 0);
  read(m);
  for (int i = 1; i <= m; i++) {
    read(x);
    read(y);
    if ((x + 1) / 2 == (y + 1) / 2) {
      ans[i] = w[(y + 1) / 2];
      continue;
    }
    int op1 = x & 1 ? 0 : 1;
    int op2 = y & 1 ? 0 : 1;
    x = (x + 1) / 2;
    y = (y + 1) / 2;
    query[x].push_back(make_pair(y, (op1 << 1) | op2));
    query[y].push_back(make_pair(x, (op2 << 1) | op1));
    query_id[x].push_back(i);
    query_id[y].push_back(i);
  }
  dfs4(1);
  for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
  return 0;
}
