#include<bits/stdc++.h>usingnamespacestd;constintinf=(int)1e7;classGraph{public:intn;vector<vector<pair<int,int>>>adj;Graph(intn){this->n=n;adj.resize(n);}public:voiddijkstra(intsrc,intdest);};voidGraph::dijkstra(intsrc,intdest){vector<pair<int,int>>wave_arrival_time(n,{inf,inf});vector<int>visited_cnt(n);wave_arrival_time[src]={0,inf};// At every event, a wave reaches a vertex for the first or second time.
// Hence, we only need to run this algorithm for 2*n times.
for(inti=0;i<2*n;i++){intvertex;intcurrent_time=inf;for(intv=0;v<n;v++){if(visited_cnt[v]==0&&wave_arrival_time[v].first<current_time){current_time=wave_arrival_time[v].first;vertex=v;}if(visited_cnt[v]==1&&wave_arrival_time[v].second<current_time){current_time=wave_arrival_time[v].second;vertex=v;}}visited_cnt[vertex]++;// Emit waves for all the neighbors.
for(auto[child,weight]:adj[vertex]){autoarrival_time_of_this_wave=current_time+weight;// If this wave is faster, the wave in queue might act as the
// second wave to arrive at that vertex.
if(wave_arrival_time[child].first>arrival_time_of_this_wave){wave_arrival_time[child].second=wave_arrival_time[child].first;wave_arrival_time[child].first=arrival_time_of_this_wave;}elseif(wave_arrival_time[child].first==arrival_time_of_this_wave){// Do nothing. We've just found a different shortest path.
}else{if(wave_arrival_time[child].second>arrival_time_of_this_wave){wave_arrival_time[child].second=arrival_time_of_this_wave;}}}}if(wave_arrival_time[dest].second>=inf){cout<<"?"<<endl;}else{cout<<wave_arrival_time[dest].second<<endl;}}voidsolve(intn){intm;cin>>m;Graphg(n);for(inti=0;i<m;i++){intx,y,w;cin>>x>>y>>w;g.adj[x].push_back({y,w});g.adj[y].push_back({x,w});}intq;cin>>q;for(inti=0;i<q;i++){intsrc,dest;cin>>src>>dest;g.dijkstra(src,dest);}}intmain(){intn;inttc=1;while(cin>>n){cout<<"Set #"<<tc<<endl;solve(n);tc++;}return0;}