Java Union Find solution o(nlogn) + o(n)
```\nclass Solution {\n    private int[] f;\n   \n    private void init(int n) {\n        f = new int[n];\n        \n        for (int i = 0; i < n; i++) {\n    
```\nclass Solution {\n    private int[] f;\n   \n    private void init(int n) {\n        f = new int[n];\n        \n        for (int i = 0; i < n; i++) {\n            f[i] = i;\n        }\n    }\n    \n    private int find(int x) {\n        if (f[x] == x) {\n            return x;\n        }\n        \n        return f[x] = find(f[x]);\n    }\n    \n    private void union(int x, int y) {\n        int p = find(x);\n        int q = find(y);\n        \n        if (p != q) {\n            f[p] = q;\n        }\n    }\n    \n    class Query implements Comparable<Query> {\n        int[] qry;\n        int index;\n        \n        public Query(int[] qry, int index) {\n            this.qry = qry;\n            this.index = index;\n        }\n        \n        public int compareTo(Query q) {\n            return this.qry[2] - q.qry[2];\n        }\n    }\n    \n    public boolean[] distanceLimitedPathsExist(int n, int[][] edgeList, int[][] queries) {\n        if (edgeList == null || edgeList.length == 0 || queries == null || queries.length == 0) {\n            return new boolean[0];\n        }\n        \n        Arrays.sort(edgeList, (e1, e2) -> e1[2] - e2[2]);\n        \n        List<Query> list = new ArrayList();\n        \n        for (int i = 0; i < queries.length; i++) {\n            list.add(new Query(queries[i], i));\n        }\n        \n        Collections.sort(list);\n        \n        init(n);\n        \n        boolean[] res = new boolean[queries.length];\n        \n        int prevLimit = 0;\n        int curLimit = 0;\n        int prevIndex = 0;\n        \n        for (int i = 0; i < list.size(); i++) {\n            Query q = list.get(i);\n            \n            curLimit = q.qry[2];\n            \n            // add new edges to union\n            prevIndex = addEdges(prevIndex, prevLimit, curLimit, edgeList);\n            \n            // if two nodes has a valid path, put true\n            if (find(q.qry[0]) == find(q.qry[1])) {\n                res[q.index] = true;\n            }\n            \n            prevLimit = curLimit;\n        }\n        \n        \n        return res;\n    }\n    \n    // add new edges to uf\n    private int addEdges(int prevIndex, int prevLimit, int curLimit, int[][] edges) {\n        int i = prevIndex;\n        \n        for (i = prevIndex; i < edges.length; i++) {\n            if (edges[i][2] >= prevLimit && edges[i][2] < curLimit) {\n                union(edges[i][0], edges[i][1]);\n            }\n            else {\n                break;\n            }\n        }\n        \n        return i;\n    }\n}
[]