#include #include #include #include using namespace std; #define PII pair const int N = 100000; set < PII > G[N]; set < PII >::iterator it; int best[N]; int p[N]; int r[N]; int dijkstra( int a, int b, int n ) { priority_queue < PII, vector, greater > que; PII tmp, xd; for ( int i = 0; i < n; ++i ) best[i] = 100; que.push( make_pair(0, a) ); best[a] = 0; while ( !que.empty() ) { tmp = que.top(); que.pop(); if ( tmp.second == b ) return tmp.first; if ( tmp.first > best[tmp.second] ) continue; for ( it=G[tmp.second].begin(); it != G[tmp.second].end(); ++it ) { xd = make_pair( max( tmp.first, (*it).second ), (*it).first ); if ( xd.first < best[xd.second] ) { que.push(xd); best[xd.second] = xd.first; } } } return -1; } int Find( int a ) { if ( a == p[a] ) return a; else return ( p[a] = Find( p[a] ) ); } void Union( int a, int b ) { a = Find( a ); b = Find( b ); if ( a == b ) return; if ( r[a] < r[b] ) p[b] = a; else p[a] = b; if ( r[a] == r[b] ) r[a]++; } int main() { int n, q, x, a, b, d; scanf( "%d%d", &n, &q ); //for ( int i = 0; i < n; ++i ) p[i] = i; while ( q-- ) { scanf( "%d", &x ); if ( x == 0 ) { scanf( "%d%d%d", &a, &b, &d ); G[a].insert( make_pair( b, d ) ); G[b].insert( make_pair( a, d ) ); //Union( a, b ); } else if ( x == 1 ) { scanf( "%d%d", &a, &b ); G[a].erase( G[a].lower_bound( make_pair( b, 0 ) ) ); G[b].erase( G[b].lower_bound( make_pair( a, 0 ) ) ); } else if ( x == 2 ) { scanf( "%d%d", &a, &b ); //for ( int i = 0; i < n; ++i ) cout << i << ": " << p[i] << " " << r[i] << endl; printf( "%d\n", dijkstra( a, b, n ) ); } } }