#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <bitset>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <utility>
#include <algorithm>
#include <random>
#include <cmath>
#include <cassert>
#include <climits>
#include <ctime>
#include <chrono>



#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx,avx2,tune=native")



#ifdef LOCAL
    #define dbg(x) cout << #x << " : " << x << endl;
#else
    #define dbg(x)
#endif

#define pb push_back
#define ppb pop_back()
#define mp make_pair
#define fi(a, b) for (int i = a; i < b; i++)
#define fj(a, b) for (int j = a; j < b; j++)
#define fk(a, b) for (int k = a; k < b; k++)
#define fi1(a, b) for (int i = a - 1; i >= b; i--)
#define fj1(a, b) for (int j = a - 1; j >= b; j--)
#define fk1(a, b) for (int k = a - 1; k >= b; k--)
#define fx(x, a) for (auto& x : a)
#define rep(i, a, b) for (int i = a; i < b; ++i)
#define rep1(i, a, b) for (int i = a - 1; i >= b; --i)
#define siz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

using namespace std;

template<typename T1, typename T2>inline void mine(T1 &x, const T2 &y) { if (y < x) x = y; }
template<typename T1, typename T2>inline void maxe(T1 &x, const T2 &y) { if (x < y) x = y; }

ostream& operator << (ostream &out, const vector<int> &b) {
    for (auto k : b) out << k << ' ';
    return out;
}

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef char ch;
typedef string str;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef vector<ch> vch;
typedef vector<vch> vvch;
typedef vector<str> vs;



const int MOD = 1000000007;
const int INF = 1000000050;
const long long BIG = (long long)2e18 + 50;
const int MX = 600010;
const double EPS = 1e-9;
#ifdef LOCAL
    const int D = 4;
#else 
    const int D = 800;
#endif
const int PW = 19;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());


int c[MX];
vi g[MX];
int eul[MX];
int tin[MX], tout[MX], timer = 0;
int up[MX][PW];

void dfs0(int v, int pr = 0) {
    up[v][0] = pr;
    for (int pw = 1; pw < PW; ++pw)
        up[v][pw] = up[up[v][pw - 1]][pw - 1]; 
    eul[timer] = v;
    tin[v] = timer++;
    fx(to, g[v]) {
        if (to != pr) {
            dfs0(to, v);
        }
    }
    eul[timer] = v;
    tout[v] = timer++;
}

bool anc(int a, int b) {
    return tin[a] <= tin[b] && tout[b] <= tout[a];
}
 
int lca(int a, int b) {
    if (anc(a, b)) return a;
    if (anc(b, a)) return b;
    for (int pw = PW - 1; pw >= 0; --pw) {
        if (!anc(up[a][pw], b)) {
            a = up[a][pw];
        }
    }
    return up[a][0];
} 
 
int bsum[D + 3];
int have[MX];


void inc(int v) {
    bsum[c[v] / D] -= have[c[v]];
    have[c[v]] ^= 1;
    bsum[c[v] / D] += have[c[v]];
}


int ask(int l, int r) {
    if (r - l < D) {
        for (int i = l; i <= r; ++i) {
            if (have[i]) {
                return i;
            }
        } 
    } else {
        while (l % D != 0) {
            if (have[l])
                return l;
            ++l;
        }
        while (r % D != D - 1) {
            if (have[r])
                return r;
            --r;
        }
        for (int i = l / D; i <= r / D; ++i) {
            if (bsum[i] > 0) {
                for (int j = i * D;; ++j) {
                    if (have[j]) {
                        return j;
                    }
                }
            }
        }
        
    }
    return -1;
}


int cl = 0;
int cr = -1;

void addl() {
    inc(eul[--cl]);
}

void addr() {
    inc(eul[++cr]);
}

void delr() {
    inc(eul[cr--]);
}

void dell() {
    inc(eul[cl++]);
}

int l[MX];
int r[MX];
int L[MX];
int R[MX];
int ans[MX];



int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);


    int n, q;
    cin >> n >> q;
    fi(0, n) {
        cin >> c[i];
    }

    fi(0, n - 1) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        g[a].pb(b);
        g[b].pb(a);
    }
    dfs0(0);
    vi reqs;
    fi(0, q) {
        reqs.pb(i);
        int a, b;
        cin >> a >> b >> l[i] >> r[i];
        --a, --b;
        if (tin[a] > tin[b])
            swap(a, b);
        if (anc(a, b)) {
            L[i] = tin[a];
            R[i] = tin[b];
        } else {
            L[i] = tout[a];
            R[i] = tin[b];
        }
    }
    sort(all(reqs), [&](int i, int j) {
        return (L[i] / D < L[j] / D) || (L[i] / D == L[j] / D && R[i] < R[j]);
    });
    fx(id, reqs) {
        while (cr < R[id])
            addr();
        while (cl > L[id])
            addl();
        while (cr > R[id])
            delr();
        while (cl < L[id])
            dell();
        int lc = lca(eul[L[id]], eul[R[id]]);
        if (lc != eul[L[id]])
            inc(lc);
        ans[id] = ask(l[id], r[id]);
        if (lc != eul[L[id]])
            inc(lc);
    }
    for (int i = 0; i < q; ++i)
        cout << ans[i] << '\n';
}
