#include <bits/stdc++.h>
using namespace std;
const int nmax = 3005;
const int INF = (1 << 29);
int n, m, distMin[nmax][nmax], dist[nmax], rez[5], ans = -1;
vector<pair<int, int> > v[nmax], vIn[nmax];
vector<int> gf[nmax];
void dijkstra(int sursa) {
  set<pair<int, int> > mySet;
  for (int i = 0; i <= n; ++i) {
    dist[i] = INF;
  }
  dist[sursa] = 0;
  mySet.insert(make_pair(0, sursa));
  for (; !mySet.empty();) {
    int node = mySet.begin()->second;
    int cost = mySet.begin()->first;
    mySet.erase(mySet.begin());
    for (auto &vc : gf[node]) {
      if (dist[vc] > dist[node] + 1) {
        dist[vc] = dist[node] + 1;
        mySet.insert(make_pair(dist[vc], vc));
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (dist[i] == INF) {
      dist[i] = -1;
    }
  }
  for (int i = 1; i <= n; ++i) {
    distMin[sursa][i] = dist[i];
    v[sursa].push_back(make_pair(dist[i], i));
    vIn[i].push_back(make_pair(dist[i], sursa));
  }
  sort(v[sursa].begin(), v[sursa].end());
  reverse(v[sursa].begin(), v[sursa].end());
}
void muta(int sursa, int &i, int x) {
  for (; v[sursa][i].second == sursa || v[sursa][i].second == x; ++i)
    ;
}
void mutaIn(int sursa, int &i, int x) {
  for (; vIn[sursa][i].second == sursa || vIn[sursa][i].second == x; ++i)
    ;
}
void updateAns(int currentCost, int elSt, int i, int j, int elDr) {
  if (currentCost > ans) {
    ans = currentCost;
    rez[1] = elSt;
    rez[2] = i;
    rez[3] = j;
    rez[4] = elDr;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int x, y;
    cin >> x >> y;
    gf[x].push_back(y);
  }
  for (int i = 1; i <= n; ++i) {
    dijkstra(i);
  }
  for (int i = 1; i <= n; ++i) {
    sort(vIn[i].begin(), vIn[i].end());
    reverse(vIn[i].begin(), vIn[i].end());
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (i == j) {
        continue;
      }
      if (distMin[i][j] == -1) {
        continue;
      }
      int idSt = 0;
      int idDr = 0;
      mutaIn(i, idSt, j);
      muta(j, idDr, i);
      int elSt = vIn[i][idSt].second;
      int elDr = v[j][idDr].second;
      if (elSt != elDr) {
        int currentCost = distMin[i][j] + distMin[elSt][i] + distMin[j][elDr];
        if (currentCost > ans) {
          ans = currentCost;
          rez[1] = elSt;
          rez[2] = i;
          rez[3] = j;
          rez[4] = elDr;
        }
      } else {
        int idSt2 = idSt + 1;
        mutaIn(i, idSt2, j);
        elSt = vIn[i][idSt2].second;
        elDr = v[j][idDr].second;
        int currentCost = distMin[i][j] + distMin[elSt][i] + distMin[j][elDr];
        updateAns(currentCost, elSt, i, j, elDr);
        idDr++;
        muta(j, idDr, j);
        elSt = vIn[i][idSt].second;
        elDr = v[j][idDr].second;
        currentCost = distMin[i][j] + distMin[elSt][i] + distMin[j][elDr];
        updateAns(currentCost, elSt, i, j, elDr);
      }
    }
  }
  cout << rez[1] << " " << rez[2] << " " << rez[3] << " " << rez[4] << "\n";
  return 0;
}
