#include <bits/stdc++.h>
using namespace std;
char buf[1 << 21], *p1 = buf, *p2 = buf;
template <class T>
void read(T &x) {
  x = 0;
  int c = getchar();
  int flag = 0;
  while (c < '0' || c > '9') flag |= (c == '-'), c = getchar();
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  if (flag) x = -x;
}
template <class T>
T _max(T a, T b) {
  return b < a ? a : b;
}
template <class T>
T _min(T a, T b) {
  return a < b ? a : b;
}
template <class T>
bool checkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <class T>
bool checkmin(T &a, T b) {
  return b < a ? a = b, 1 : 0;
}
const int inf = 0x3f3f3f3f;
int n, m;
vector<int> G[3005];
int dis[3005][3005];
int F[3005][3], rF[3005][3], D[3005][3];
int q[3005];
void add_edge(int x, int y) { G[x].push_back(y); }
void bfs(int S) {
  memset(dis[S], 0x3f, sizeof dis[S]);
  dis[S][S] = 0;
  int head = 1, tail = 0;
  q[++tail] = S;
  while (head <= tail) {
    int x = q[head++];
    for (int i = 0; i < (int)G[x].size(); ++i) {
      int to = G[x][i];
      if (dis[S][to] < inf) continue;
      dis[S][to] = dis[S][x] + 1;
      q[++tail] = to;
    }
  }
  for (int i = 1; i <= n; ++i)
    if (dis[S][i] == inf) dis[S][i] = -1;
}
void init() {
  memset(dis, -1, sizeof dis);
  read(n);
  read(m);
  for (int i = 1, u, v; i <= m; ++i) {
    read(u);
    read(v);
    add_edge(u, v);
  }
  for (int i = 1; i <= n; ++i) bfs(i);
  memset(D, 0, sizeof D);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j)
      if (i ^ j) {
        for (int k = 0; k < 3; ++k) {
          if (dis[i][j] > D[i][k]) {
            for (int o = 1; o >= k; --o) {
              D[i][o + 1] = D[i][o];
              F[i][o + 1] = F[i][o];
            }
            F[i][k] = j;
            D[i][k] = dis[i][j];
            break;
          }
        }
      }
  }
  memset(D, 0, sizeof D);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j)
      if (i ^ j) {
        if (dis[i][j] == 0) continue;
        for (int k = 0; k < 3; ++k) {
          if (dis[j][i] > D[i][k]) {
            for (int o = 1; o >= k; --o) {
              D[i][o + 1] = D[i][o];
              rF[i][o + 1] = rF[i][o];
            }
            rF[i][k] = j;
            D[i][k] = dis[j][i];
            break;
          }
        }
      }
  }
}
void solve() {
  int ans = 0, A = 0, B = 0, C = 0, E = 0;
  for (int x = 1; x <= n; ++x) {
    for (int y = 1; y <= n; ++y)
      if (y ^ x) {
        if (dis[x][y] < 0) continue;
        for (int i = 0; i < 3; ++i) {
          for (int j = 0; j < 3; ++j) {
            int z = rF[x][i], w = F[y][j];
            if (dis[z][x] <= 0 || dis[y][w] <= 0) continue;
            if (z == 0 || w == 0 || z == y || z == w || w == x) continue;
            int r = dis[z][x] + dis[x][y] + dis[y][w];
            if (checkmax(ans, r)) A = z, B = x, C = y, E = w;
          }
        }
      }
  }
  cerr << "ans"
       << " = " << ans << endl;
  printf("%d %d %d %d\n", A, B, C, E);
}
int main() {
  init();
  solve();
  return 0;
}
