#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10, inf = 0x3f3f3f3f, mod = 1e9 + 7;
int hd[N], ne, n, m, dp[N], tot, buf[N], C[10];
struct E {
  int u, v, c, nxt;
} e[N << 1];
void addedge(int u, int v, int c) { e[ne] = {u, v, c, hd[u]}, hd[u] = ne++; }
queue<int> q;
vector<int> vec, vec2;
int upd(int u, int x) {
  if (!~dp[u]) {
    dp[u] = x, q.push(u);
    return 1;
  }
  return 0;
}
void bfs() {
  memset(dp, -1, sizeof dp);
  while (q.size()) q.pop();
  upd(1, 0), q.push(-1);
  while (q.size()) {
    vec.clear();
    for (; q.front() != -1; q.pop()) vec.push_back(q.front());
    q.pop();
    vec2.clear();
    for (int u : vec)
      for (int i = hd[u]; ~i; i = e[i].nxt) vec2.push_back(i);
    for (int i = 0; i <= 9; ++i) C[i] = 0;
    for (int i = 0; i < vec2.size(); ++i) ++C[e[vec2[i]].c];
    for (int i = 1; i <= 9; ++i) C[i] += C[i - 1];
    for (int i = 0; i < vec2.size(); ++i) buf[--C[e[vec2[i]].c]] = vec2[i];
    for (int i = 0, j, k; i < vec2.size(); i = j) {
      for (j = i; j < vec2.size() && e[buf[j]].c == e[buf[i]].c; ++j)
        ;
      int f = 0;
      for (k = i; k < j; ++k)
        if (upd(e[buf[k]].v,
                ((long long)dp[e[buf[k]].u] * 10 + e[buf[k]].c) % mod))
          f = 1;
      if (f) q.push(-1);
    }
  }
}
int main() {
  memset(hd, -1, sizeof hd), ne = 0;
  scanf("%d%d", &n, &m);
  tot = n;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    int c = i;
    if (c / 10) {
      addedge(++tot, u, c % 10), addedge(++tot, v, c % 10), c /= 10;
      for (; c / 10; c /= 10)
        ++tot, addedge(tot, tot - 2, c % 10), ++tot,
            addedge(tot, tot - 2, c % 10);
      addedge(v, tot - 1, c), addedge(u, tot, c);
    } else
      addedge(u, v, c), addedge(v, u, c);
  }
  bfs();
  for (int i = 2; i <= n; ++i) printf("%d\n", dp[i]);
  return 0;
}
