#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
int N,E;
struct nod{
int next,w;
bool operator <(const nod &x)const{
return w > x.w;
}
};
vector <nod> V[2005];
long long ans[2005];
bool vis[2005];
long long disTo[2005];
void dijkstra(int x){
priority_queue <nod> pq;
pq.push((nod){x,0});
memset(disTo,0x3f,sizeof disTo);
disTo[x] = 0;
ans[x] = 1;
while(!pq.empty()){
nod nx = pq.top();
int kx = nx.next;
pq.pop();
for(int i = 0;i < V[kx].size();i++){
nod xx = V[kx][i];
if(disTo[xx.next] > disTo[kx] + xx.w){
disTo[xx.next] = disTo[kx] + xx.w;
ans[xx.next] = ans[kx];
pq.push((nod){disTo[xx.next],xx.next});
}
else if(disTo[xx.next] == disTo[kx] + xx.w)
ans[xx.next] += ans[kx];
}
}
}
int main(){
cin >> N >> E;
for(int i = 1;i <= E;i++){
int u,v,w1;
cin >> u >> v >> w1;
nod l;l.next = v;l.w = w1;
V[u].push_back(l);
}
dijkstra(1);
if(disTo[N] < 0x3f3f3f3f) cout << disTo[N] << " " << ans[N];
else cout << "No answer";
return 0;
}