#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> a) {
  out << a.first << " " << a.second;
  return out;
}
template <typename T, typename T1>
T maxs(T &a, T1 b) {
  if (b > a) a = b;
  return a;
}
template <typename T, typename T1>
T mins(T &a, T1 b) {
  if (b < a) a = b;
  return a;
}
const long long N = 2e5 + 5;
long long lp[N + 1];
long long pr[N];
long long t = 0;
long long cnt = 0;
void sieve() {
  for (long long i = 2; i < N; ++i) {
    if (lp[i] == 0) {
      lp[i] = i;
      pr[t++] = i;
    }
    for (long long j = 0; j < t && pr[j] <= lp[i] && i * pr[j] < N; ++j)
      lp[i * pr[j]] = pr[j];
  }
}
struct node {
  pair<long long, long long> a;
  void merge(node &n1, node &n2) { this->a = min(n1.a, n2.a); }
};
template <typename node>
struct segtree {
  node t[4 * N];
  long long tl[4 * N];
  long long tr[4 * N];
  void build(long long v, long long start, long long end) {
    tl[v] = start;
    tr[v] = end;
    if (start == end) {
      t[v].a = {lp[start], start};
    } else {
      long long m = (start + end) / 2;
      build(2 * v, start, m);
      build(2 * v + 1, m + 1, end);
      t[v].merge(t[2 * v], t[2 * v + 1]);
    }
  }
  pair<long long, long long> query(long long v, long long l, long long r) {
    if (tr[v] < l || tl[v] > r) return {1e9, 1e9};
    if (l <= tl[v] && tr[v] <= r) {
      return t[v].a;
    }
    pair<long long, long long> a = query(2 * v, l, r);
    pair<long long, long long> b = query(2 * v + 1, l, r);
    return min(a, b);
  }

 public:
  pair<long long, long long> query(long long l, long long r) {
    return query(1, l, r);
  }
};
segtree<node> seg;
map<long long, long long> mp;
vector<long long> fac[N];
vector<long long> mul[N];
long long solve() {
  long long n, m, l, r;
  cin >> n >> m >> l >> r;
  seg.build(1, 2, 2e5);
  long long sl = max(2LL, l);
  long long sr = min(m, r);
  long long k = 1;
  while (k < n && sl > sr) {
    k++;
    cout << -1 << "\n";
    sl = max(2LL, l / k + (l % k != 0));
    sr = min(m, r / k);
  }
  for (long long i = sl; i <= sr; i++) {
    for (auto j : fac[i]) mp[j]++;
  }
  auto del = [&](long long first) {
    for (auto j : fac[first]) {
      mp[j]--;
      if (mp[j] == 0) mp.erase(j);
    }
  };
  auto add = [&](long long first) {
    for (auto j : fac[first]) {
      mp[j]++;
    }
  };
  auto get = [&](long long l, long long a) {
    long long idx =
        lower_bound(mul[a].begin(), mul[a].end(), l) - mul[a].begin();
    return mul[a][idx];
  };
  for (long long i = k; i < n + 1; i++) {
    long long L = 2;
    maxs(L, l / i + (l % i != 0));
    long long R = m;
    mins(R, r / i);
    while (sl > L) {
      add(--sl);
    }
    while (sr > R) {
      del(sr--);
    }
    if (L > R) {
      cout << -1 << "\n";
      continue;
    }
    auto s = seg.query(L, R);
    if (s.first * i <= n) {
      cout << i << " " << s.second << " " << i * s.first << " "
           << s.second / s.first << "\n";
    } else {
      long long x2, y2, y1;
      bool found = 0;
      for (auto j : fac[i]) {
        auto itr = mp.upper_bound(j);
        if (itr != mp.end()) {
          long long val = (i / j) * itr->first;
          if (val <= n) {
            found = 1;
            x2 = val;
            y1 = get(L, itr->first);
            y2 = (i * y1) / x2;
            break;
          }
        }
      }
      if (!found)
        cout << -1 << "\n";
      else
        cout << i << " " << y1 << " " << x2 << " " << y2 << "\n";
    }
  }
  return 0;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  for (long long i = 2; i <= 2e5; i++) {
    for (long long j = i; j <= 2e5; j += i) {
      fac[j].push_back(i);
      mul[i].push_back(j);
    }
  }
  sieve();
  long long t = 1;
  while (t--) {
    solve();
  }
  return 0;
}
