Problem:
Problem E:
Poor Mail Forwarding
Masa 君が住んでいる地域の郵便システムは少々変わっている。
			この地域では、各々の郵便局に対して 1 から順に連続した異なる番号がつけられており、ある郵便局に届けられた郵便物は、その郵便局からいくつかの郵便局を経由して目的の郵便局に届けられる。
			郵便物の「転送」は、特定の郵便局の間でしか行われない。 ただし、転送が行われる郵便局同士の間では、転送は双方向に行われる。
ある郵便局から宛先まで郵便物を転送するための経路が複数存在する場合は、 宛先までの距離が最短となるような経路を使用する。
			したがって、転送先はそのような最短経路における次の郵便局となる。 もし、総距離が最短となる経路が複数存在する場合は、直接の転送先となる郵便局の番号が若いほうに転送する。
ところで、この地域では深刻な労働力不足に悩まされており、郵便局間の転送を行う転送員が各郵便局に 1 人ずつしかいない。
			彼らががんばって往復しているのである。 当然、ある郵便局に郵便物が届いた時点でその郵便局に所属する転送員が出払っていた場合は、その郵便局からの転送は一時的にストップする。
彼らは自分の所属する郵便局にいるときに、その郵便局から転送されていない郵便物が存在すれば即座に出発し、転送先に届けた後は即座に戻ってくる。
			彼が転送先の郵便局から帰ってくるとき、彼の郵便局に転送される郵便物がその郵便局にあったとしても、それを運んでくることはしない (その郵便物の転送はその郵便局の転送員の仕事である)。
転送する際に、複数の郵便物が溜まっていた場合は、その郵便局に最も早く届けられた郵便物から転送を行う。 ここで、同じ時刻に届いた郵便物が複数あったときは、直接の転送先となる郵便局の番号が若いほうから転送する。 なお、同じ転送先となる郵便物があればそれも一緒に転送する。
			また、転送員の出発時刻と同じ時刻に、同じ郵便局に転送されるべき郵便物が到着した場合は、それも一緒に転送される。
			なお、彼らは全員、距離 1 の移動に時間 1 を要する。
あなたには、郵便局間の転送に関わる情報と、各郵便局に郵便物が届いた時刻のリストが与えられる。
			このとき、郵便物の動きをシミュレートし、各郵便物が宛先の郵便局に届いた時刻を報告せよ。 問題のシミュレーション中で必要となる時刻はすべて 0 以上 2
31
未満の範囲におさまると仮定してよい。
Input
入力は複数のデータセットからなり、入力の終了は 0 0 とだけ書かれた 1 行で表される。 それぞれのデータセットの書式は以下の通りである。
データセットの最初の行には、整数
n
(2 <=
n
<= 32) と
m
(1 <=
m
<= 496) が 1 文字のスペースで区切られて順に与えられる。
n
は郵便局の総数を、
m
は郵便局間の直接の転送経路の数を表す。 ある 2 つの郵便局間に 2 つ以上の直接転送経路が存在することはない。
続く
m
行に、局間の直接転送経路の情報を記した 3 つの整数が書かれる。 1 つ目と 2 つ目が転送経路の両端の郵便局の番号 (1 以上
n
以下) であり、最後の整数がその 2 局間の距離を表す。 距離は 1 以上 10000 未満である。
次の行には、処理すべき郵便物の数を表す整数
l
(1 <=
l
<= 1000) が書かれ、
			それに続く
l
行に各郵便物の詳細が書かれる。 その各行の先頭には 3 つの整数が書かれている。
			これらは順に、発送元の郵便局の番号、宛先の郵便局の番号、発送元の郵便局に届いた時刻である。 行の最後に、郵便物のラベルを表す文字列が書かれる。
			このラベルは、長さが 1 文字以上 50 文字以内であり、 アルファベット、数字、ハイフン ('-')、アンダースコア ('_') のみからなる。
			これらの各郵便物の情報は、発送元の郵便局に到着した時刻順に書かれている。 同じ時刻のときは、順番は特に規定されていない。
			また、同じラベルの郵便物や、発送元と宛先が同じ郵便物または配達するための経路が存在しない郵便物は存在しない。
入力行中の各数値や文字列の区切りは、全て 1 文字のスペースである。
Output
各々のデータセットに対して
l
行の出力を行う。
				それぞれの出力は、以下の書式に従う。
各々の郵便物について、その郵便物が届いた時刻を 1 行に出力する。その行には、最初に郵便物のラベルを出力し、次に 1 文字のスペースを挟んで、最後に郵便物が宛先の郵便局に到着した時刻を出力する。
				これらは到着時刻順に出力する。同時刻に到着した郵便物が複数ある場合は、そのラベルの ASCII コードの昇順に出力する。
各々のデータセットに対応する出力の間に、空行が 1 つ挿入される。
Sample Input
4 5
1 2 10
1 3 15
2 3 5
2 4 3
3 4 10
2
1 4 10 LoveLetter
2 3 20 Greetings
3 3
1 2 1
2 3 1
3 1 1
3
1 2 1 BusinessMailC
2 3 1 BusinessMailB
3 1 1 BusinessMailA
0 0
Output for the Sample Input
Greetings 25
LoveLetter 33

BusinessMailA 2
BusinessMailB 2
BusinessMailC 2

Submitted solutions:

code_snippet: // AOJ #2010
// Poor Mail Forwarding 2025.2.8

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 const int INF = 1000000000;
 
struct Mail {
    int src, dest;
    ll start_time;
    string label;
    ll delivered_time;
};
 
struct Event {
    ll time;
    int type;
    int post;
    int mail_id;
};
 
struct EventComparator {
    bool operator()(const Event &a, const Event &b) const {
        if(a.time != b.time) return a.time > b.time;
        if(a.type != b.type) return a.type > b.type;
        return a.post > b.post;
    }
};
 
struct WaitingMail {
    ll arrivalTime;
    int next;
    int mail_id;
};
 
struct WaitingMailComparator {
    bool operator()(const WaitingMail &a, const WaitingMail &b) const {
        if(a.arrivalTime != b.arrivalTime) return a.arrivalTime < b.arrivalTime;
        if(a.next != b.next) return a.next < b.next;
        return a.mail_id < b.mail_id;
    }
};
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    bool firstDataset = true;
    while(true){
        int n, m;
        if(!(cin >> n >> m)) break;
        if(n==0 && m==0) break;
 
        vector<vector<int>> graph(n+1, vector<int>(n+1, INF));
        for (int i = 1; i <= n; i++){
            graph[i][i] = 0;
        }
        for (int i = 0; i < m; i++){
            int u, v, w;
            cin >> u >> v >> w;
            graph[u][v] = w;
            graph[v][u] = w;
        }
 
        int l;
        cin >> l;
        vector<Mail> mails(l);
        for (int i = 0; i < l; i++){
            cin >> mails[i].src >> mails[i].dest >> mails[i].start_time >> mails[i].label;
            mails[i].delivered_time = -1;
        }
 
        vector<vector<int>> dist(n+1, vector<int>(n+1, INF));
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++){
                dist[i][j] = graph[i][j];
            }
        }
        for (int k = 1; k <= n; k++){
            for (int i = 1; i <= n; i++){
                for (int j = 1; j <= n; j++){
                    if(dist[i][k] < INF && dist[k][j] < INF)
                        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
 
        vector<vector<int>> nextHop(n+1, vector<int>(n+1, -1));
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++){
                if(i == j) continue;
                int chosen = -1;
                for (int k = 1; k <= n; k++){
                    if(k == i) continue;
                    if(graph[i][k] < INF){
                        if(dist[k][j] < INF && dist[i][j] == graph[i][k] + dist[k][j]){
                            if(chosen == -1 || k < chosen)
                                chosen = k;
                        }
                    }
                }
                nextHop[i][j] = chosen;
            }
        }
 
        vector<vector<WaitingMail>> waiting(n+1);
        vector<bool> forwarderFree(n+1, true);
 
        priority_queue<Event, vector<Event>, EventComparator> eventQueue;
        for (int i = 0; i < l; i++){
            Event ev;
            ev.time = mails[i].start_time;
            ev.type = 0;
            ev.post = mails[i].src;
            ev.mail_id = i;
            eventQueue.push(ev);
        }
 
        while(!eventQueue.empty()){
            ll currentTime = eventQueue.top().time;
            vector<Event> currentEvents;
            while(!eventQueue.empty() && eventQueue.top().time == currentTime) {
                currentEvents.push_back(eventQueue.top());
                eventQueue.pop();
            }
            sort(currentEvents.begin(), currentEvents.end(), [](const Event &a, const Event &b){
                if(a.type != b.type) return a.type < b.type;
                return a.post < b.post;
            });
 
            for(auto &ev : currentEvents) {
                if(ev.type == 0) {
                    int post = ev.post;
                    int mailId = ev.mail_id;
                    if(post == mails[mailId].dest) {
                        mails[mailId].delivered_time = currentTime;
                    } else {
                        WaitingMail wm;
                        wm.arrivalTime = currentTime;
                        wm.next = nextHop[post][ mails[mailId].dest ];
                        wm.mail_id = mailId;
                        waiting[post].push_back(wm);
                    }
                } else {
                    int post = ev.post;
                    forwarderFree[post] = true;
                }
            }
 
            for (int post = 1; post <= n; post++){
                if(forwarderFree[post] && !waiting[post].empty()){
                    sort(waiting[post].begin(), waiting[post].end(), WaitingMailComparator());
 
                    int target = waiting[post][0].next;
 
                    vector<int> batchMailIds;
                    vector<WaitingMail> remaining;
                    for(auto &wm : waiting[post]){
                        if(wm.next == target)
                            batchMailIds.push_back(wm.mail_id);
                        else
                            remaining.push_back(wm);
                    }
                    waiting[post] = remaining;
 
                    int travelTime = graph[post][target];
 
                    for(auto &mailId : batchMailIds){
                        Event newEv;
                        newEv.time = currentTime + travelTime;
                        newEv.type = 0;
                        newEv.post = target;
                        newEv.mail_id = mailId;
                        eventQueue.push(newEv);
                    }
 
                    forwarderFree[post] = false;
                    Event retEv;
                    retEv.time = currentTime + 2LL * travelTime;
                    retEv.type = 1;
                    retEv.post = post;
                    retEv.mail_id = -1;
                    eventQueue.push(retEv);
                }
            }
        }
 
        vector<int> order(l);
        for (int i = 0; i < l; i++){
            order[i] = i;
        }
        sort(order.begin(), order.end(), [&](int a, int b) {
            if(mails[a].delivered_time != mails[b].delivered_time)
                return mails[a].delivered_time < mails[b].delivered_time;
            return mails[a].label < mails[b].label;
        });
 
        if(!firstDataset) cout << endl;
        firstDataset = false;
 
        for(auto idx : order){
            cout << mails[idx].label << " " << mails[idx].delivered_time << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3524
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long double ld;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define F first
#define S second
#define sz(A) ((ll)(A.size()))
#define ALL(A) A.begin(),A.end()
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    bool cc=0;
    while(1){
        ll N,M;cin>>N>>M;
        if(!N)return 0;
        if(cc)cout<<"\n";
        cc=1;
        vvi D(N,vi(N,1e18));
        vvi E(N,vi(N,1e18));
        REP(i,M){
            ll u,v,c;cin>>u>>v>>c;u--;v--;
            E[u][v]=E[v][u]=D[u][v]=D[v][u]=c;
        }
        REP(i,N)D[i][i]=0;
        REP(i,N)REP(j,N)REP(k,N)D[j][k]=min(D[j][k],D[j][i]+D[i][k]);
        vvi F(N,vi(N,-1));
        REP(i,N)REP(j,N)if(i!=j&&D[i][j]<1e17){
            F[i][j]=0;
            while(D[i][j]!=E[i][F[i][j]]+D[F[i][j]][j])F[i][j]++;
        }
        ll _;cin>>_;
        min_priority_queue<pair<ll,pair<string,pi>>>Q;
        while(_--){
            ll u,v,t;string s;cin>>u>>v>>t>>s;u--;v--;
            Q.emplace(make_pair(t,make_pair(s,pi(u,v))));
        }
        vector<pair<ll,string>>ans;
        vector<vector<vector<pair<ll,string>>>>letters(N,vector<vector<pair<ll,string>>>(N));
        vector<bool>officer(N,1);
        while(sz(Q)){
            ll t=Q.top().F;
            string s=Q.top().S.F;
            auto[u,v]=Q.top().S.S;
            Q.pop();
            if(s=="|"){
                pi p=pi(1e18,0);
                REP(v,N)for(auto[nt,ns]:letters[u][v])p=min(p,pi(nt,F[u][v]));
                if(p.F>1e17)officer[u]=1;
                else{
                    REP(v,N)if(F[u][v]==p.S){
                        for(auto[nt,ns]:letters[u][v])Q.emplace(make_pair(t+E[u][p.S],make_pair(ns,pi(p.S,v))));
                        letters[u][v].clear();
                    }
                    Q.emplace(make_pair(t+2*E[u][p.S],make_pair("|",pi(u,u))));
                }
            }
            else{
                if(u==v)ans.emplace_back(make_pair(t,s));
                else{
                    if(officer[u]){
                        officer[u]=0;
                        Q.emplace(make_pair(t,make_pair("|",pi(u,u))));
                    }
                    letters[u][v].emplace_back(make_pair(t,s));
                }
            }
        }
        REP(i,sz(ans))cout<<ans[i].S<<" "<<ans[i].F<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3996
final_rank: 10

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
using namespace std;
typedef long long int LL;
typedef pair<LL,LL> P;
typedef pair<LL,int> LP;
const LL INF=1LL<<40;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}

vector<vector<LL>> dis,path,to;
vector<tuple<LL,LL,LL,string>> mail;
typedef tuple<LL,LL,LL> T;
priority_queue<T,vector<T>,greater<T>> q1;
bool emp[50];
bool used[50];

int main(){
    LL n,m,q;
    int i,j,k;
    LL a,b,c;
    LL p;
    string sa;
    int cnt=0;
    while(cin>>n>>m){
        if(!n)break;
        if(cnt)cout<<endl;
        cnt++;
        dis.assign(n,vector<LL>(n,INF));
        path.assign(n,vector<LL>(n,INF));
        to.assign(n,vector<LL>(n,-1));
        for(i=0;i<m;i++){
            cin>>a>>b>>c;
            a--,b--;
            dis[a][b]=c;
            dis[b][a]=c;
            path[a][b]=c;
            path[b][a]=c;
        }
        for(i=0;i<n;i++){
            dis[i][i]=0;
        }
        for(k=0;k<n;k++){
            for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                }
            }
        }
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                for(k=0;k<n;k++){
                    if(path[i][k]<INF && dis[i][j]==path[i][k]+dis[k][j])break;
                }
                to[i][j]=k;
            }
        }

        mail.clear();
        cin>>q;
        for(i=0;i<q;i++){
            cin>>a>>b>>c>>sa;
            a--,b--;
            mail.push_back(make_tuple(a,b,c,sa));
            q1.push(make_tuple(c,a,i));
        }
        memset(emp,false,sizeof(emp));
        memset(used,false,sizeof(used));
        vector<P> st[40][40];
        vector<pair<LL,string>> vs;
        while(!q1.empty()){
            p=get<0>(q1.top());
            while(!q1.empty() && p==get<0>(q1.top())){
                tie(ignore,a,b)=q1.top(),q1.pop();
                if(b==-1){
                    emp[a]=false,used[a]=true;
                    continue;
                }
                c=get<1>(mail[b]);
                if(a==c){
                    vs.push_back(make_pair(p,get<3>(mail[b])));
                    continue;
                }
                st[a][to[a][c]].push_back(make_pair(p,b));
                used[a]=true;
            }
            for(i=0;i<n;i++){
                if(!used[i] || emp[i])continue;
                used[i]=false;
                a=INF,k=-1;
                for(j=0;j<n;j++){
                    if(st[i][j].empty())continue;
                    if(a>st[i][j][0].first){
                        a=st[i][j][0].first,k=j;
                    }
                }
                if(k==-1)continue;
                for(auto node:st[i][k]){
                    int id=node.second;
                    q1.push(make_tuple(p+path[i][k],k,id));
                }
                st[i][k].clear();
                emp[i]=true;
                q1.push(make_tuple(p+path[i][k]*2,i,-1));
            }
        }
        sort(vs.begin(),vs.end());
        for(auto node:vs){
            cout<<node.second<<" "<<node.first<<endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3340
final_rank: 4

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

//0...荷物届く
//1...人が帰る
struct ste {
	int tm,typ, id;
};
bool operator<(const ste& a, const ste& b) {
	if (a.tm != b.tm)return a.tm > b.tm;
	if (a.typ != b.typ)return a.typ > b.typ;
	else return a.id > b.id;
}
int n, m;
int dist[32][32];
struct edge {
	int to, cost;
};
void solve() {
	rep(i, n)rep(j, n) {
		if (i == j)dist[i][j] = 0;
		else dist[i][j] = mod;
	}
	vector<vector<edge>> G(n);
	rep(i, m) {
		int a, b; cin >> a >> b;
		a--; b--;
		int c; cin >> c;
		dist[a][b] = dist[b][a] = min(dist[a][b],c);
		G[a].push_back({ b,c });
		G[b].push_back({ a,c });
	}
	rep(k, n)rep(i, n)rep(j, n) {
		dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
	}
	int l; cin >> l; vector<queue<int>> tos(l);
	
	//配達員の存在
	vector<bool> exi(n, true);
	//荷物の存在状況
	vector<vector<P>> bags(n);

	priority_queue<ste> q;
	vector<string> names(l);
	//荷物の前の位置
	vector<int> pre(l);
	rep(i, l) {
		int a, b, t; string s;
		cin >> a >> b >> t >> s;
		names[i] = s;
		a--; b--;
		int d = dist[a][b];
		int cur = a;
		tos[i].push(cur);
		//cout << "?! " << cur << "\n";
		while (cur != b) {
			int chk = mod;
			for (edge e : G[cur]) {
				if (e.cost + dist[e.to][b] == d) {
					chk = min(chk, e.to);
				}
			}
			d -= dist[cur][chk];
			cur = chk;
			tos[i].push(cur);
			//cout << "?! " << cur << "\n";
		}
		q.push({ t,0,i });
		pre[i] = -1;
	}
	vector<string> ans;
	vector<int> anstime;
	while (!q.empty()) {
		//cout << "start\n";
		int t = q.top().tm;
		vector<string> curans;
		while (q.size() && q.top().tm == t) {
			ste s = q.top(); q.pop();
			//cout << "? "<<s.tm << " " << s.typ << " " << s.id << "\n";
			if (s.typ == 0) {
				int id = s.id;
				int cur = tos[id].front();
				int pr = pre[id];
				//cout << "shogeki" << cur << " " << pr << "\n";
				if (pr >= 0) {
					//cout << "nande " << pr << "\n";
					q.push({ t + dist[cur][pr],1,pr });
				}
				if (tos[id].size() == 1) {
					curans.push_back(names[id]);
					continue;
				}
				bags[cur].push_back({ t,id });
				tos[id].pop();
				
			}
			else {
				//cout << "??????? " << s.id << "\n";
				exi[s.id] = true;
			}
		}
		sort(all(curans));
		for (string s : curans) {
			ans.push_back(s);
			anstime.push_back(t);
		}

		//cout << "!!! " << exi[1] << " " << bags[1].size() << "\n";
		rep(i, n) {
			if (exi[i] && bags[i].size()) {
				int mi = bags[i][0].first;
				int to = mod;
				rep(j, bags[i].size()) {
					if (bags[i][j].first == mi) {
						int id = bags[i][j].second;
						to = min(to, tos[id].front());
					}
				}
				//cout << "wow " << i << " " << to << "\n";
				int len = bags[i].size();
				vector<P> nex;
				rep(j,len) {
					int id = bags[i][j].second;
					if (tos[id].front() == to) {
						q.push({ t + dist[i][to],0,id });
						pre[id] = i;
					}
					else nex.push_back(bags[i][j]);
				}
				swap(bags[i], nex);
				exi[i] = false;
			}
		}
		//cout << pre[1] << " " << bags[1].size() << "\n";
		//cout << pre[0] << " " << pre[1] << "\n";
	}
	rep(i, ans.size())cout << ans[i] <<" "<<anstime[i]<< endl;
	
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(8);
	//init_f(); 
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	bool f = true;
	while (cin >> n >> m, n) {
		if (!f)cout << endl;
		else f = false;
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3860
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
using namespace std;
const int inf = 1e9;

struct transfer{
    int from, to, direct_to, time;
    string name;
    transfer(int from, int to, int direct_to, int time, string name):
        from(from), to(to), direct_to(direct_to), time(time), name(name){}
    transfer(){}
    bool operator <(const transfer &a) const{
        return (time!=a.time)? time<a.time: direct_to<a.direct_to;
    }
};

int main(){
    bool is_first_dataset = true;
    while(1){
        int n,m;
        cin >> n >> m;
        if(n == 0) break;
        if(is_first_dataset){
            is_first_dataset = false;
        }else{
            cout << endl;
        }

        vector<vector<int>> dist_0(n, vector<int>(n, inf));
        for(int i=0; i<n; i++){
            dist_0[i][i] = 0;
        }
        for(int i=0; i<m; i++){
            int a,b,c;
            cin >> a >> b >> c;
            a--; b--;
            dist_0[a][b] = dist_0[b][a] = c;
        }
        auto dist = dist_0;
        for(int k=0; k<n; k++){
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);
                }
            }
        }
        vector<vector<int>> direct(n, vector<int>(n));
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                if(i == j){
                    direct[i][j] = i;
                    continue;
                }
                for(int k=0; k<n; k++){
                    if(k == i) continue;
                    if(dist_0[i][k] +dist[k][j] == dist[i][j]){
                        direct[i][j] = k;
                        break;
                    }
                }
            }
        }

        int q;
        cin >> q;
        vector<vector<transfer>> tr(n);
        priority_queue<int> event;
        for(int i=0; i<q; i++){
            int from,to,time;
            string name;
            cin >> from >> to >> time >> name;
            from--; to--;
            tr[from].emplace_back(from, to, direct[from][to], time, name);
            event.push(-time);
        }

        for(int i=0; i<n; i++){
            sort(tr[i].begin(), tr[i].end());
        }
        vector<int> rettime(n, 0);
        event.push(0);

        vector<pair<int,string>> ans;
        while(!event.empty()){
            int t = event.top();
            while(!event.empty() and event.top() == t){
                event.pop();
            }
            t = -t;
            for(int i=0; i<n; i++){
                if(t < rettime[i]) continue;
                if(tr[i].empty() or tr[i][0].time > t) continue;
                int dto = tr[i][0].direct_to;
                rettime[i] = t +2*dist[i][dto];
                event.push(-rettime[i]);
                event.push(-(t +dist[i][dto]));
                for(int j=(int)tr[i].size()-1; j>=0; j--){
                    if(tr[i][j].direct_to == dto and t >= tr[i][j].time){
                        if(tr[i][j].to == tr[i][j].direct_to){
                            ans.emplace_back(t +dist[i][dto], tr[i][j].name);
                        }else{
                            int to = tr[i][j].to;
                            tr[dto].emplace_back(dto, to, direct[dto][to], t+dist[i][dto], tr[i][j].name);
                        }
                        tr[i].erase(tr[i].begin() +j);
                    }                    
                }
                sort(tr[dto].begin(), tr[dto].end());
            }
        }
        sort(ans.begin(), ans.end());
        for(auto p: ans){
            cout << p.second << " " << p.first << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3344
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long double EPS = 1e-10;
const int INF = 1e9;
const long double PI = acos(-1.0L);
//const ll mod = 1000000007;

struct query {
    int type;
    int pos;
    string name;
};

bool operator< (query a, query b) {
    return a.type < b.type;
}

int N, M;
int dist[32][32];
int Next[32][32];
int Connected[32][32];
bool Exist[32];
vector<vector<string>> QUEUE[32];
map<int, vector<query>> mp;
map<string, int> ans;
map<string, int> destination;
typedef pair<int, query> iq;
typedef pair<int, string> is;

void Add(query q) {
    //cerr << "Add: " << q.pos << " " << q.name << endl;
    int to = Next[q.pos][destination[q.name]];
    for(int i = 0; i < QUEUE[q.pos].size(); i++) {
        if(to == Next[q.pos][destination[QUEUE[q.pos][i][0]]]) {
            QUEUE[q.pos][i].push_back(q.name);
            return;
        }
    }
    QUEUE[q.pos].push_back({q.name});
}

void Serve(int pos, int timer) {
    if(!Exist[pos]) return;
    if(QUEUE[pos].empty()) return;
    for(string tmp : QUEUE[pos][0]) {
        int to = Next[pos][destination[tmp]];
        int newtimer = timer + dist[pos][to];
        query q;
        q.type = 1;
        q.name = tmp;
        q.pos = to;
        //cerr << "Serve: from " << pos << " to " << to << " " << tmp << " when " << newtimer << endl;
        mp[newtimer].push_back(q);
        q.type = 0;
        q.name = "";
        q.pos = pos;
        newtimer += dist[pos][to];
        mp[newtimer].push_back(q);
    }
    QUEUE[pos].erase(QUEUE[pos].begin());
    Exist[pos] = false;
}

void solve() {
    mp.clear();
    ans.clear();
    destination.clear();
    for(int i = 0; i < N; i++) {
        Exist[i] = true;
        QUEUE[i].clear();
    }
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            dist[i][j] = INF;
            Connected[i][j] = 1e9;
        }
        dist[i][i] = 0;
        Next[i][i] = -1;
        Connected[i][i] = 0;
    }
    for(int i = 0; i < M; i++) {
        int a, b, l;
        cin >> a >> b >> l;
        a--;
        b--;
        dist[a][b] = l;
        dist[b][a] = l;
        Connected[a][b] = l;
        Connected[b][a] = l;
    }
    int Q;
    cin >> Q;
    while(Q--) {
        int a, b, t;
        string S;
        cin >> a >> b >> t >> S;
        a--;
        b--;
        destination[S] = b;
        query q;
        q.pos = a;
        q.name = S;
        q.type = 1;
        mp[t].push_back(q);
    }
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            for(int k = 0; k < N; k++) {
                chmin(dist[j][k], dist[j][i] + dist[i][k]);
            }
        }
    }
    for(int from = 0; from < N; from++) {
        for(int to = 0; to < N; to++) {
            if(from == to) continue;
            int tmp = -1;
            for(int i = 0; i < N; i++) {
                if(Connected[from][i] == 1e9) continue;
                if(i == from) continue;
                if(tmp == -1 or Connected[from][tmp] + dist[tmp][to] > Connected[from][i] + dist[i][to]) 
                tmp = i;
            }
            Next[from][to] = tmp;
        }
    }
    for(auto itr = mp.begin(); itr != mp.end(); itr++) {
        auto tmp = *itr;
        //cerr << "------" << tmp.first << "------" << endl;
        vector<iq> vec;
        for(auto q : tmp.second) {
            //cerr << q.type << " " << q.name << " " << q.pos << endl;
            if(q.type == 0) {
                //cerr << "clerk of " << q.pos << " comes back" << endl;
                Exist[q.pos] = true;
            }
            if(q.type == 1) {
                //cerr << q.name << " " << destination[q.name] << endl;
                if(destination[q.name] == q.pos) {
                    ans[q.name] = tmp.first;
                    continue;
                }
                vec.push_back({Next[q.pos][destination[q.name]], q});
            }
        }
        sort(vec.begin(), vec.end());
        for(auto tmp : vec) {
            Add(tmp.second);
        }
        for(int i = 0; i < N; i++) {
            Serve(i, tmp.first);
        }
    }
    vector<is> ANS;
    for(auto tmp : ans) {
        ANS.push_back({tmp.second, tmp.first});
    }
    sort(ANS.begin(), ANS.end());
    for(auto tmp : ANS) {
        cout << tmp.second << " " << tmp.first << endl;
    }
    /*
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            cerr << Next[i][j] << " ";
        }
        cerr << endl;
    }
    */
}

int main() {
    //cout.precision(10);
    cin.tie(0);
    ios::sync_with_stdio(false);
    int testcase = 0;
    while(cin >> N >> M) {
        if(N == 0) break;
        if(testcase != 0) cout << endl;
        testcase++;
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4016
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

using pii = pair<int, int>;
constexpr int inf = numeric_limits<int>::max();

struct edge {
    int from, to, cost;
    edge(int f, int t, int c) : from(f), to(t), cost(c) {}
};

using edges = vector<edge>;
using graph = vector<edges>;

void add_edge(graph& g, int from, int to, int cost) {
    g[from].emplace_back(from, to, cost);
    g[to].emplace_back(to, from, cost);
}

vector<int> dijkstra(graph const& g, int s) {
    const int n = g.size();
    vector<int> dist(n, inf / 2);
    dist[s] = 0;
    priority_queue<pii, vector<pii>, greater<>> que;
    que.emplace(0, s);
    while(!que.empty()) {
        int cur_d, v; tie(cur_d, v) = que.top();
        que.pop();
        if(cur_d > dist[v]) continue;
        for(auto const& e : g[v]) {
            if(dist[e.to] > dist[v] + e.cost) {
                dist[e.to] = dist[v] + e.cost;
                que.emplace(dist[e.to], e.to);
            }
        }
    }
    return dist;
}

edge calc_next_v(graph const& g, int s, int t) {
    const auto from_s = dijkstra(g, s);
    const auto from_t = dijkstra(g, t);
    edge res{s, inf, -1};
    for(auto const& e : g[s]) {
        if(from_s[e.from] + e.cost + from_t[e.to] == from_s[t] && res.to > e.to) {
            res = e;
        }
    }
    return res;
}

struct packet {
    string name;
    int to;
    packet(string n, int t) : name(n), to(t) {}
};

struct event {
    int from, time;
    packet pkt;
    event(int f, int t, packet p) : from(f), time(t), pkt(p) {}
    bool operator>(const event& e) const {
        return time > e.time;
    }
};

struct postman {
    int idx, cur, dst, remain, ecost;
    vector<packet> ps;
    postman(int i) : idx(i), cur(i), dst(-1), remain(0), ecost(-1) {}

    void move(int cur_t, int t, vector<vector<event>>& tasks, vector<pair<int, string>>& ans) {
        while(t != 0 && dst != -1) {
            const int use = min(remain, t);
            remain -= use, t -= use;
            cur_t += use;
            if(remain == 0) {
                cur = dst;
                dst = -1;
                for(auto const& p : ps) {
                    if(p.to == cur) {
                        ans.emplace_back(cur_t, p.name);
                    } else {
                        tasks[cur].emplace_back(cur, cur_t, p);
                    }
                }
                ps.clear();
                if(cur != idx) { // return to original
                    dst = idx;
                    remain = ecost;
                }
            }
        }
        assert(t >= 0);
    }
};

int main() {
    int n, m;
    bool first = true;
    while(cin >> n >> m, n) {
        if(!first) cout << '\n';
        first = false;

        graph g(n);
        for(int i = 0; i < m; ++i) {
            int f, t, cost; cin >> f >> t >> cost;
            f--, t--;
            add_edge(g, f, t, cost);
        }
        vector<vector<edge>> sg(n);
        for(int s = 0; s < n; ++s) {
            for(int t = 0; t < n; ++t) {
                sg[s].push_back(calc_next_v(g, s, t));
            }
        }
        int l; cin >> l;
        vector<event> ev;
        for(int i = 0; i < l; ++i) {
            int s, t, time; cin >> s >> t >> time;
            string name; cin >> name;
            s--, t--;
            ev.emplace_back(s, time, packet{name, t});
        }
        sort(begin(ev), end(ev), greater<>{});

        vector<postman> man;
        for(int i = 0; i < n; ++i) {
            man.emplace_back(i);
        }
        int cur_t = 0;
        vector<vector<event>> tasks(n);
        vector<pair<int, string>> ans;
        auto is_finished = [&] () {
            if(!ev.empty()) return false;
            for(auto const& t : tasks) {
                if(!t.empty()) return false;
            }
            for(auto const& p : man) {
                if(p.dst != -1) return false;
            }
            return true;
        };
        while(!is_finished()) {
            //cout << "cur_t: " << cur_t << endl;
            // determine next time
            int nxt_t = inf;
            for(auto const& p : man) {
                if(p.dst == -1) continue;
                nxt_t = min(nxt_t, cur_t + p.remain);
            }
            if(!ev.empty()) nxt_t = min(nxt_t, ev.back().time);
            //cout << "ev.sz: " << ev.size() << endl;
            //cout << "elapsed: " << nxt_t - cur_t << endl;

            // first, resolve task
            while(!ev.empty() && ev.back().time == nxt_t) {
                tasks[ev.back().from].push_back(ev.back());
                ev.pop_back();
            }

            // second, resolve postman
            for(int i = 0; i < n; ++i) {
                man[i].move(cur_t, nxt_t - cur_t, tasks, ans);
            }
            for(int i = 0; i < n; ++i) {
                // returned to original office
                if(man[i].dst != -1) continue;
                if(!tasks[i].empty()) {
                    vector<event> nxt_ts;
                    int min_time = inf, min_to = inf, ecost = -1;
                    for(auto const& t : tasks[i]) {
                        if(make_pair(min_time, min_to) > make_pair(t.time, sg[i][t.pkt.to].to)) {
                            min_time = t.time;
                            min_to = sg[i][t.pkt.to].to;
                            ecost = sg[i][t.pkt.to].cost;
                        }
                    }
                    assert(ecost >= 1);
                    man[i].remain = man[i].ecost = ecost;
                    man[i].dst = min_to;
                    for(auto const& t : tasks[i]) {
                        if(sg[i][t.pkt.to].to == min_to) {
                            man[i].ps.push_back(t.pkt);
                        } else {
                            nxt_ts.push_back(t);
                        }
                    }
                    tasks[i] = move(nxt_ts);
                }
            }
            cur_t = nxt_t;
        }

        //cout << "finished: " << endl;
        sort(begin(ans), end(ans));
        for(auto const& p : ans) {
            cout << p.second << " " << p.first << '\n';
        }
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3384
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
Int e[40][40],g[40][40];
signed main(){
  Int n,m;
  Int first=0;
  while(cin>>n>>m,n||m){
    if(exchange(first,1)) cout<<endl;
    memset(e,-1,sizeof(e));
    for(Int i=0;i<m;i++){
      Int a,b,c;
      cin>>a>>b>>c;
      a--;b--;
      e[a][b]=e[b][a]=c;
    }
    
    Int l;
    cin>>l;
    vector<Int> xs(l),ys(l),ts(l);
    vector<string> ss(l);
    for(Int i=0;i<l;i++){
      cin>>xs[i]>>ys[i]>>ts[i]>>ss[i];
      xs[i]--;
      ys[i]--;
    }

    const Int INF = 1e15;
    for(Int i=0;i<40;i++)
      for(Int j=0;j<40;j++)
        g[i][j]=~e[i][j]?e[i][j]:INF;
    
    for(Int i=0;i<40;i++) g[i][i]=0;

    for(Int k=0;k<n;k++)
      for(Int i=0;i<n;i++)
        for(Int j=0;j<n;j++)
          chmin(g[i][j],g[i][k]+g[k][j]);

    using S = pair<Int, string>;    
    vector<S> ans;
    
    using T = tuple<Int, Int, Int, Int>;
    priority_queue<T, vector<T>, greater<T> > pq;
    for(Int i=0;i<l;i++) pq.emplace(ts[i],xs[i],ts[i],i);

    vector<Int> ws(n,0);
    while(!pq.empty()){
      T pt=pq.top();
      Int t,v,a,k;
      tie(t,v,a,k)=pt;
      if(t<ws[v]){
        pq.pop();
        pq.emplace(ws[v],v,a,k);
        continue;
      }
      
      vector<Int> idxs,arrs;
      while(!pq.empty()){
        T qt=pq.top();
        Int tt,vv,aa,idx;
        tie(tt,vv,aa,idx)=qt;
        if(t!=tt||v!=vv) break;
        pq.pop();
        idxs.emplace_back(idx);
        arrs.emplace_back(aa);
      }
      ws[v]=t;
      
      Int arr=arrs[0];
      vector<Int> nxts(idxs.size());
      for(Int i=0;i<(Int)idxs.size();i++){
        chmin(arr,arrs[i]);
        Int y=ys[idxs[i]];
        Int u=-1;
        for(Int j=0;j<n;j++){
          if(e[v][j]<0) continue;
          if(e[v][j]+g[j][y]==g[v][y]){
            u=j;
            break;
          }
        }
        nxts[i]=u;
      }
      
      Int nxt=n;
      for(Int i=0;i<(Int)idxs.size();i++)
        if(arrs[i]==arr) chmin(nxt,nxts[i]);

      ws[v]+=e[v][nxt]*2;
      for(Int i=0;i<(Int)idxs.size();i++){
        if(nxts[i]==nxt){
          if(ys[idxs[i]]==nxt){
            ans.emplace_back(t+e[v][nxt],ss[idxs[i]]);
          }else{
            pq.emplace(t+e[v][nxt],nxt,t+e[v][nxt],idxs[i]);
          }
        }else{
          pq.emplace(ws[v],v,arrs[i],idxs[i]);
        }
      }
    }
    
    sort(ans.begin(),ans.end());
    for(auto p:ans) cout<<p.second<<" "<<p.first<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3312
final_rank: 3

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
//#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define BIG_NUM INT_MAX
#define NUM 32
#define SIZE 1000

enum Type{
	Human,
	Letter,
};

struct Edge{
	Edge(int arg_to,int arg_dist){
		to = arg_to;
		dist = arg_dist;
	}
	int to,dist;
};

struct Porter{
	int home_office;
	vector<int> Bag;
};

struct Item{
	string name;
	int final_office;
};

struct Data{
	Data(int arg_item_id,int arg_arrive_time,int arg_next_loc){
		item_id = arg_item_id;
		arrive_time = arg_arrive_time;
		next_loc = arg_next_loc;
	}
	bool operator<(const struct Data& arg) const{
		if(arrive_time != arg.arrive_time){
			return arrive_time < arg.arrive_time;
		}else{
			return next_loc < arg.next_loc;
		}
	}
	int item_id,arrive_time,next_loc;
};

struct Office{
	bool can_port;
	int pre_time; //ポーターが前回帰ってきた時刻
	vector<Data> V;
};

struct Info{
	Info(Type arg_type,int arg_time,int arg_id,int arg_arrive_loc){
		type = arg_type;
		time = arg_time;
		id = arg_id;
		arrive_loc = arg_arrive_loc;
	}
	bool operator<(const struct Info &arg) const{ //時刻の昇順(PQ)
		return time > arg.time;
	}
	Type type;
	int time,id,arrive_loc;
};

struct FINISH{
	FINISH(string arg_name,int arg_time){
		name = arg_name;
		time = arg_time;
	}
	bool operator<(const struct FINISH &arg) const{
		if(time != arg.time){ //時刻または名前の昇順(PQ)
			return time > arg.time;
		}else{
			return name > arg.name;
		}
	}
	string name;
	int time;
};

int N,E;
int min_dist[NUM][NUM];
int next_table[NUM][NUM];
int num_item;
vector<Edge> G[NUM];
Office office[NUM];
Porter porter[NUM];
Item item[SIZE];
priority_queue<Info> EVENT;
priority_queue<FINISH> ANS;
int case_num;


//転送先へ最短経路で届ける際の、次の中継点を求める
int find_next(int current,int goal){

	int minimum = min_dist[current][goal],min_index = BIG_NUM,mid;

	for(int i = 0; i < G[current].size(); i++){
		mid = G[current][i].to;
		if(G[current][i].dist+min_dist[mid][goal] != minimum)continue;

		min_index = min(min_index,mid);
	}

	return min_index;
}

//bool DEBUG = false;

void func(){

	if(case_num > 0)printf("\n");

	for(int i = 0; i < N; i++){
		G[i].clear();
		office[i].V.clear();
		porter[i].Bag.clear();
	}

	while(!EVENT.empty())EVENT.pop();

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			if(i != k){
				min_dist[i][k] = BIG_NUM;
			}else{
				min_dist[i][k] = 0;
			}
		}
	}

	int from,to,dist;

	for(int loop = 0; loop < E; loop++){

		scanf("%d %d %d",&from,&to,&dist);
		from--;
		to--;

		min_dist[from][to] = dist;
		min_dist[to][from] = dist;

		G[from].push_back(Edge(to,dist));
		G[to].push_back(Edge(from,dist));
	}

	//全点対間最短経路
	for(int mid = 0; mid < N; mid++){
		for(int start = 0; start < N; start++){
			if(min_dist[start][mid] == BIG_NUM)continue;
			for(int goal = 0; goal < N; goal++){
				if(min_dist[mid][goal] == BIG_NUM)continue;
				min_dist[start][goal] = min(min_dist[start][goal],min_dist[start][mid]+min_dist[mid][goal]);
			}
		}
	}

	for(int a = 0; a < N; a++){
		for(int b = 0; b < N; b++){
			if(a == b)continue;
			next_table[a][b] = find_next(a,b);
		}
	}

	scanf("%d",&num_item);

	int tmp_time;

	for(int i = 0; i < num_item; i++){

		cin >> from >> to >> tmp_time >> item[i].name;

		from--;
		to--;

		item[i].final_office = to;

		EVENT.push(Info(Letter,tmp_time,i,from));
	}

	//配達人を、自分の本拠地に配置する
	for(int i = 0; i < N; i++){

		porter[i].home_office = i;

		office[i].can_port = true;
		office[i].pre_time = 0;
	}

	int current_time,tmp_id,tmp_loc,letter_id,tmp_next_loc;

	int num_finish = 0;
	vector<Data> work;

	while(!EVENT.empty()){

		current_time = EVENT.top().time;

		//同時刻のイベントを同時に処理する
		while(EVENT.empty() == false && EVENT.top().time == current_time){

			if(EVENT.top().type == Human){

				tmp_id = EVENT.top().id;

				if(porter[tmp_id].home_office == EVENT.top().arrive_loc){ //本拠地に戻った場合

					office[porter[tmp_id].home_office].can_port = true;
					office[porter[tmp_id].home_office].pre_time = EVENT.top().time; //戻った時刻を記録

				}else{ //別のofficeに到着した場合[★荷物を渡す★]

					tmp_loc = EVENT.top().arrive_loc;
					tmp_time = EVENT.top().time;

					for(int i = 0; i < porter[tmp_id].Bag.size(); i++){

						letter_id = porter[tmp_id].Bag[i];

						if(item[letter_id].final_office == tmp_loc){ //★最終目的地に届いた場合

							num_finish++;

							ANS.push(FINISH(item[letter_id].name,tmp_time));
							if(num_finish == num_item)break;

							continue;
						}

						//次の転送先を先に計算しておく
						tmp_next_loc = next_table[tmp_loc][item[letter_id].final_office];
						if(tmp_next_loc == tmp_loc){
							printf("BUGG!!\n");
							return;
						}

						office[tmp_loc].V.push_back(Data(letter_id,tmp_time,tmp_next_loc));
					}
					porter[tmp_id].Bag.clear();
					if(num_finish == num_item)break;

					//★porterが本拠地に戻る★
					EVENT.push(Info(Human,tmp_time+min_dist[tmp_loc][porter[tmp_id].home_office],tmp_id,porter[tmp_id].home_office));
				}

			}else{

				letter_id = EVENT.top().id;
				tmp_loc = EVENT.top().arrive_loc;
				tmp_time = EVENT.top().time;

				//転送先を計算
				tmp_next_loc = next_table[tmp_loc][item[letter_id].final_office];
				office[tmp_loc].V.push_back(Data(letter_id,tmp_time,tmp_next_loc));
			}

			EVENT.pop();
		}
		if(num_finish == num_item)break;

		//home_officeにいるporterがいたら、Letterを持ち出す

		int min_time,min_next;

		for(int i = 0; i < N; i++){
			if(office[i].can_port == false || office[i].V.size() == 0)continue;

			/*
			 *最も早く、officeに届いた郵便物を探す。
			 *複数あるなら、届先の番号が若い順
			 */

			sort(office[i].V.begin(),office[i].V.end());

			min_time = office[i].V[0].arrive_time; //★到着が早い順にpushされているはず★
			min_next = office[i].V[0].next_loc;

			for(int k = 1; k < office[i].V.size(); k++){
				if(min_time < office[i].V[k].arrive_time)break;
				if(min_time == office[i].V[k].arrive_time){
					min_next = min(min_next,office[i].V[k].next_loc);
				}
			}

			//届先がmin_nextのletterを、porterに持たせる。porterは出発させる
			for(int k = 0; k < office[i].V.size(); k++){

				if(office[i].V[k].next_loc == min_next){ //ポーターのバッグに詰める

					porter[i].Bag.push_back(office[i].V[k].item_id);

				}else{ //今回は運ばない

					work.push_back(office[i].V[k]);
				}
			}
			office[i].V.clear();

			if(work.size() > 0){

				for(int k = 0; k < work.size(); k++){
					office[i].V.push_back(work[k]);
				}
				work.clear();
			}
			//ポーターの移動
			office[i].can_port = false;

			if(office[i].pre_time <= min_time){ //★porterが待つ場合

				EVENT.push(Info(Human,min_time+min_dist[i][min_next],i,min_next));

			}else{ //★porterが待たない場合

				EVENT.push(Info(Human,office[i].pre_time+min_dist[i][min_next],i,min_next));
			}
		}
	}

	while(!ANS.empty()){

		printf("%s %d\n",ANS.top().name.c_str(),ANS.top().time);
		ANS.pop();
	}

	case_num++;
}

int main(){

	case_num = 0;

	while(true){

		//if(DEBUG)break;

		scanf("%d %d",&N,&E);
		if(N == 0 && E == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3488
final_rank: 5

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
//#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define BIG_NUM INT_MAX
#define NUM 32
#define SIZE 1000

enum Type{
	Human,
	Letter,
};

struct Edge{
	Edge(int arg_to,int arg_dist){
		to = arg_to;
		dist = arg_dist;
	}
	int to,dist;
};

struct Porter{
	int home_office;
	vector<int> Bag;
};

struct Item{
	string name;
	int final_office;
};

struct Data{
	Data(int arg_item_id,int arg_arrive_time,int arg_next_loc){
		item_id = arg_item_id;
		arrive_time = arg_arrive_time;
		next_loc = arg_next_loc;
	}
	bool operator<(const struct Data& arg) const{
		if(arrive_time != arg.arrive_time){
			return arrive_time < arg.arrive_time;
		}else{
			return next_loc < arg.next_loc;
		}
	}
	int item_id,arrive_time,next_loc;
};

struct Office{
	bool can_port;
	int pre_time; //ポーターが前回帰ってきた時刻
	vector<Data> V;
};

struct Info{
	Info(Type arg_type,int arg_time,int arg_id,int arg_arrive_loc){
		type = arg_type;
		time = arg_time;
		id = arg_id;
		arrive_loc = arg_arrive_loc;
	}
	bool operator<(const struct Info &arg) const{ //時刻の昇順(PQ)
		return time > arg.time;
	}
	Type type;
	int time,id,arrive_loc;
};

struct FINISH{
	FINISH(string arg_name,int arg_time){
		name = arg_name;
		time = arg_time;
	}
	bool operator<(const struct FINISH &arg) const{
		if(time != arg.time){ //時刻または名前の昇順(PQ)
			return time > arg.time;
		}else{
			return name > arg.name;
		}
	}
	string name;
	int time;
};

int N,E;
int min_dist[NUM][NUM];
int next_table[NUM][NUM];
int num_item;
vector<Edge> G[NUM];
Office office[NUM];
Porter porter[NUM];
Item item[SIZE];
priority_queue<Info> EVENT;
priority_queue<FINISH> ANS;
int case_num;


//転送先へ最短経路で届ける際の、次の中継点を求める
int find_next(int current,int goal){

	int minimum = min_dist[current][goal],min_index = BIG_NUM,mid;

	for(int i = 0; i < G[current].size(); i++){
		mid = G[current][i].to;
		if(G[current][i].dist+min_dist[mid][goal] != minimum)continue;

		min_index = min(min_index,mid);
	}

	return min_index;
}

//bool DEBUG = false;

void func(){

	if(case_num > 0)printf("\n");

	for(int i = 0; i < N; i++){
		G[i].clear();
		office[i].V.clear();
		porter[i].Bag.clear();
	}

	while(!EVENT.empty())EVENT.pop();

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			if(i != k){
				min_dist[i][k] = BIG_NUM;
			}else{
				min_dist[i][k] = 0;
			}
		}
	}

	int from,to,dist;

	for(int loop = 0; loop < E; loop++){

		scanf("%d %d %d",&from,&to,&dist);
		from--;
		to--;

		min_dist[from][to] = dist;
		min_dist[to][from] = dist;

		G[from].push_back(Edge(to,dist));
		G[to].push_back(Edge(from,dist));
	}

	//全点対間最短経路
	for(int mid = 0; mid < N; mid++){
		for(int start = 0; start < N; start++){
			if(min_dist[start][mid] == BIG_NUM)continue;
			for(int goal = 0; goal < N; goal++){
				if(min_dist[mid][goal] == BIG_NUM)continue;
				min_dist[start][goal] = min(min_dist[start][goal],min_dist[start][mid]+min_dist[mid][goal]);
			}
		}
	}

	for(int a = 0; a < N; a++){
		for(int b = 0; b < N; b++){
			if(a == b)continue;
			next_table[a][b] = find_next(a,b);
		}
	}

	scanf("%d",&num_item);

	int tmp_time;

	for(int i = 0; i < num_item; i++){

		cin >> from >> to >> tmp_time >> item[i].name;

		from--;
		to--;

		item[i].final_office = to;

		EVENT.push(Info(Letter,tmp_time,i,from));
	}

	//配達人を、自分の本拠地に配置する
	for(int i = 0; i < N; i++){

		porter[i].home_office = i;

		office[i].can_port = true;
		office[i].pre_time = 0;
	}

	int current_time,tmp_id,tmp_loc,letter_id,tmp_next_loc;

	int num_finish = 0;
	vector<Data> work;

	while(!EVENT.empty()){

		current_time = EVENT.top().time;

		//同時刻のイベントを同時に処理する
		while(EVENT.empty() == false && EVENT.top().time == current_time){

			if(EVENT.top().type == Human){

				tmp_id = EVENT.top().id;

				if(porter[tmp_id].home_office == EVENT.top().arrive_loc){ //本拠地に戻った場合

					office[porter[tmp_id].home_office].can_port = true;
					office[porter[tmp_id].home_office].pre_time = EVENT.top().time; //戻った時刻を記録

				}else{ //別のofficeに到着した場合[★荷物を渡す★]

					tmp_loc = EVENT.top().arrive_loc;
					tmp_time = EVENT.top().time;

					for(int i = 0; i < porter[tmp_id].Bag.size(); i++){

						letter_id = porter[tmp_id].Bag[i];

						if(item[letter_id].final_office == tmp_loc){ //★最終目的地に届いた場合

							num_finish++;

							ANS.push(FINISH(item[letter_id].name,tmp_time));
							if(num_finish == num_item)break;

							continue;
						}

						//次の転送先を先に計算しておく
						tmp_next_loc = next_table[tmp_loc][item[letter_id].final_office];
						if(tmp_next_loc == tmp_loc){
							printf("BUGG!!\n");
							return;
						}

						office[tmp_loc].V.push_back(Data(letter_id,tmp_time,tmp_next_loc));
					}
					porter[tmp_id].Bag.clear();
					if(num_finish == num_item)break;

					//★porterが本拠地に戻る★
					EVENT.push(Info(Human,tmp_time+min_dist[tmp_loc][porter[tmp_id].home_office],tmp_id,porter[tmp_id].home_office));
				}

			}else{

				letter_id = EVENT.top().id;
				tmp_loc = EVENT.top().arrive_loc;
				tmp_time = EVENT.top().time;

				//転送先を計算
				tmp_next_loc = next_table[tmp_loc][item[letter_id].final_office];
				office[tmp_loc].V.push_back(Data(letter_id,tmp_time,tmp_next_loc));
			}

			EVENT.pop();
		}
		if(num_finish == num_item)break;

		//home_officeにいるporterがいたら、Letterを持ち出す

		int min_time,min_next;

		for(int i = 0; i < N; i++){
			if(office[i].can_port == false || office[i].V.size() == 0)continue;

			/*
			 *最も早く、officeに届いた郵便物を探す。
			 *複数あるなら、届先の番号が若い順
			 */

			sort(office[i].V.begin(),office[i].V.end());

			min_time = office[i].V[0].arrive_time; //★到着が早い順にpushされているはず★
			min_next = office[i].V[0].next_loc;

			for(int k = 1; k < office[i].V.size(); k++){
				if(min_time < office[i].V[k].arrive_time)break;
				if(min_time == office[i].V[k].arrive_time){
					min_next = min(min_next,office[i].V[k].next_loc);
				}
			}

			//届先がmin_nextのletterを、porterに持たせる。porterは出発させる
			for(int k = 0; k < office[i].V.size(); k++){

				//if(office[i].V[k].arrive_time == min_time && office[i].V[k].next_loc == min_next){ //ポーターのバッグに詰める
				if(office[i].V[k].next_loc == min_next){ //ポーターのバッグに詰める

					porter[i].Bag.push_back(office[i].V[k].item_id);

				}else{ //今回は運ばない

					work.push_back(office[i].V[k]);
				}
			}
			office[i].V.clear();

			if(work.size() > 0){

				for(int k = 0; k < work.size(); k++){
					office[i].V.push_back(work[k]);
				}
				work.clear();
			}
			//ポーターの移動
			office[i].can_port = false;

			if(office[i].pre_time <= min_time){ //★porterが待つ場合

				EVENT.push(Info(Human,min_time+min_dist[i][min_next],i,min_next));

			}else{ //★porterが待たない場合

				EVENT.push(Info(Human,office[i].pre_time+min_dist[i][min_next],i,min_next));
			}
		}
	}

	while(!ANS.empty()){

		printf("%s %d\n",ANS.top().name.c_str(),ANS.top().time);
		ANS.pop();
	}

	case_num++;
}

int main(){

	case_num = 0;

	while(true){

		//if(DEBUG)break;

		scanf("%d %d",&N,&E);
		if(N == 0 && E == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3504
final_rank: 6

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 50

bool firstcase = true;

struct DATA{
  ll t;
  int id;
  int now;
  int next;
  int goal;

  const bool operator<(const DATA &B) const{
    if(t != B.t) return t > B.t;
    if(next != B.next) return next > B.next;
    return false;
  }

  DATA(ll t, int id, int now, int next, int goal):
    t(t), id(id), now(now), next(next), goal(goal){}
};

int dist[40][40];
int connect[40][40];
int n;

int getNext(int a, int b){
  if (a == b) return a;
  for(int i=0;i<n;i++){
    if(connect[a][i] && connect[a][i] == dist[a][i] && dist[a][i] + dist[i][b] == dist[a][b])
      return i;
  }

  assert(false);
  return -1;
}

bool solve(){
  int m, q;
  string text[1000];
  
  priority_queue<DATA> pq;

  scanf("%d%d", &n, &m);
  
  if(n == 0) return false;
  if(firstcase) firstcase = false;
  else puts("");
  
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      dist[i][j] = INF;
      connect[i][j] = false;
    }
    dist[i][i] = 0;
  }
  
  
  for(int i=0;i<m;i++){
    int a, b, c; 
    scanf("%d%d%d", &a, &b, &c);
    a--; b--;

    dist[a][b] = dist[b][a] = c;
    connect[a][b] = connect[b][a] = c;
  }

  for(int k=0;k<n;k++)
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
  
  scanf("%d", &q);

  for(int i=0;i<q;i++){
    int a, b, t;
    char temp[60];
    scanf("%d%d%d%s", &a, &b, &t, temp);
    a--; b--;
    text[i] = temp;
    
    pq.push(DATA(t, i, a, getNext(a,b), b));
  }

  bool outside[40] = {};
  ll sent[40][40] = {};
  priority_queue<pair<ll,int> > que[40];
  queue<DATA> post[40][40];
  vector<pair<ll,string> > ans;

  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      sent[i][j] = -1;
  
  while(pq.size()){
    queue<int> work;
    ll t = pq.top().t;
    
    while(pq.size() && pq.top().t == t){
      auto p = pq.top(); pq.pop();
      if(p.id != -1){
        if(p.now == p.goal){
          ans.push_back({p.t, text[p.id]});
          continue;
        }
        
        post[p.now][p.next].push(p);
        que[p.now].push({-p.t, -p.next});
        // cerr << "[post] " << t << " : " << p.now << " -> " << p.next << " -> " << p.goal << endl;
      }else{
        assert(outside[p.now]);
        outside[p.now] = false;
        // cerr << "[back] " << t << " : " << p.now << endl;
      }

      work.push(p.now);
    }
    

    while(work.size()){
      int now = work.front(); work.pop();
      if(outside[now]) continue;
      
      while(que[now].size() && -que[now].top().first <= t){
        auto p = que[now].top(); que[now].pop();

        if(-p.first <= sent[now][-p.second]) continue;
        
        //cerr << now << " -> " << -p.second << endl;
        
        while(post[now][-p.second].size()){
          auto p2 = post[now][-p.second].front(); post[now][-p.second].pop();
          
          p2.t = t + dist[now][p2.next];
          p2.now = p2.next;
          p2.next = getNext(p2.next, p2.goal);
          pq.push(p2);
        }
        
        outside[now] = true;
        pq.push(DATA((ll)t + dist[now][-p.second]*2, -1, now, -1, -1));
        sent[now][-p.second] = t;
        break;
      }

    }
  }

  sort(ans.begin(), ans.end());

  assert(ans.size() == q);
  
  for(int i=0;i<q;i++){
    cout << ans[i].second << " " << ans[i].first << endl;
  }
  
  return true;
}


int main(){
  while(solve());
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4452
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <utility>
#include <cassert>
#include <cstdio>

using namespace std;
const int INF = 1e9;

struct mail{
  int time, to, cur, next, id;
};

bool operator < (const mail &a, const mail &b){
  if(a.time != b.time) return a.time > b.time;
  if(a.next != b.next) return a.next > b.next;
  return a.cur > b.cur;
}

int main(){
  int n, m, c = 0;
  while(cin >> n >> m, n){
    if(c) printf("\n");
    else ++c;
    vector< vector<int> > D(n, vector<int>(n, INF)), E(n, vector<int>(n, -1));
    for(int i = 0; i < m; ++i){
      int u, v, d;
      cin >> u >> v >> d;
      --u;--v;
      D[u][v] = d;
      D[v][u] = d;
      E[u][v] = d;
      E[v][u] = d;
    }

    for(int i = 0; i < n; ++i) D[i][i] = 0;
    for(int k = 0; k < n; ++k){
      for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
          D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
        }
      }
    }

    vector< vector<int> > next(n, vector<int>(n, -1));
    for(int i = 0; i < n; ++i){
      for(int j = 0; j < n; ++j){
        for(int k = 0; k < n; ++k){
          if((D[i][k] + D[k][j] != D[i][j]) || (D[i][k] != E[i][k])) continue;
          next[i][j] = k;
          break;
        }
      }
    }

    int l;
    cin >> l;
    vector<string> name(l);
    priority_queue<mail> pque;
    
    for(int i = 0; i < l; ++i){
      int from, to, time;
      cin >> from >> to >> time >> name[i];
      pque.push((mail){time, to-1, from-1, next[from-1][to-1], i});
    }
    
    vector<int> T(n, -1);
    vector< vector<int> > U(n, vector<int>(n, -1));
    vector< pair<int, string> > A;
    
    while(!pque.empty()){
      mail x = pque.top();
      pque.pop();
      
      if(U[x.cur][x.next] < x.time){
        T[x.cur] = max(T[x.cur], x.time);
        U[x.cur][x.next] = T[x.cur];
        T[x.cur] = max(T[x.cur], U[x.cur][x.next] + 2*D[x.cur][x.next]);
      }
      x.time = U[x.cur][x.next] + D[x.cur][x.next];
      x.cur = x.next;
      x.next = next[x.cur][x.to];

      if(x.cur == x.to){
        A.push_back(make_pair(x.time, name[x.id]));
      }else{
        pque.push(x);
      }
    }
    
    sort(A.begin(), A.end());
    for(int i = 0; i < l; ++i){
      cout << A[i].second << " " << A[i].first << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3188
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <utility>
#include <cassert>
#include <cstdio>

using namespace std;
const int INF = 1e9;

struct mail{
  int time, to, cur, next, id;
};

bool operator < (const mail &a, const mail &b){
  if(a.time != b.time) return a.time > b.time;
  if(a.next != b.next) return a.next > b.next;
  return a.cur > b.cur;
}

int main(){
  int n, m, c = 0;
  while(cin >> n >> m, n){
    if(c) printf("\n");
    else ++c;
    vector< vector<int> > D(n, vector<int>(n, INF)), E(n, vector<int>(n, 0));

    
    for(int i = 0; i < m; ++i){
      int u, v, d;
      cin >> u >> v >> d;
      --u;--v;
      D[u][v] = d;
      D[v][u] = d;
      E[u][v] = d;
      E[v][u] = d;
    }

    for(int i = 0; i < n; ++i) D[i][i] = 0;
    for(int k = 0; k < n; ++k){
      for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
          D[i][j] = min(D[i][j], D[i][k] + D[k][j]);

        }
      }
    }

    vector< vector<int> > next(n, vector<int>(n, -1));
    for(int i = 0; i < n; ++i){
      for(int j = 0; j < n; ++j){
        for(int k = 0; k < n; ++k){
          if(i == k || (D[i][k] + D[k][j] != D[i][j]) || (D[i][k] != E[i][k])) continue;
          next[i][j] = k;
          break;
        }
      }
    }

    int l;
    cin >> l;
    vector<string> name(l);
    priority_queue<mail> pque;
    
    for(int i = 0; i < l; ++i){
      int from, to, time;
      cin >> from >> to >> time >> name[i];
      pque.push((mail){time, to-1, from-1, next[from-1][to-1], i});
    }
    
    vector<int> T(n, -1);
    vector< vector<int> > U(n, vector<int>(n, -1));
    vector< pair<int, string> > A;
    
    while(!pque.empty()){
      mail x = pque.top();
      pque.pop();
      
      if(U[x.cur][x.next] < x.time){
        T[x.cur] = max(T[x.cur], x.time);
        U[x.cur][x.next] = T[x.cur];
        T[x.cur] = max(T[x.cur], U[x.cur][x.next] + 2*D[x.cur][x.next]);
      }
      x.time = U[x.cur][x.next] + D[x.cur][x.next];
      x.cur = x.next;
      x.next = next[x.cur][x.to];

      if(x.cur == x.to){
        A.push_back(make_pair(x.time, name[x.id]));
      }else{
        pque.push(x);
      }
    }
    
    sort(A.begin(), A.end());
    for(int i = 0; i < l; ++i){
      cout << A[i].second << " " << A[i].first << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3192
final_rank: 2

code_snippet: // g++ -std=c++11 a.cpp
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>   
#include<map>
#include<set>
#include<unordered_map>
#include<utility>
#include<cmath>
#include<random>
#include<cstring>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(ll i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define FOR(i,a) for(auto i:a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define show2d(v) rep(i,v.size()){rep(j,v[i].size())cout<<" "<<v[i][j];cout<<endl;}
using namespace std;
//kaewasuretyuui
typedef long long ll;
#define int ll
typedef ll Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
#define mt make_tuple
typedef tuple<int,int,int,int> tp;
typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
//template<class C>constexpr int size(const C &c){return (int)c.size();}
//template<class T,size_t N> constexpr int size(const T (&xs)[N])noexcept{return (int)N;}
const double PI=acos(-1);
const double EPS=1e-9;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9+10;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
signed main(){
	int n,m,co=0;
	while(cin>>n>>m,n){
		if(co++)cout<<endl;
		vvi cost(n,vi(n,inf));
		rep(i,n)cost[i][i]=0;
		vvp G(n);
		rep(i,m){
			int a,b,c;cin>>a>>b>>c;
			a--;b--;
			cost[a][b]=cost[b][a]=c;
			G[a].pb({b,c});
			G[b].pb({a,c});
		}
		rep(i,n)sort(all(G[i]));
		rep(k,n)rep(i,n)rep(j,n)
			cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);

		vvi go(n,vi(n,inf));
		rep(i,n)rep(j,n)if(i!=j)rep(k,G[i].size())if(cost[i][j]==G[i][k].second+cost[G[i][k].first][j]){
			go[i][j]=G[i][k].first;break;
		}

		int q;
		cin>>q;
		vi s(q),t(q),hu(n),ob(q);
		vs name(q);
		rep(i,q)cin>>s[i]>>t[i]>>ob[i]>>name[i];
		rep(i,q)s[i]--,t[i]--;
		while(1){
			int mi=inf,from=-1;
			rep(i,q)if(s[i]!=t[i]){
				int tim=max(ob[i],hu[s[i]]);
				if(mi>tim)mi=tim,from=s[i];
			}
			if(from==-1)break;

			int mi_t=inf,to=-1;
			rep(i,q)if(s[i]!=t[i]&s[i]==from){
				if(mi_t>ob[i])mi_t=ob[i],to=go[s[i]][t[i]];
				else if(mi_t==ob[i])to=min(to,go[s[i]][t[i]]);
			}

			hu[from]=mi+2*cost[from][to];
			rep(i,q)if(ob[i]<=mi&&s[i]==from&&go[s[i]][t[i]]==to){
				ob[i]=mi+cost[from][to];
				s[i]=to;
			}
		}
		vector<pair<int,string> >out(q);
		rep(i,q)out[i]={ob[i],name[i]};
		sort(all(out));
		rep(i,q)cout<<out[i].second<<" "<<out[i].first<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3228
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll INF =(1LL<<31);

typedef pair<ll,ll> Pii;
typedef pair<ll,string> Pis;
typedef pair< Pii , Pis > PP;

ll N,M,K;
ll G[32][32];
ll g[32][32];

set< PP > u[32][32];

ll mem[32][32];

ll search(ll from,ll to){
  if(mem[from][to]!=-1)return mem[from][to];
  ll mini=INF, res=-1;
  for(int i=0;i<N;i++){
    if(from==i || g[from][i]==INF)continue;
    if(mini>g[from][i]+G[i][to]){
      mini=g[from][i]+G[i][to];
      res=i;
    }
  }
  assert(res!=-1);
  return mem[from][to]=res;
}

void init(){
  for(int i=0;i<32;i++){
    for(int j=0;j<32;j++){
      g[i][j]=(i==j?0:INF);
      G[i][j]=(i==j?0:INF);
      mem[i][j]=-1;
      u[i][j].clear();
    }
  }
}

int main(){
  ll cnt=0;
  while(1){

    init();
    cin>>N>>M;
    if(N==0&&M==0)break;
    if(cnt)cout<<endl;
    cnt++;
    
    for(int i=0;i<M;i++){
      ll a,b,c;
      cin>>a>>b>>c;
      a--,b--;
      G[a][b]=G[b][a]=c;
    }
    
    for(int i=0;i<N;i++)
      for(int j=0;j<N;j++)
        g[i][j]=G[i][j];
    
    for(int k=0;k<N;k++)
      for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
          G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
    
    cin>>K;

    map<ll, vector<PP> > mp;
    set<ll> st;
    
    for(int i=0;i<K;i++){
      ll from,to,ti;
      string name;
      cin>>from>>to>>ti>>name;
      from--,to--;
      mp[ti].push_back( PP( Pii(from,to) , Pis(0,name)) );
      st.insert(ti);
    }

    vector< Pis > ans;
    vector<ll> v(N,0);
    ll last=-1;
    
    st.insert(0);
    while(!st.empty()){

      ll p=*st.begin();
      assert( last < p ); last=p;
      
      if(mp.count(p)){
        for(int i=0;i<(int)mp[p].size();i++){
          PP pp=mp[p][i];
          ll from=pp.first.first;
          ll to=pp.first.second;
          string name=pp.second.second;
          ll key=search(from,to);
          PP tmp=PP( Pii(p, key ) , Pis(to,name) );
          u[from][key].insert(tmp);
        }
        //       mp[p].clear();
      }
      
      for(int i=0;i<N;i++){
        if(v[i]>p)continue;
        
        PP target=PP( Pii(INF,0) , Pis(0,"") );
        
        for(int j=0;j<N;j++){
          if(u[i][j].empty())continue;
          PP pp=*u[i][j].begin();
          target=min(target,pp);
        }
        if(target.first.first==INF)continue;

        ll nex=target.first.second;
        
        set< PP > :: iterator it;
        for( it=u[i][nex].begin(); it!= u[i][nex].end() ; it++ ){
          PP pp=*it;
          ll to=pp.second.first;
          string name=pp.second.second;

          if(to==nex){
            ans.push_back( Pis( p+g[i][nex] , name ) );
          }else{
            mp[ p+g[i][nex] ].push_back( PP(Pii(nex,to),Pis(0,name)) );
          }
        }// iterator
        
        u[i][nex].clear();
        v[i]=p+g[i][nex]*2;
        st.insert(p+g[i][nex]);
        st.insert(p+g[i][nex]*2);
      }// i
      
      st.erase(p);
    }// while ( st.empty() )
    
    sort(ans.begin(),ans.end());
    for(int i=0;i<(int)ans.size();i++){
      Pis p=ans[i];
      cout<<p.second<<' '<<p.first<<endl;
    }
  }
  
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3508
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define INF 10000000
using namespace std;

typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,string> P2;

struct edge{
	int t,c;
	edge(){}
	edge(int tt,int cc){
		t=tt;
		c=cc;
	}
};

struct data{
	int f,id;
	int ti,gt,next;
	data(){}
	data(int ff,int ii,int tt,int gg,int nn){
		f=ff;
		id=ii;
		ti=tt;
		gt=gg;
		next=nn;
	}
	bool operator<(const data& d)const{
		if(ti==d.ti){
			if(gt==d.gt)return next>d.next;
			return gt>d.gt;
		}
		return ti>d.ti;
	}
};

int n,m,l;
vector<edge> G[1001];

int dist[33];
int dijk(int f,int t){
	fill(dist,dist+n,INF);
	priority_queue<P,vector<P>,greater<P> > que;
	que.push(P(0,t));
	int res=n;
	dist[t]=0;
	while(que.size()){
		P p=que.top();
		que.pop();
		if(dist[p.second]<p.first)continue;
		for(int j=0;j<G[p.second].size();j++){
			edge e=G[p.second][j];
			if(e.t==f && dist[e.t]==dist[p.second]+e.c)res=min(res,p.second);
			if(dist[e.t]>dist[p.second]+e.c){
				if(e.t==f)res=p.second;
				dist[e.t]=dist[p.second]+e.c;
				que.push(P(dist[e.t],e.t));
			}
		}
	}
	return res;
}

priority_queue<data> que[35];
string str[1001];
int lf[1001],lt[1001],ltime[1001];
int next[35];
int ntime[35];
priority_queue<P,vector<P>,greater<P> > backer;
vector<P2> res;

int main(void){
	bool space=false;
	while(1){
		scanf("%d%d",&n,&m);
		if(n==0 && m==0)break;
		if(space)cout << endl;
		for(int i=0;i<n;i++){
			G[i].clear();
		}
		space=true;
		for(int i=0;i<m;i++){
			int f,t,c;
			scanf("%d%d%d",&f,&t,&c);
			f--;
			t--;
			G[f].push_back(edge(t,c));
			G[t].push_back(edge(f,c));
		}
		for(int i=0;i<n;i++){
			while(que[i].size())que[i].pop();
		}
		while(backer.size())backer.pop();
		scanf("%d",&l);
		for(int i=0;i<l;i++){
			cin >> lf[i] >> lt[i] >> ltime[i] >> str[i];
			lf[i]--;
			lt[i]--;
			que[lf[i]].push(data(-1,i,ltime[i],ltime[i],dijk(lf[i],lt[i])));
		}
		memset(next,0,sizeof(next));
		memset(ntime,0,sizeof(ntime));
		res.clear();
		while(1){
			bool flag=false;
			int best=0,bt=0;
			for(int i=0;i<n;i++){
				if(que[i].size()>0){
					data p=que[i].top();
					if(!flag){
						best=p.ti;
						bt=i;
					}
					flag=true;
					if(best>p.ti){
						bt=i;
						best=p.ti;
					}
				}
			}
			if(!flag)break;
			data v=que[bt].top();
			que[bt].pop();
			while(backer.size()){
				P p=backer.top();
				if(p.first<=v.ti){
					backer.pop();
					next[p.second]=0;
				}else break;
			}
			if(bt==lt[v.id]){
				res.push_back(P2(v.ti,str[v.id]));
				continue;
			}
			if(next[bt]==-1){
				v.ti=ntime[bt];
				que[bt].push(v);
				continue;
			}
			int nex=dijk(bt,lt[v.id]);
			int now=v.ti;
			int plu=0;
			for(int i=0;i<G[bt].size();i++){
				if(nex==G[bt][i].t)plu=G[bt][i].c;
			}
			next[bt]=-1;
			ntime[bt]=v.ti+plu*2;
			backer.push(P(v.ti+plu*2,bt));
			v.ti+=plu;
			que[nex].push(data(bt,v.id,v.ti,v.ti,(nex==lt[v.id])?-1:dijk(nex,lt[v.id])));
			queue<data> tmp;
			while(que[bt].size()){
				data pp=que[bt].top();
				if(pp.ti>now)break;
				que[bt].pop();
				if(pp.next==nex){
					que[nex].push(data(bt,pp.id,v.ti,v.ti,(nex==lt[pp.id])?-1:dijk(nex,lt[pp.id])));
				}else{
					tmp.push(pp);
				}
			}
			while(tmp.size()){
				data pp=tmp.front();
				que[bt].push(pp);
				tmp.pop();
			}
		}
		sort(res.begin(),res.end());
		for(int i=0;i<res.size();i++){
			cout << res[i].second << " " << res[i].first << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3424
final_rank: 19

code_snippet: #ifndef _WIN32
#include<iostream>
#endif // !_WIN32

#include<algorithm>
#include<vector>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<utility>
#include<assert.h>
using namespace std;
typedef long long LL;
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
typedef pair<LL, string> P;
typedef vector<int> V;
typedef vector<V> VV;
//input
int n, m, l;
int c[32][32];
string label[1123];
int bg_pos[1123];
int ed_pos[1123];
LL bg_time[1123];


LL d[32][32];
int nxt[32][32];

const LL INF = 1e15;

int exist[32];
vector<VV> post(32,VV(32));
LL min_time[32][32];
typedef pair<LL, int> pli;
template<typename T>
bool chmin(T &a, T b) { bool f = a > b; if (f)a = b; return f; }
map<LL, vector<pair<int,int>>> sc;
void sync(LL now_time,vector<P>& answer) {
	REP(from, n)if(exist[from]) {
		pli res(INF,-1);
		REP(j, n)chmin(res, { min_time[from][j],j });
		int to = res.second;
		if (to != -1) {
			exist[from] = 0;
			LL next_time = now_time + c[from][to];
			V &now_post = post[from][to];
			while (now_post.size()) {
				int now_item = now_post.back();
				if (ed_pos[now_item] == to)
					answer.push_back({ next_time,label[now_item] });
				else {
					sc[next_time].push_back({ to,now_item });
					//cout << label[now_item] << " " << from << "->" << to << endl;
				}
				now_post.pop_back();
			}
			min_time[from][to] = INF;
			next_time += c[to][from];
			sc[next_time].push_back({ from,-1 });
		}
	}
}
LL clean(LL now_time) {
	auto it = sc.upper_bound(now_time);
	if (it == sc.end())return -1;
	now_time = it->first;
	while (it->second.size()) {
		int id = it->second.back().second;
		int pos = it->second.back().first;
		if (id == -1)exist[pos] = 1;
		else {
			int to = nxt[pos][ed_pos[id]];
			chmin(min_time[pos][to], now_time);
			post[pos][to].push_back(id);
		}
		it->second.pop_back();
	}
	return now_time;
}

void init() {
	sc.clear();
	REP(i, 32)REP(j, 32)c[i][j] = -1;
	REP(i, 32)REP(j, 32) {
		d[i][j] = INF;
		nxt[i][j] = -1;
	}
	REP(i, 32) {
		exist[i] = 1;
		REP(j,32)post[i][j].clear();
		REP(j,32)min_time[i][j] = INF;
	}
}

void set_nxt(){
	REP(t, n) {
		bool update = true;
		d[t][t] = 0;
		while (update) {
			update = false;
			REP(i, n)REP(j, n) if(c[i][j]!=-1){
				LL nxt_cost = d[i][t] + c[i][j];
				if (d[j][t] > nxt_cost) {
					update = true;
					d[j][t] = nxt_cost;
					nxt[j][t] = i;
				}
				if (d[j][t] == nxt_cost) {
					nxt[j][t] = min(nxt[j][t], i);
				}
			}
		}
	}
}

int main() {
	int xxx = 0;
	while (cin >> n >> m, n + m) {
		if (xxx)cout << endl;
		xxx = 1;
		init();
		REP(i, m) {
			int a, b, x;
			cin >> a >> b >> x;
			a--, b--;
			c[a][b] = c[b][a] = x;
		}
		vector<P> res;
		set_nxt();
		cin >> l;
		REP(i, l) {
			cin >> bg_pos[i] >> ed_pos[i] >> bg_time[i] >> label[i];
			bg_pos[i]--;
			ed_pos[i]--;
			sc[bg_time[i]].push_back({ bg_pos[i],i });
		}
		LL nt = -1;
		while (true) {
			nt = clean(nt);
			if (nt == -1)break;
			sync(nt, res);
		}
		assert(res.size() == l);
		sort(ALL(res));
		for (auto &it : res)cout << it.second << " " << it.first << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3576
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (int)(k); i < (int)(n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/


int n, m, l;
vector<vi> dist, nx;
typedef pair<int, string> Item;

struct Event
{
	int time, office;
	int eve; //  0 -> ??°??£?????????, 1 -> ???????????????????????????
	Item item;

	bool operator < (const Event& e) const 
	{ 
		if (time != e.time) return time > e.time;
		else return eve > e.eve;
	}
};

vector<Item> getItem(int office, set<pair<Item, int>> &que)
{
	ll time = LLONG_MAX / 100; int to = 10000;
	for (auto i : que)
	{
		if (i.second < time)
		{
			time = i.second;
			to = nx[office][i.first.first];
		}
		else if (i.second == time)
		{
			chmin(to, nx[office][i.first.first]);
		}
	}
	vector<Item> res;
	vector<pair<Item, int>> er;
	for (auto i : que)
	{
		if (nx[office][i.first.first] == to)
		{
			er.push_back(i);
			res.push_back(i.first);
		}
	}
	for (auto i : er) que.erase(i);
	return res;
}

int main()
{
	cin.sync_with_stdio(false); cout << fixed << setprecision(10);
	bool start = true;
	while (cin >> n >> m, n)
	{
		if (!start) cout << endl;
		start = false;
		dist.clear(), nx.clear();
		dist.resize(n, vi(n, INF));
		nx.resize(n, vi(n));
		REP(i, n)REP(j, n)
		{
			if (i == j) dist[i][j] = 0;
			nx[i][j] = j;
		}
		REP(i, m)
		{
			int a, b, c; cin >> a >> b >> c;
			a--; b--;
			dist[a][b] = c;
			dist[b][a] = c;
		}
		REP(k, n)REP(i, n)REP(j, n)
		{
			if (dist[i][j] > dist[i][k] + dist[k][j])
			{
				dist[i][j] = dist[i][k] + dist[k][j];
				nx[i][j] = nx[i][k];
			}
			else if (k != i && dist[i][j] == dist[i][k] + dist[k][j])
			{
				nx[i][j] = min(nx[i][j], nx[i][k]);
			}
		}
	
		priority_queue<Event> events;
		cin >> l;
		REP(i, l)
		{
			int a, b, t; string s;
			cin >> a >> b >> t >> s;
			a--; b--;
			events.push(Event{ t,a,1,Item(b, s) });
		}
		vector<bool> officer(n, true);
		vector<set<pair<Item, int>>> que(n); //????????¨??????

		int now = -1;
		vs reach;
		while (1)
		{
			if (events.empty())
			{
				bool f = true;
				REP(i, que.size()) if (!que.empty()) f = false;
				if(f) break;
			}
			if (events.empty() || events.top().time != now)
			{
				bool f = true;
				sort(ALL(reach));
				for(auto i: reach)
				{ 
					cout << i << " " << now << endl;
				}
				reach.clear();
				REP(i, n)
				{
					if (!officer[i] || que[i].empty()) continue;
					f = false;
					vector<Item> send = getItem(i, que[i]);
					int next_office = nx[i][get<0>(send[0])];
					int d = dist[i][next_office];
					officer[i] = false;
					events.push(Event{ now + d * 2 ,i, 0 });
					for (auto item : send)
					{
						events.push(Event{ now + d, next_office,  1, item });
					}
				}
				if (f)
				{
					if (events.empty()) break;
					else now = events.top().time;
				}
				else continue;
			}

			Event tmp = events.top();
			events.pop();
			if (tmp.eve == 0)
			{
				officer[tmp.office] = true;
			}
			else
			{
				if (tmp.item.first == tmp.office)
				{
					reach.push_back(tmp.item.second);
				}
				else
				{
					que[tmp.office].emplace(tmp.item, tmp.time);
				}
			}
		}
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3408
final_rank: 12

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;

struct root {
	int start;
	int goal;
	int time;
	vector<int>ways;
	root():ways() {
		start = 0;
		goal = 0;
	}
	root(const int start_, const int goal_, const int time_, const vector<int>ways_)
		:start(start_), goal(goal_), time(time_), ways(ways_) {

	}
};
struct edge {
	int src;
	int dst;
	int cost;
};

struct query {
	int type;
	int id;
	int num;
	int next;
	int nextnext;
	int time;
	query(int type_, int id_, int num_, const int next_,const int nextnext_, int time_) :type(type_), id(id_), num(num_), next(next_),nextnext(nextnext_), time(time_) {

	}
};
class Compare {
public:
	bool operator()(const query&l, const query&r) {
		return l.time==r.time?l.type==r.type?l.nextnext>r.nextnext:l.type<r.type:l.time> r.time;
	}
};	//aa?????????????????¶
struct letter {
	int id;
	string name;
	vector<int>ways;
};
int main() {
	int aa = 0;
	while (1) {
		int N, M; cin >> N >> M;
		if (!N)break;
		if(aa)	cout << endl;

		aa++;
		
		vector<vector<root>>roots(N, vector<root>(N));
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				
				roots[i][j].start = i;
				roots[i][j].goal = j;
				if (i == j) {
					roots[i][j].time = 0;
					roots[i][j].ways = vector<int>{};
				}
				else {
					roots[i][j].time = 1e9;
				}

			}
		}
		for (int i = 0; i < M; ++i) {
			int a, b, c; cin >> a >> b >> c; a--; b--;
			roots[a][b] = root( a,b,c,vector<int>{b} );
			roots[b][a] = root(b, a, c, vector<int>{a});
		}
		for (int k = 0; k < N; ++k) {
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N; ++j) {
					if (i == k || j == k||i==j)continue;
					if (roots[i][k].time < 1e8&&roots[k][j].time < 1e8) {
						const int  nexttime = roots[i][k].time + roots[k][j].time;
						bool ok = true;
						vector<int>preways(roots[i][j].ways);
						vector<int>nextways(roots[i][k].ways);
						nextways.insert(nextways.end(), roots[k][j].ways.begin(), roots[k][j].ways.end());
						if (nexttime > roots[i][j].time)ok = false;
						else if (nexttime == roots[i][j].time) {

							for (int a= 0; a < preways.size(); ++a) {
								if (preways[a] > nextways[a]) {
									ok = true;
									break;
								}
								else if (preways[a] < nextways[a]) {
									ok = false;
									break;
								}
							}
						}
						else {
							ok = true;
						}
						if (ok) {
							roots[i][j].time = nexttime;
							roots[i][j].ways = nextways;
						}
					}
				}
			}
		}
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				if (roots[i][j].time < 1e8) {
					roots[i][j].ways.insert(roots[i][j].ways.begin(), i);
					roots[i][j].ways.emplace_back(-1);
				}
			}
		}


		int L; cin >> L;
		priority_queue<query, vector<query>, Compare>que;
		map<int,letter>mp;
		for (int i = 0; i < L; ++i) {
			int a, b, c; string d; cin >> a >> b >> c >> d; a--; b--;
			mp[i] = letter{ i,d,roots[a][b].ways };
			int nextnext = roots[a][b].ways[1];
			que.push(query(1,i,0,roots[a][b].ways[0],nextnext,c ));
		}
		for (int i = 0; i < N; ++i) {
			que.push(query{ 0,0,0,i,0,0 });
		}
		vector<pair< int,string>>anss;
		//vector<vector<vector<int>>>waits(N,vector<vector<int>>(N,vector<int>()));
		vector<deque<vector<tuple<int,int,int>>>>nexts(N);
		vector<int>exists(N);
		
		while (!que.empty()) {
			query q(que.top());
			que.pop();

			const int nowtime = q.time;

			const int nowplace = q.next;
			//??°??£?????????
			if (q.type == 0) {
				assert(exists[nowplace] == false);
				if (!nexts[nowplace].empty()) {
					auto carrys(nexts[nowplace].front());
					const int nextplace = get<2>(carrys[0]);
					for (auto carry : carrys) {
						int aid = get<0>(carry);
						int anum = get<1>(carry);
						const int needtime = roots[nowplace][nextplace].time;
						const int nexttime = nowtime + needtime;
						const int backtime = nexttime + needtime;
						que.push(query(1,aid,anum + 1,nextplace,mp[aid].ways[anum+2],nexttime ));
						exists[nowplace] = false;
					}
					que.push(query(0, 0, 0, nowplace, 0,nowtime+2*roots[nowplace][nextplace].time));
					nexts[nowplace].pop_front();
				}
				else {
					assert(!exists[nowplace]);
					exists[nowplace] = true;
				}
			}
			//???????????\???
			else {
				if (q.nextnext==-1) {
					anss.push_back(make_pair(q.time, mp[q.id].name));
				}
				else {
					const int nextplace = mp[q.id].ways[q.num + 1];
					if (!exists[nowplace]) {
						bool flag = true;
						for (int i = 0; i < nexts[nowplace].size(); ++i) {
							if (get<2>(nexts[nowplace][i][0]) == nextplace) {
								nexts[nowplace][i].push_back(make_tuple(q.id, q.num, nextplace));
								flag = false;
								break;
							}
						}
						if (flag) {
							nexts[nowplace].push_back(vector<tuple<int,int,int>>(1, make_tuple(q.id, q.num, nextplace)));
						}
					}
					else {
						bool flag = true;
						for (int i = 0; i < nexts[nowplace].size(); ++i) {
							if (get<2>(nexts[nowplace][i][0]) == nextplace) {
								nexts[nowplace][i].push_back(make_tuple(q.id, q.num, nextplace));
								flag = false;
								break;
							}
						}
						if (flag) {
							nexts[nowplace].push_back(vector<tuple<int, int, int>>(1, make_tuple(q.id, q.num, nextplace)));
						}
						que.push(query(0, 0, 0, nowplace, 0, nowtime));
						exists[nowplace] = false;

					}
				}
				
			}
		}
		sort(anss.begin(), anss.end());
		for (auto ans : anss) {
			cout << ans.second << " " << ans.first << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3452
final_rank: 20

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 32;

const int INF = 1 << 30;

const string evnms[] = { "E_LT_ARV", "E_PM_BK", "E_PM_DL", "E_PM_ST" };

/* typedef */

typedef pair<int,int> pii;
typedef pair<int,string> pis;
typedef vector<int> vi;
typedef vector<pis> vpis;
typedef queue<pii> qpii;

struct Letter {
  int t, nexthop, dst;
  string label;
  Letter() {}
  Letter(int _t, int _nexthop, int _dst, string _label) {
    t = _t, nexthop = _nexthop, dst = _dst, label = _label;
  }

  bool operator<(const Letter& lt) const {
    return t < lt.t || (t == lt.t && nexthop < lt.nexthop);
  }

  void print() {
    printf("    Letter: t=%d, nexthop=%d, dst=%d, labe=%s\n",
	   t, nexthop, dst, label.c_str());
  }
};

typedef deque<Letter> dql;

struct PostMan {
  int id, st;
  dql mls;

  void print() {
    printf("  PostMan: id=%d, st=%d, mls=%lu\n", id, st, mls.size());
    for (int i = 0; i < mls.size(); i++) mls[i].print();
  }
};

enum { M_WT, M_ON };
enum { E_LT_ARV, E_PM_BK, E_PM_DL, E_PM_ST };

struct Event {
  int t, st;
  int p0, p1;
  string label;
  PostMan *pm;

  Event() {}
  Event(int _t, int _st, int _p0, int _p1, string _label) {
    t = _t, st = _st, p0 = _p0, p1 = _p1;
    label = _label;
    pm = NULL;
  }
  Event(int _t, int _st, int _p0, int _p1, PostMan *_pm) {
    t = _t, st = _st, p0 = _p0, p1 = _p1;
    label = "";
    pm= _pm;
  }
  
  bool operator>(const Event& ev) const {
    return t > ev.t || (t == ev.t && st > ev.st);
  }

  void print() {
    if (st == E_LT_ARV) {
      printf("Event: t=%d, st=%s, %d->%d, label=%s\n",
	     t, evnms[st].c_str(), p0, p1, label.c_str());
    }
    else {
      printf("Event: t=%d, st=%s, %d->%d, pm=%d\n",
	     t, evnms[st].c_str(), p0, p1, pm->id);
      pm->print();
    }
  }
};

/* global variables */

int n, m, l;
vi nbrs[MAX_N];
int costs[MAX_N][MAX_N];
int dists[MAX_N], nhops[MAX_N];
int rt[MAX_N][MAX_N];

dql posts[MAX_N];
PostMan pmen[MAX_N];

/* subroutines */

/* main */

int main() {
  for (bool first = true;; first = false) {
    cin >> n >> m;
    if (n == 0) break;
    
    if (! first) cout << endl;

    for (int i = 0; i < n; i++) nbrs[i].clear();
    
    for (int i = 0; i < m; i++) {
      int a, b, c;
      cin >> a >> b >> c;
      a--, b--;
      nbrs[a].push_back(b);
      nbrs[b].push_back(a);
      costs[a][b] = costs[b][a] = c;
    }

    for (int i = 0; i < n; i++) {
      sort(nbrs[i].begin(), nbrs[i].end());
      for (int j = 0; j < n; j++) rt[i][j] = -1;
    }

    for (int st = 0; st < n; st++) {
      for (int i = 0; i < n; i++) dists[i] = INF;
      dists[st] = 0;
      nhops[st] = -1;

      qpii q;
      q.push(pii(0, st));

      while (! q.empty()) {
	pii u = q.front();
	q.pop();

	int ud = u.first;
	int ui = u.second;
	if (ud != dists[ui]) continue;

	int unhop = nhops[ui];
	vi& nbru = nbrs[ui];

	for (vi::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
	  int vi = *vit;
	  int vd = ud + costs[ui][vi];
	  if (dists[vi] > vd) {
	    dists[vi] = vd;
	    nhops[vi] = (unhop >= 0) ? unhop : vi;
	    q.push(pii(vd, vi));
	  }
	  else if (dists[vi] == vd && nhops[vi] > unhop) {
	    dists[vi] = vd;
	    nhops[vi] = unhop;
	    q.push(pii(vd, vi));
	  }
	}
      }

      for (int gl = 0; gl < n; gl++) rt[st][gl] = nhops[gl];
    }

    if (false) {
      for (int i = 0; i < n; i++) {
	for (int j = 0; j < n; j++) cout << rt[i][j] << ' ';
	cout << endl;
      }
    }

    for (int i = 0; i < n; i++) {
      posts[i].clear();
      pmen[i].id = i, pmen[i].st = M_WT;
      pmen[i].mls.clear();
    }

    priority_queue<pis,vector<pis>,greater<pis> > arrived;
    priority_queue<Event,vector<Event>,greater<Event> > pqe;

    cin >> l;
    
    for (int i = 0; i < l; i++) {
      int p0, p1, t;
      string label;
      cin >> p0 >> p1 >> t >> label;
      p0--, p1--;
      
      pqe.push(Event(t, E_LT_ARV, p0, p1, label));
    }

    while (! pqe.empty()) {
      Event ev = pqe.top();
      pqe.pop();
      //ev.print();
      
      if (ev.st == E_LT_ARV) {
	int nexthop = rt[ev.p0][ev.p1];
	posts[ev.p0].push_back(Letter(ev.t, nexthop, ev.p1, ev.label));

	PostMan *pm = &pmen[ev.p0];
	if (pm->st == M_WT) {
	  pm->st = M_ON;
	  pqe.push(Event(ev.t, E_PM_ST, ev.p0, ev.p0, pm));
	}
      }

      else if (ev.st == E_PM_ST) {
	dql& post = posts[ev.p0];
	sort(post.begin(), post.end());

	Letter lt0 = post.front();
	post.pop_front();
	PostMan *pm = ev.pm;
	pm->mls.push_back(lt0);

	for (dql::iterator lit = post.begin(); lit != post.end();) {
	  if (lit->nexthop == lt0.nexthop) {
	    pm->mls.push_back(*lit);
	    lit = post.erase(lit);
	  }
	  else lit++;
	}

	pqe.push(Event(ev.t + costs[ev.p0][lt0.nexthop],
		       E_PM_DL, ev.p0, lt0.nexthop, pm));
      }

      else if (ev.st == E_PM_DL) {
	PostMan *pm = ev.pm;
	dql& mls = pm->mls;
	
	for (dql::iterator lit = mls.begin(); lit != mls.end(); lit++) {
	  lit->nexthop = rt[ev.p1][lit->dst];
	  if (lit->nexthop == -1)
	    arrived.push(pis(ev.t, lit->label));
	  else
	    pqe.push(Event(ev.t, E_LT_ARV, ev.p1, lit->dst, lit->label));
	}

	pm->mls.clear();

	pqe.push(Event(ev.t + costs[ev.p1][ev.p0],
		       E_PM_BK, ev.p1, ev.p0, pm));
      }

      else if (ev.st == E_PM_BK) {
	PostMan *pm = ev.pm;
	if (posts[pm->id].empty())
	  pm->st = M_WT;
	else {
	  pqe.push(Event(ev.t, E_PM_ST, ev.p1, ev.p1, pm));
	}
      }
    }

    //cout << arrived.size() << endl;

    while (! arrived.empty()) {
      pis lt = arrived.top();
      arrived.pop();

      cout << lt.second << ' ' << lt.first << endl;
    }
  }

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1476
final_rank: 8