Using Union Find
IntuitionThe problem requires us to find the minimum cost of a walk between pairs of nodes in an undirected weighted graph. The key observation here is that the
# Intuition
The problem requires us to find the minimum cost of a walk between pairs of nodes in an undirected weighted graph. The key observation here is that the cost of any walk is determined by the bitwise AND of all edge weights encountered. Since a walk can traverse the same edge multiple times, the optimal approach involves understanding connected components and the minimum bitwise AND of any possible path.

# Approach
1. **Use Disjoint Set Union (DSU) to Identify Components**  
   - Since the problem allows traversal of edges multiple times, every node that is reachable from another should be part of the same connected component.
   - We use a DSU (Union-Find) data structure to track components.
   - Additionally, each component will store the minimum bitwise AND of all its edge weights.

2. **Building the DSU**  
   - Iterate through the edges, performing union operations.
   - While merging two sets, update the component’s bitwise AND weight by taking the AND of existing component weights and the new edge.

3. **Processing Queries**  
   - For each query $ (s, t) $, check if both nodes belong to the same connected component.
   - If they are not connected, return $ -1 $.
   - If they are connected, return the precomputed minimum bitwise AND for that component.

# Complexity
- **Time Complexity**:  
  - Constructing DSU: $$O(E \alpha(N))$$ (where $$E$$ is the number of edges and $$\alpha(N)$$ is the inverse Ackermann function).
  - Processing Queries: $$O(Q \alpha(N))$$ (where $$Q$$ is the number of queries).
  - Overall complexity: **$$O((E + Q) \alpha(N))$$**, which is near-linear in practical scenarios.

- **Space Complexity**:  
  - $$O(N)$$ for DSU storage (parent, rank, and weights).
  - $$O(Q)$$ for results.
  - Overall: **$$O(N + Q)$$**.

# Code
```python
from typing import List

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n
        self.weights = [131071] * n  # 2^17 - 1 (max 17-bit integer)

    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y, w):
        repX = self.find(x)
        repY = self.find(y)
        if repX != repY:
            if self.rank[repX] >= self.rank[repY]:
                self.parent[repY] = repX
                self.rank[repX] += self.rank[repY]
            else:
                self.parent[repX] = repY
                self.rank[repY] += self.rank[repX]
        # Update min AND weight for the component
        self.weights[repX] = self.weights[repY] = self.weights[repX] & self.weights[repY] & w

    def path_weight(self, node):
        return self.weights[self.find(node)]

class Solution:
    def minimumCost(self, n: int, edges: List[List[int]], query: List[List[int]]) -> List[int]:
        dsu = UnionFind(n)

        # Build DSU with edges
        for u, v, w in edges:
            dsu.union(u, v, w)

        res = []
        for s, t in query:
            if dsu.find(s) == dsu.find(t):
                res.append(dsu.path_weight(s))
            else:
                res.append(-1)

        return res

['Bit Manipulation', 'Union Find', 'Python3']