#include <bits/stdc++.h>
inline long long read() {
  long long x = 0;
  char c = getchar(), f = 1;
  for (; c < '0' || '9' < c; c = getchar())
    if (c == '-') f = -1;
  for (; '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
inline void write(long long x) {
  static char buf[20];
  int len = 0;
  if (x < 0) putchar('-'), x = -x;
  for (; x; x /= 10) buf[len++] = x % 10 + '0';
  if (!len)
    putchar('0');
  else
    while (len) putchar(buf[--len]);
}
inline void writesp(long long x) {
  write(x);
  putchar(' ');
}
inline void writeln(long long x) {
  write(x);
  putchar('\n');
}
struct edge {
  int to, nxt;
} e[2 * 3010];
int x[2 * 3010], y[2 * 3010];
int dis1[3010][3010], dis2[3010][3010];
int fir[3010], mx1[3010][3], mx2[3010][3];
int n, m, tot;
int ans, A, B, C, D;
inline void add_edge(int x, int y) {
  e[tot].to = y;
  e[tot].nxt = fir[x];
  fir[x] = tot++;
}
void bfs(int S, int* dis) {
  static int q[3010], vis[3010];
  for (int i = 1; i <= n; i++) vis[i] = 0, dis[i] = 0x3f3f3f3f;
  int h = 1, t = 1;
  q[1] = S;
  vis[S] = 1;
  dis[S] = 0;
  while (h <= t) {
    int now = q[h++];
    for (int i = fir[now]; ~i; i = e[i].nxt)
      if (!vis[e[i].to]) {
        dis[e[i].to] = dis[now] + 1;
        q[++t] = e[i].to;
        vis[e[i].to] = 1;
      }
  }
  for (int i = 1; i <= n; i++)
    if (dis[i] == 0x3f3f3f3f) dis[i] = -1;
}
void update(int p, int q, int r, int s) {
  if (!(p && q && r && s)) return;
  if (dis1[p][q] + dis1[q][r] + dis1[r][s] > ans) {
    ans = dis1[p][q] + dis1[q][r] + dis1[r][s];
    A = p;
    B = q;
    C = r;
    D = s;
  }
}
int main() {
  n = read();
  m = read();
  memset(fir, 255, sizeof(fir));
  tot = 0;
  for (int i = 1; i <= m; i++) {
    x[i] = read();
    y[i] = read();
    add_edge(x[i], y[i]);
  }
  for (int i = 1; i <= n; i++) {
    bfs(i, dis1[i]);
    mx1[i][0] = mx1[i][1] = mx1[i][2] = 0;
    for (int j = 1; j <= n; j++)
      if (dis1[i][j] > dis1[i][mx1[i][0]])
        mx1[i][2] = mx1[i][1], mx1[i][1] = mx1[i][0], mx1[i][0] = j;
      else if (dis1[i][j] > dis1[i][mx1[i][1]])
        mx1[i][2] = mx1[i][1], mx1[i][1] = j;
      else if (dis1[i][j] > dis1[i][mx1[i][2]])
        mx1[i][2] = j;
  }
  memset(fir, 255, sizeof(fir));
  tot = 0;
  for (int i = 1; i <= m; i++) add_edge(y[i], x[i]);
  for (int i = 1; i <= n; i++) {
    bfs(i, dis2[i]);
    mx2[i][0] = mx2[i][1] = mx2[i][2] = 0;
    for (int j = 1; j <= n; j++)
      if (dis2[i][j] > dis2[i][mx2[i][0]])
        mx2[i][2] = mx2[i][1], mx2[i][1] = mx2[i][0], mx2[i][0] = j;
      else if (dis2[i][j] > dis2[i][mx2[i][1]])
        mx2[i][2] = mx2[i][1], mx2[i][1] = j;
      else if (dis2[i][j] > dis2[i][mx2[i][2]])
        mx2[i][2] = j;
  }
  ans = 0;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      if (dis1[i][j] <= 0) continue;
      int p1 = 0, p2 = 0;
      if (mx2[i][p1] == j) ++p1;
      if (mx1[j][p2] == i) ++p2;
      if (mx2[i][p1] != mx1[j][p2])
        update(mx2[i][p1], i, j, mx1[j][p2]);
      else {
        ++p1;
        if (mx2[i][p1] == j)
          update(mx2[i][p1 + 1], i, j, mx1[j][p2]);
        else
          update(mx2[i][p1], i, j, mx1[j][p2]);
        --p1;
        ++p2;
        if (mx1[j][p2] == i)
          update(mx2[i][p1], i, j, mx1[j][p2 + 1]);
        else
          update(mx2[i][p1], i, j, mx1[j][p2]);
        --p2;
      }
    }
  writesp(A);
  writesp(B);
  writesp(C);
  writeln(D);
  return 0;
}
