#include <bits/stdc++.h>
using namespace std;
const int MX = 1000005;
const int MD = 1000000007;
int append(long long a, int x) { return (a * 10LL + x) % MD; }
vector<pair<int, int>> neigh[MX];
bool vis[MX];
int val[MX];
vector<int> Q[MX];
int main() {
  int n, m;
  ignore = scanf("%d %d", &n, &m);
  int nxt = n + 1;
  for (int i = 1; i <= m; i++) {
    int u, v;
    ignore = scanf("%d %d", &u, &v);
    vector<int> t;
    int x = i;
    while (x) {
      t.push_back(x % 10);
      x /= 10;
    }
    reverse(t.begin(), t.end());
    int pr = u;
    for (int j = 0; j < (int)t.size() - 1; j++) {
      neigh[pr].emplace_back(nxt, t[j]);
      neigh[nxt].emplace_back(pr, t.end()[-j - 1]);
      pr = nxt++;
    }
    neigh[pr].emplace_back(v, t.back());
    neigh[v].emplace_back(pr, t[0]);
  }
  vis[1] = true;
  val[1] = 0;
  int L = 0, R = 0;
  Q[R++] = {1};
  while (L < R) {
    vector<int> cur = move(Q[L++]);
    static vector<int> next_verts[10];
    for (int x = 0; x < 10; x++) {
      next_verts[x].clear();
      for (int v : cur) {
        for (auto e : neigh[v]) {
          if (e.second != x) continue;
          if (vis[e.first]) continue;
          vis[e.first] = true;
          val[e.first] = append(val[v], x);
          next_verts[x].push_back(e.first);
        }
      }
    }
    for (int x = 0; x < 10; x++) {
      if (next_verts[x].empty()) continue;
      Q[R++] = move(next_verts[x]);
    }
  }
  for (int v = 2; v <= n; v++) {
    printf("%d\n", val[v]);
  }
}
