#include <bits/stdc++.h>
using namespace std;
const int NINF = -0x1000000, MAXN = 3000;
vector<int> graph[MAXN];
int dist[MAXN][MAXN], f[3][MAXN], b[3][MAXN], arr[MAXN], n, m, v, x, y, z, w, s;
bool cmpf(int a, int b) { return dist[a][v] > dist[b][v]; }
bool cmpb(int a, int b) { return dist[v][a] > dist[v][b]; }
void bfs(int v) {
  queue<int> q;
  dist[v][v] = 0;
  q.push(v);
  while (!q.empty()) {
    int p = q.front();
    q.pop();
    for (int i = 0; i < (int)graph[p].size(); i++)
      if (dist[v][graph[p][i]] == NINF) {
        dist[v][graph[p][i]] = dist[v][p] + 1;
        q.push(graph[p][i]);
      }
  }
}
void compsol(int a, int b, int c, int d) {
  if (a == b || a == c || a == d || b == c || b == d || c == d) return;
  int p = dist[a][b] + dist[b][c] + dist[c][d];
  if (s < p) {
    s = p;
    x = a;
    y = b;
    z = c;
    w = d;
  }
}
int main() {
  for (int i = 0; i < MAXN; i++)
    for (int j = 0; j < MAXN; j++) dist[i][j] = NINF;
  s = NINF;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    graph[--a].push_back(--b);
  }
  for (int i = 0; i < n; i++) {
    arr[i] = i;
    bfs(i);
  }
  for (int i = 0; i < n; i++) {
    v = i;
    sort(arr, arr + n, cmpf);
    for (int j = 0; j < 3; j++) f[j][i] = arr[j];
    sort(arr, arr + n, cmpb);
    for (int j = 0; j < 3; j++) b[j][i] = arr[j];
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < 3; k++)
        for (int l = 0; l < 3; l++) compsol(f[k][i], i, j, b[l][j]);
  printf("%d %d %d %d\n", x + 1, y + 1, z + 1, w + 1);
  return 0;
}
