#include <bits/stdc++.h>
using namespace std;
struct PairDist {
  int i, j;
  int d;
};
bool operator<(const PairDist& l, const PairDist& r) { return l.d < r.d; }
struct TDist {
  int i;
  int d;
};
bool operator<(const TDist& l, const TDist& r) { return l.d > r.d; }
struct Ret {
  int a, b, c, d;
  int val;
};
bool operator<(const Ret& l, const Ret& r) { return l.val < r.val; }
int main(int argc, const char* argv[]) {
  int n, m;
  cin >> n >> m;
  n++;
  vector<std::vector<int> > edges(n);
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    edges[u].push_back(v);
  }
  vector<std::vector<int> > dist(n);
  for (typeof((dist).end()) it = (dist).begin(); it != (dist).end(); ++it)
    it->assign(n, -1);
  for (int i = 0; i < n; i++) {
    std::vector<int>& d = dist[i];
    queue<int> q;
    d[i] = 0;
    q.push(i);
    while (!q.empty()) {
      int id = q.front();
      int a = d[id] + 1;
      q.pop();
      for (typeof((edges[id]).end()) it = (edges[id]).begin();
           it != (edges[id]).end(); ++it)
        if (d[*it] < 0) {
          d[*it] = a;
          q.push(*it);
        }
    }
  }
  vector<PairDist> sdists(n * n);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      PairDist& pd = sdists[i * n + j];
      pd.i = i;
      pd.j = j;
      pd.d = dist[i][j];
    }
  vector<vector<TDist> > in(n);
  vector<vector<TDist> > out(n);
  for (int i = 0; i < n; i++) {
    in[i].resize(n);
    out[i].resize(n);
    for (int j = 0; j < n; j++) {
      in[i][j].i = j;
      in[i][j].d = dist[j][i];
      out[i][j].i = j;
      out[i][j].d = dist[i][j];
    }
    sort(in[i].begin(), in[i].end());
    sort(out[i].begin(), out[i].end());
  }
  Ret best;
  best.val = 0;
  for (typeof((sdists).end()) it = (sdists).begin(); it != (sdists).end(); ++it)
    if (it->d > 0) {
      Ret t;
      t.b = it->i;
      t.c = it->j;
      bool good;
      good = true;
      for (typeof((in[t.b]).end()) jt = (in[t.b]).begin();
           jt != (in[t.b]).end(); ++jt) {
        if (jt->d <= 0) {
          good = false;
          break;
        }
        if (jt->i != t.b && jt->i != t.c) {
          t.a = jt->i;
          break;
        }
      }
      for (typeof((out[t.c]).end()) jt = (out[t.c]).begin();
           jt != (out[t.c]).end(); ++jt) {
        if (jt->d <= 0) {
          good = false;
          break;
        }
        if (jt->i != t.b && jt->i != t.c && jt->i != t.a) {
          t.d = jt->i;
          break;
        }
      }
      if (good) {
        t.val = dist[t.a][t.b] + dist[t.b][t.c] + dist[t.c][t.d];
        if (best < t) best = t;
      }
      good = true;
      for (typeof((out[t.c]).end()) jt = (out[t.c]).begin();
           jt != (out[t.c]).end(); ++jt) {
        if (jt->d <= 0) {
          good = false;
          break;
        }
        if (jt->i != t.b && jt->i != t.c) {
          t.d = jt->i;
          break;
        }
      }
      for (typeof((in[t.b]).end()) jt = (in[t.b]).begin();
           jt != (in[t.b]).end(); ++jt) {
        if (jt->d <= 0) {
          good = false;
          break;
        }
        if (jt->i != t.b && jt->i != t.c && jt->i != t.d) {
          t.a = jt->i;
          break;
        }
      }
      if (good) {
        t.val = dist[t.a][t.b] + dist[t.b][t.c] + dist[t.c][t.d];
        if (best < t) best = t;
      }
    }
  cout << best.a << ' ' << best.b << ' ' << best.c << ' ' << best.d << endl;
  return 0;
}
