#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
const int INF = 0x3f3f3f3f;
int dis[N][N];
vector<int> nex[N];
vector<pair<int, int> > p[N], o[N];
int n, m;
void bfs(int s) {
  queue<int> q;
  q.push(s);
  dis[s][s] = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0, v; i < nex[u].size(); i++) {
      v = nex[u][i];
      if (dis[s][v] == -1) {
        dis[s][v] = dis[s][u] + 1;
        q.push(v);
      }
    }
  }
  for (int i = 0; i < n; i++)
    if (dis[s][i] != -1 && s != i) {
      o[s].push_back({dis[s][i], i});
      p[i].push_back({dis[s][i], s});
    }
}
void fd() {
  int a, b, c, d;
  for (int i = 0; i < n; i++) {
    sort(o[i].begin(), o[i].end(), greater<pair<int, int> >());
    sort(p[i].begin(), p[i].end(), greater<pair<int, int> >());
  }
  int mx = 3;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++)
      if (i != j && dis[i][j] != -1) {
        for (int i1 = 0, t1 = 0, u; i1 < p[i].size() && t1 < 2; i1++) {
          u = p[i][i1].second;
          if (u == i || u == j) continue;
          t1++;
          for (int j1 = 0, t2 = 0, v; j1 < o[j].size() && t2 < 2; j1++) {
            v = o[j][j1].second;
            if (v == i || v == j || v == u) continue;
            t2++;
            mx = max(mx, dis[i][j] + p[i][i1].first + o[j][j1].first);
            if (dis[i][j] + p[i][i1].first + o[j][j1].first >= mx) {
              mx = dis[i][j] + p[i][i1].first + o[j][j1].first;
              a = u + 1, b = i + 1, c = j + 1, d = v + 1;
            }
          }
        }
      }
  }
  printf("%d %d %d %d\n", a, b, c, d);
}
int main() {
  scanf("%d %d", &n, &m);
  memset(dis, -1, sizeof(dis));
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    nex[u].push_back(v);
  }
  for (int i = 0; i < n; i++) bfs(i);
  fd();
  return 0;
}
