#include
#include
#include
using namespace std;
typedef long long ll;
const ll mxN = 1e5, MOD = 1e9+7, inf = 1e17;
vector> adj[mxN+1];
ll d[mxN+1], visited[mxN+1], cnt[mxN+1], M[mxN+1],mini[mxN+1];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n , m;
cin >> n >> m;
for(int i = 1;i<=m;i++)
{
int u , v, w;
cin >> u >> v >> w;
adj[u].push_back({v,w});
}
for(int i = 2;i<=n;i++)
{
d[i] = mini[i] = inf;
M[i] = -inf;
}
cnt[1] = 1;
mini[1] = 0;
M[1] = 0;
priority_queue> pq;
pq.push({0,1}); // distance -- node
while(!pq.empty())
{
int node = pq.top().second;
pq.pop();
if(visited[node]) continue;
visited[node] = true;
for(auto it : adj[node])
{
ll u = it.first, w = it.second;
ll dist = d[node] + w;
if(d[u] > dist)
{
d[u] = dist;
mini[u] = mini[node]+1;
M[u] = M[node]+1;
cnt[u] = cnt[node];
pq.push({-dist,u});
}
else if(d[u] == dist)
{
mini[u] = min(mini[u], mini[node]+1);
M[u] = max(M[u],M[node]+1);
cnt[u] = (cnt[u] + cnt[node]);
if(cnt[u] >= inf) cnt[u]%=MOD;
}
}
}
cout << d[n] << ' ' << cnt[n] % MOD << ' ' << mini[n] << ' ' << M[n];
return 0;
}