🏆 Graph | DFS & BFS | Bitwise AND 🔥 | TC:O(N+E)✅
IntuitionApproachWe use a modified Union-Find data structure that not only tracks connectivity between nodes but also maintains the minimum possible bitwise AND
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->for any connected component, the minimum cost between any two nodes will be the bitwise AND of all edges that might be included in any possible walk. we can solve this using union find approach.


# Approach
<!-- Describe your approach to solving the problem. -->
We use a modified Union-Find data structure that not only tracks connectivity between nodes but also maintains the minimum possible bitwise AND value for each connected component.

1. Initialize each node as its own component with an AND value of -1 (all bits set to 1 in binary).
2. Process each edge by:
    - Finding the root nodes of the components containing the edge's endpoints
    - Updating the target component's AND value with the edge weight
    - If the endpoints are in different components, merge them and combine their AND values
3. For each query (s, t):
    - If s and t are the same node, return 0
    - If s and t are not in the same component, return -1
    - Otherwise, return the AND value of their component

The beauty of this approach is that as we build the graph, we simultaneously calculate the minimum possible AND value for any potential walk between nodes in the same component.
# Complexity
- Time complexity: O(N+E)
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: O(N)
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```python3 []
class Solution:
    def minimumCost(self, n: int, edges: List[List[int]], query: List[List[int]]) -> List[int]:
        parent = list(range(n))
        
        min_path_cost = [-1] * n
        
        def find_root(node: int) -> int:
            if parent[node] != node:
                parent[node] = find_root(parent[node])
            return parent[node]
        
        for source, target, weight in edges:
            source_root = find_root(source)
            target_root = find_root(target)
            
            min_path_cost[target_root] &= weight
            
            if source_root != target_root:
                min_path_cost[target_root] &= min_path_cost[source_root]
                parent[source_root] = target_root
        
        result = []
        for start, end in query:
            if start == end:
                result.append(0)
            elif find_root(start) != find_root(end):
                result.append(-1)
            else:
                result.append(min_path_cost[find_root(start)])
                
        return result
```
['Array', 'Bit Manipulation', 'Union Find', 'Graph', 'Python3']