Divide & Conquer
Approach
Transform the List of edges in an adjacency list, for an easier use.
Group the vertices in trees, if u can be reached from v, then u belongs to the sam
# Approach
1. Transform the List of edges in an adjacency list, for an easier use.
2. Group the vertices in trees, if `u` can be reached from `v`, then `u` belongs to the same tree as `v`. I used a `DFS` but other algorithms also work.
3. Atribute a cost to the whole tree. Because of the properties of the operand `AND`, the more we use it between diferent numbers the smaller the final number (`w1 & w2 >= w1 & w2 & w3`). So to calculate the smallest cost possible in a tree we calculate de `AND` result between all the costs.
4. The answer to each element of `query` will be `-1` if the vertices belong to diferent trees and `Tree.cost` otherwise.


# Complexity
- Time complexity: $O(N)$

- Space complexity: $O(N)$

# Code
```python3 []
class Solution:
    def minimumCost(self, n: int, edges: List[List[int]], query: List[List[int]]) -> List[int]:
        nodes = [-1] * n  # to what tree each node belongs
        trees = []      # cost inside a tree
        
        paths = [[] for i in range(n)] # egdges to list of adjencies
        
        for u, v, w in edges:
            paths[u].append([v, w])
            paths[v].append([u, w])

        t = -1
        for i in range(n):
            if nodes[i] != -1: continue
            t += 1
            stack = [i]
            nodes[i] = t
            cost = -1
            while stack:
                u = stack.pop()
                for v, w in paths[u]:
                    cost = cost & w
                    if nodes[v] == -1:
                        stack.append(v)
                        nodes[v] = t

            trees.append(cost)

        res = []
        for u, v in query:
            if nodes[u] != nodes[v]:
                res.append(-1)
            else:
                res.append(trees[nodes[u]])
        
        return res
```
['Bit Manipulation', 'Graph', 'Python3']