#include <bits/stdc++.h>
using namespace std;
const int N = (int)1e6 + 7;
const int mod = (int)1e9 + 7;
int n, m, tot;
int d[N], ans[N];
vector<pair<int, int> > G[N];
vector<int> G2[N][10];
vector<int> V;
void solve(int u, int v, int x) {
  V.clear();
  for (int i = x; i; i /= 10) {
    V.push_back(i % 10);
  }
  reverse(V.begin(), V.end());
  int cur = u;
  for (int i = 0; i < V.size(); i++) {
    if (i == (int)V.size() - 1) {
      G[cur].push_back(make_pair(V[i], v));
    } else {
      tot++;
      G[cur].push_back(make_pair(V[i], tot));
      cur = tot;
    }
  }
  cur = v;
  for (int i = 0; i < V.size(); i++) {
    if (i == (int)V.size() - 1) {
      G[cur].push_back(make_pair(V[i], u));
    } else {
      tot++;
      G[cur].push_back(make_pair(V[i], tot));
      cur = tot;
    }
  }
}
void dfs(vector<int> &P) {
  vector<int> V;
  for (int i = 0; i <= 9; i++) {
    V.clear();
    for (auto &u : P) {
      for (auto &v : G2[u][i]) {
        if (~ans[v]) continue;
        ans[v] = (1LL * ans[u] * 10 + i) % mod;
        V.push_back(v);
      }
    }
    if (V.size()) dfs(V);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  tot = n;
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    solve(u, v, i);
  }
  for (int i = 1; i <= tot; i++) {
    d[i] = -1;
    ans[i] = -1;
  }
  d[1] = 0;
  queue<int> que;
  que.push(1);
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (auto &e : G[u]) {
      int v = e.second, w = e.first;
      if (d[v] == -1) {
        d[v] = d[u] + 1;
        G2[u][w].push_back(v);
        que.push(v);
      } else if (d[u] + 1 == d[v]) {
        G2[u][w].push_back(v);
      }
    }
  }
  ans[1] = 0;
  vector<int> V;
  V.push_back(1);
  dfs(V);
  for (int i = 2; i <= n; i++) {
    printf("%d\n", ans[i]);
  }
  return 0;
}
