#include <bits/stdc++.h>
int p[3000][3000];
int visited[3000];
struct pr {
  int v, p = -1;
};
bool compare_pair(pr a, pr b) { return (a.p > b.p); }
struct path {
  pr s[3], o[3];
} mp[3000];
int n = 0, m = 0;
using namespace std;
vector<vector<int> > g;
void unvisit() {
  for (int i = 0; i < n; i++) {
    visited[i] = 0;
  }
}
void disconnect() {
  for (int i = 0; i < n; i++) {
    p[i][i] = 0;
    for (int j = i + 1; j < n; j++) {
      p[i][j] = -1;
      p[j][i] = -1;
    }
  }
}
void bfs(int k) {
  queue<int> q;
  unvisit();
  q.push(k);
  visited[k] = 1;
  p[k][k] = 0;
  while (q.size()) {
    int v = q.front();
    q.pop();
    for (vector<int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
      if (visited[*it] == 0) {
        q.push(*it);
        p[k][*it] = p[k][v] + 1;
        visited[*it] = 1;
      }
    }
  }
}
int main() {
  int u, v;
  cin >> n >> m;
  disconnect();
  g.resize(n);
  for (int i = 0; i < m; i++) {
    cin >> u >> v;
    u--, v--;
    g[u].push_back(v);
  }
  for (int i = 0; i < n; i++) {
    bfs(i);
  }
  for (int i = 0; i < n; i++) {
    vector<pr> o(n);
    o[i].v = i;
    vector<pr> s(n);
    s[i].v = i;
    for (int j = 0; j < n; j++) {
      if (i != j) {
        o[j].v = j;
        o[j].p = p[i][j];
        s[j].v = j;
        s[j].p = p[j][i];
      }
    }
    sort(o.begin(), o.end(), compare_pair);
    sort(s.begin(), s.end(), compare_pair);
    mp[i].s[0] = s[0];
    mp[i].s[1] = s[1];
    mp[i].s[2] = s[2];
    mp[i].o[0] = o[0];
    mp[i].o[1] = o[1];
    mp[i].o[2] = o[2];
  }
  int max = 0;
  int a, b, c, d;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (i != j) {
        if (p[i][j] > 0) {
          int s_i = 0, o_i = 0;
          if (mp[i].s[s_i].v == j) {
            s_i++;
          }
          if (mp[j].o[o_i].v == i) {
            o_i++;
          }
          if (mp[i].s[s_i].v == mp[j].o[o_i].v) {
            int new_s = s_i + 1, new_o = o_i + 1;
            if (mp[i].s[new_s].v == j) {
              new_s++;
            }
            if (mp[j].o[new_o].v == i) {
              new_o++;
            }
            int move_s = mp[i].s[new_s].p + mp[j].o[o_i].p,
                move_o = mp[i].s[s_i].p + mp[j].o[new_o].p;
            if (move_s > move_o && move_s) {
              s_i = new_s;
            } else {
              o_i = new_o;
            }
          }
          int path = mp[i].s[s_i].p + p[i][j] + mp[j].o[o_i].p;
          if (path > max) {
            max = path;
            a = mp[i].s[s_i].v;
            b = i;
            c = j;
            d = mp[j].o[o_i].v;
          }
        }
        if (p[j][i] > 0) {
          int s_i = 0, o_i = 0;
          if (mp[j].s[s_i].v == i) {
            s_i++;
          }
          if (mp[i].o[o_i].v == j) {
            o_i++;
          }
          if (mp[j].s[s_i].v == mp[i].o[o_i].v) {
            int new_s = s_i + 1, new_o = o_i + 1;
            if (mp[j].s[new_s].v == i) {
              new_s++;
            }
            if (mp[i].o[new_o].v == j) {
              new_o++;
            }
            int move_s = mp[j].s[new_s].p + mp[i].o[o_i].p,
                move_o = mp[j].s[s_i].p + mp[i].o[new_o].p;
            if (move_s > move_o && move_s) {
              s_i = new_s;
            } else {
              o_i = new_o;
            }
          }
          int path = mp[j].s[s_i].p + p[j][i] + mp[i].o[o_i].p;
          if (path > max) {
            max = path;
            a = mp[j].s[s_i].v;
            b = j;
            c = i;
            d = mp[i].o[o_i].v;
          }
        }
      }
    }
  }
  cout << a + 1 << " " << b + 1 << " " << c + 1 << " " << d + 1 << endl;
  return 0;
}
