#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MULTITEST 0
#define debug(x) cerr << "Line " << __LINE__ << ": " << #x << "=" << (x) << endl;
#define debugv(v) cerr << "Line " << __LINE__ << ": " << #v << " [ "; for(auto _i:v) cerr << _i << " "; cerr << "]\n";
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
void solve() {
// Write your code here
int n, m; cin >> n >> m;
vector<vector<int>> adj(n), rev_adj(n);
rep(i,0,m) {
int a, b; cin >> a >> b;
adj[a].push_back(b);
rev_adj[b].push_back(a);
}
auto djikstra = [&](vector<vector<int>> &adja, int src) {
vi dist(n, INT_MAX);
dist[src] = 0;
priority_queue<array<int, 2>, vector<array<int, 2>>, greater<array<int, 2>>> pq;
pq.push({0, src});
while (!pq.empty()) {
auto cur = pq.top(); pq.pop();
if (cur[0] != dist[cur[1]]) continue;
for (auto &nxt: adja[cur[1]]) {
int newD = cur[0] + 1;
if (newD < dist[nxt]) {
dist[nxt] = newD;
pq.push({newD, nxt});
}
}
}
return dist;
};
vi distToZero = djikstra(adj, 0), distToN = djikstra(rev_adj, n - 1);
vector<array<int, 2>> nodes;
map<int, vi> mp;
for (int i = 0; i < n - 1; i++) mp[distToN[i]].push_back(i);
vi ans(n, -1);
for (auto &[k, L]: mp) {
for (auto &v: L) {
// debug(v);
ans[v] = max(distToN[v], distToZero[v]);
}
if (k > 1) {
for (auto &v: L) {
int cur = INT_MAX;
for (auto &u: adj[v]) {
if (ans[u] == -1) continue;
if (cur == INT_MAX) cur = ans[u];
else cur = min(ans[u], cur);
}
assert(cur != INT_MAX);
cur++;
ans[v] = max(ans[v], cur);
}
}
}
for (int i = 0; i < n - 1; i++) cout << ans[i] << " ";
cout << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
cin.exceptions(cin.failbit);
int t;
if(MULTITEST) cin >> t;
else t = 1;
while (t--) {
solve();
}
}