#include <bits/stdc++.h>
using namespace std;
void get_costs(vector<vector<int>> &adj, vector<vector<int>> &dist,
               vector<vector<int>> &furthest) {
  int n = adj.size();
  for (int u = 0; u < n; ++u) {
    vector<int> &distu = dist[u];
    queue<int> que;
    for (distu[u] = 0, que.push(u); !que.empty(); que.pop()) {
      int v = que.front();
      for (int w : adj[v])
        if (distu[w] == -1) {
          distu[w] = 1 + distu[v];
          que.push(w);
        }
    }
  }
  const int maxk = 4;
  using node = pair<int, int>;
  vector<vector<node>> bests(n);
  for (int u = 0; u < n; ++u)
    for (int v = 0; v < n; ++v)
      if (dist[u][v] > 0) {
        bests[u].insert(lower_bound(bests[u].begin(), bests[u].end(),
                                    node(dist[u][v], v), greater<node>()),
                        node(dist[u][v], v));
        if (bests[u].size() >= maxk) bests[u].pop_back();
      }
  for (int u = 0; u < n; ++u)
    for (auto &nod : bests[u]) furthest[u].push_back(nod.second);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<vector<int>> adj(n), radj(n);
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    adj[--u].push_back(--v);
    radj[v].push_back(u);
  }
  vector<vector<int>> dist(n, vector<int>(n, -1)), rdist(n, vector<int>(n, -1));
  vector<vector<int>> furthest(n), rfurthest(n);
  get_costs(adj, dist, furthest);
  get_costs(radj, rdist, rfurthest);
  auto get_cost = [&](int a, int b, int c, int d) {
    return dist[a][b] + dist[b][c] + dist[c][d];
  };
  int a = 0, b = 0, c = 0, d = 0;
  for (int u = 0; u < n; ++u)
    for (int v = 0; v < n; ++v)
      if (dist[u][v] > 0)
        for (int w : rfurthest[u])
          for (int z : furthest[v])
            if (w != v && z != u && w != z &&
                get_cost(a, b, c, d) < get_cost(w, u, v, z))
              a = w, b = u, c = v, d = z;
  for (int u : {a, b, c, d}) cout << u + 1 << " ";
  cout << '\n';
  return 0;
}
