#include <bits/stdc++.h>
#define PREP(i, s, x) for(ll (i) = (s); (i) < (x); (i) ++)
#define REP(i, x) PREP(i, 0, x)
#define MREP(i, s, x) for(ll (i) = (s); (i) >= (x); (i) --)
#define MOD7 (1000000007LL)
#define MOD9 998244353LL
#define INF (1LL<<60)
typedef long long ll;
using namespace std;
using P = pair<ll, ll>;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

using graph = vector<vector<ll>>;

graph g, rev_g;
vector<bool> seen;
vector<ll> numbering;
vector<ll> scc; // 頂点番号がgroupのグループに属するか返す
vector<vector<ll>> group; // グループごとに属する頂点番号を格納

void dfs(ll v){
    seen[v] = true;
    for(auto next_v : g[v]){
        if(seen[next_v]) continue;
        dfs(next_v);
    }
    numbering.push_back(v);
    return;
}

void rev_dfs(ll v, ll num){
    seen[v] = true;
    group[num].push_back(v);
    scc[v] = num;
    for(auto next_v : rev_g[v]){
        if(seen[next_v]) continue;
        rev_dfs(next_v, num);
    }
}

int main(){
    ll n, m;
    cin >> n >> m;
    g.resize(n);
    rev_g.resize(n);
    REP(i, m){
        ll a, b;
        cin >> a >> b;
        a --, b --;
        g[a].push_back(b);
        rev_g[b].push_back(a);
    }

    seen.resize(n);
    REP(i, n){
        // 未探索
        seen[i] = false;
    }

    REP(v, n){
        if(seen[v] == false) dfs(v);
    }

    reverse(numbering.begin(), numbering.end());

    REP(i, n){
        seen[i] = false;
    }

    scc.resize(n);

    ll num = 0;
    for(auto v : numbering){
        if(seen[v] == false){
            group.push_back(vector<ll>());
            rev_dfs(v, num);
            num ++;
        }
    }

    REP(i, num){
        sort(group[i].begin(), group[i].end());
    }

    REP(v, n){
        ll i = scc[v];
        for(auto ite = group[i].begin(); ite < group[i].end(); ite ++){
            cout << (*ite) + 1;
            if(ite != group[i].end() - 1) cout << " ";
        }
        cout << endl;
    }

    return 0;
}
