C++ | 8 ms | Beats 98% | DSU with Path Compression 
IntuitionUse Disjoint Set Union (DSU) to determine whether two nodes belong to the same connected component. If they do, the minimum possible walk between them
# Intuition
Use Disjoint Set Union (DSU) to determine whether two nodes belong to the same connected component. If they do, the minimum possible walk between them will be the bitwise AND of all edge weights in that component because :
The bitwise AND operation (&) only decreases or remains the same when applied multiple times.

So, the minimum possible AND value between source and destination , if they belong to the same component will be the AND of all edge weights in that component.
thus , While forming each connected component, we keep track of the bitwise AND of all edge weights within that component.

also if they belong to different components walk will be -1(no edge connecting source to destination).

# Approach
1. Use DSU with Path Compression to group nodes into connected components.
2. Maintain parentAND vector along with parent vector to store the bitwise AND of all edge weights in the parent's component.
3. For each edge (u, v, w):
- Union their components and update the AND value: parentAND[parent] &= w.
- For each query (source,target):
If source == target, return 0. 
- If source and target are in different components, return -1.
- Else, return parentAND[parent] of that component.

# Complexity
- Time complexity:
- Building DSU (Union + Find for all edges):
O(E * α(n)) — where E is the number of edges, and α(n) is the inverse Ackermann function (nearly constant)

- Processing Queries:
O(Q * α(n)) — where Q is the number of queries.

- Total Time Complexity:
O((E + Q) * α(n)) 

- Space complexity:
- O(n) : For parent and parentAND vectors.

Edit : The typedef on the top is because i was thinking to store parent and AND in the same vector , like parent[i] = {parentOf_i,AND} but i found taking another vector for storing AND's simpler and also source and destination was given so for dijkstra.
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```cpp []
class Solution {
public:
    typedef pair<int,int> P;
    int find(int x , vector<int> &parent){
        if(x == parent[x]){
            return x;
        }
        return parent[x] = find(parent[x],parent);
    }
    void unionf(int x , int y , vector<int> &parent){
        parent[y] = x;
    }
    vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
        vector<int> parent(n);
        for(int i=0 ; i<n ; i++){
            parent[i] = i;
        }
        vector<int> parentAND(n,-1);
        for(auto &edge : edges){
            int u = edge[0];
            int v = edge[1];
            int w = edge[2];
            int up = find(u,parent);
            int vp = find(v,parent);
            if(up != vp){
                unionf(up,vp,parent);
                parentAND[up] &= parentAND[vp];
            }
            parentAND[up] &= w;
        }
        vector<int> result;
        for(auto &q : query){
            int u = q[0];
            int v = q[1];
            int up = find(u,parent);
            int vp = find(v,parent);
            if(u == v){
                result.push_back(0);
            }
            else if(up != vp){
                result.push_back(-1);
            }
            else{
                result.push_back(parentAND[up]);
            }
        }
        return result;
    }
};
```
['Union Find', 'C++']