#include <bits/stdc++.h>
using namespace std;
void fre() {
  freopen("c://test//input.in", "r", stdin);
  freopen("c://test//output.out", "w", stdout);
}
template <class T1, class T2>
inline void gmax(T1 &a, T2 b) {
  if (b > a) a = b;
}
template <class T1, class T2>
inline void gmin(T1 &a, T2 b) {
  if (b < a) a = b;
}
const int N = 3003, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n, m;
int x, y;
vector<int> a[2][N];
int d[2][N][N];
int f[2][N][3];
void bfs(vector<int> a[N], int d[N], int f[3], int st) {
  queue<int> q;
  q.push(st);
  d[st] = 0;
  f[0] = f[1] = f[2] = st;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    f[2] = f[1];
    f[1] = f[0];
    f[0] = x;
    for (int i = a[x].size() - 1; ~i; --i) {
      int y = a[x][i];
      if (d[y] == -1) {
        d[y] = d[x] + 1;
        q.push(y);
      }
    }
  }
}
int check(int u, int x, int y, int v) {
  if (u == x || u == y || u == v || v == x || v == y) return 0;
  return d[0][u][x] + d[0][x][y] + d[0][y][v];
}
struct P {
  int a, b, c, d;
} p;
int main() {
  while (~scanf("%d%d", &n, &m)) {
    for (int i = 1; i <= n; ++i) a[0][i].clear(), a[1][i].clear();
    for (int i = 1; i <= m; ++i) {
      scanf("%d%d", &x, &y);
      a[0][x].push_back(y);
      a[1][y].push_back(x);
    }
    memset(d, -1, sizeof(d));
    for (int i = 1; i <= n; ++i) {
      bfs(a[0], d[0][i], f[0][i], i);
      bfs(a[1], d[1][i], f[1][i], i);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= n; ++j)
        if (i != j && ~d[0][i][j]) {
          for (int u = 0; u < 3; ++u) {
            for (int v = 0; v < 3; ++v) {
              int tmp = check(f[1][i][u], i, j, f[0][j][v]);
              if (tmp > ans) {
                ans = tmp;
                p = {f[1][i][u], i, j, f[0][j][v]};
              }
            }
          }
        }
    }
    printf("%d %d %d %d\n", p.a, p.b, p.c, p.d);
  }
  return 0;
}
