You do not give too much context about the problem you're working on, but by looking at the code, the adjacent matrix could be much smaller: if "a" is adjacent to "b", then "b" is adjacent to "a", as you can see in these two lines of code:
adj[a].push_back( b );
adj[b].push_back( a );
This means that you could save only if "a" is adjacent to "b", because if this is the case, "b" is adjacent to "a":
adj[a].push_back( b );
Thus the size of the adj would be much smaller (instead of being an MxM matrix, it could only be a vector of size M)