# 《挑战程序设计竞赛》 P108 Roadbloks 3255 改造Dijkstra算法 次短路径

#include <iostream>
#include  <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include  <utility>
#include <bits/stdc++.h>
using namespace std;
int N,R;
const  int  MM=5001;
const  int INF=0x3f3f3f3f;
struct  Edge{
int to;
int cost;

};

typedef pair<int ,int> P; //first : 最短距离  second ： 目的点。

vector<Edge> G[MM];

int shortest[MM];
int  shorter[MM];

void dijks(){

priority_queue< P, vector<P>, greater<P> > q;
shortest[1]=0;
q.push(P(0,1));

while( !q.empty())
{
P p= q.top(); q.pop();
int v=p.second;
if( shortest[v] < p.first ) return;

for(int i=0;i<G[v].size(); i++){
Edge &e = G[v][i];
if( shortest[ e.to ] > shortest[ v ] + e.cost ){
shortest[e.to] = shortest[ v ] + e.cost;
q.push( P( shortest[e.to] ,e.to) );
//cout << "入队" << shortest[e.to] <<" "<<e.to <<endl;
}
}
}
}

int main()

{
cin >>  N >> R;

for(int i=1;i<=R;i++){
int a, b,c; cin >> a>> b >> c;

Edge e; e.to= b;e.cost = c;

Edge ee; ee.to=a; ee.cost =c;

G[a].push_back(e);
G[b].push_back(ee);
}

fill(shortest+1, shortest+N+1, INF );
dijks();

cout << *min_element(shortest+1, shortest+N+1 );

for(int i=1;i<=N;i++){

cout <<  i <<" "<< shortest[i] <<endl;
}

return 0;
}