#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;
const int N = 100005 * 10;
vector<pair<int, int>> g[N];
int ans[N];
int vis[N];
int prv[N];
vector<int> nx[10];
int n;
void solve() {
  queue<vector<int>> q;
  q.push({1});
  vis[1] = 1;
  while (!q.empty()) {
    vector<int> vec = q.front();
    q.pop();
    for (int u : vec) {
      for (auto [v, w] : g[u])
        if (!vis[v]) {
          if (prv[v] == -1 or w < prv[v]) {
            ans[v] = int((10LL * ans[u] + w) % mod);
            prv[v] = w;
            nx[w].push_back(v);
          }
        }
    }
    for (int d = 0; d < 10; d++) {
      int j = 0;
      for (int i = 0; i < (int)nx[d].size(); i++) {
        if (prv[nx[d][i]] == d) {
          vis[nx[d][i]] = 1;
          nx[d][j++] = nx[d][i];
        }
      }
      nx[d].resize(j);
      if (!nx[d].empty()) {
        q.emplace(move(nx[d]));
      }
      nx[d].clear();
    }
  }
}
int main() {
  memset(prv, -1, sizeof prv);
  int m;
  scanf("%d %d", &n, &m);
  int ne = n + 1;
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    vector<int> vec;
    int x = i / 10;
    while (x) {
      vec.push_back(x % 10);
      x /= 10;
    }
    reverse(vec.begin(), vec.end());
    int last = u;
    for (int dig : vec) {
      g[last].push_back({ne, dig});
      last = ne;
      ne++;
    }
    g[last].push_back({v, i % 10});
    last = v;
    for (int dig : vec) {
      g[last].push_back({ne, dig});
      last = ne;
      ne++;
    }
    g[last].push_back({u, i % 10});
  }
  for (int i = 1; i < ne; i++) {
    sort(g[i].begin(), g[i].end(), [](pair<int, int> a, pair<int, int> b) {
      return a.second < b.second;
    });
  }
  solve();
  for (int i = 2; i <= n; i++) {
    printf("%d\n", ans[i]);
  }
}
