#include <bits/stdc++.h>
using namespace std;
int gcd(int x, int y) { return (!y ? x : gcd(y, x % y)); }
const int N = 1e6 + 10, M = 20, C = 10, mod = 1e9 + 7;
string st[N];
vector<pair<int, int> > adj[N];
int d[N];
void dij(int x) {
  memset(d, 63, sizeof d);
  d[x] = 0;
  set<pair<int, int> > s;
  s.insert({d[x], x});
  while (s.size()) {
    auto t = *s.begin();
    s.erase(t);
    int v = t.second;
    for (auto e : adj[v]) {
      int u = e.first, id = e.second;
      if (d[v] + st[id].size() < d[u]) {
        s.erase({d[u], u});
        d[u] = d[v] + st[id].size();
        s.insert({d[u], u});
      }
    }
  }
}
int ver[N], lst[N], val[N], upd[N];
int h[N], par[M][N];
void init(int v, int p, int c) {
  val[v] = (10LL * val[p] + c) % mod;
  par[0][v] = p;
  lst[v] = c;
  h[v] = h[p] + 1;
  for (int i = 1; i < M; i++) par[i][v] = par[i - 1][par[i - 1][v]];
}
int ec = 1, nxt[C][N];
int ins(int v, string s) {
  for (int i = 0; i < s.size(); i++) {
    int x = s[i] - '0';
    if (nxt[x][v] == -1) {
      nxt[x][v] = ec;
      init(ec, v, x);
      v = ec++;
    } else
      v = nxt[x][v];
  }
  return v;
}
int get(int v, int k) {
  for (int i = 0; i < M; i++)
    if (k >> i & 1) v = par[i][v];
  return v;
}
int lca(int u, int v) {
  if (h[u] < h[v]) swap(u, v);
  u = get(u, h[u] - h[v]);
  if (u == v) return u;
  for (int i = M - 1; i >= 0; i--)
    if (par[i][v] != par[i][u]) {
      u = par[i][u];
      v = par[i][v];
    }
  return par[0][v];
}
bool best(int u, int v) {
  int p = lca(u, v);
  int u1 = get(u, h[u] - h[p] - 1);
  int v1 = get(v, h[v] - h[p] - 1);
  return lst[u1] < lst[v1];
}
void mk(int v) {
  for (auto e : adj[v]) {
    int u = e.first, id = e.second;
    if (d[u] > d[v]) upd[id] = ins(ver[v], st[id]);
  }
}
int32_t main() {
  ios::sync_with_stdio(0), cin.tie(0);
  for (int i = 1; i < N; i++) st[i] = st[i / 10] + char('0' + i % 10);
  memset(nxt, -1, sizeof nxt);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back({v, i});
    adj[v].push_back({u, i});
  }
  dij(1);
  mk(1);
  vector<pair<int, int> > p;
  for (int i = 2; i <= n; i++) p.push_back({d[i], i});
  sort(p.begin(), p.end());
  for (auto t : p) {
    int v = t.second;
    int b = -1;
    for (auto e : adj[v]) {
      int u = e.first, id = e.second;
      if (d[u] + st[id].size() == d[v]) {
        if (b == -1 || best(upd[id], b)) b = upd[id];
      }
    }
    ver[v] = b;
    mk(v);
  }
  for (int i = 2; i <= n; i++) cout << val[ver[i]] << '\n';
}
