#include <bits/stdc++.h>
using LL = long long;
using VI = std::vector<int>;
struct ST {
  VI qs;
  VI lazy;
  int p2;
  ST(int size) {
    p2 = 1;
    while (p2 < size) p2 <<= 1;
    qs = VI(p2 + size, std::numeric_limits<int>::max());
    lazy = qs;
  }
  ST(VI& source) : ST(int(source.size())) {
    int n = int(source.size());
    for (int i = 0; i < n; ++i) qs[p2 + i] = source[i];
    for (int i = (p2 + n) / 2 - 1; i >= 0; --i)
      qs[i] = std::min(qs[2 * i], qs[2 * i + 1]);
  }
  int query(int L, int R) const {
    int acc = std::numeric_limits<int>::max();
    L += p2;
    R += p2;
    {
      int cL = L;
      int cR = R;
      while (cL) {
        acc = std::min(acc, lazy[cL]);
        acc = std::min(acc, lazy[cR - 1]);
        cL >>= 1;
        cR = (cR + 1) >> 1;
      }
    }
    while (L < R) {
      acc = std::min(acc, qs[L]);
      acc = std::min(acc, qs[R - 1]);
      L = (L + 1) >> 1;
      R >>= 1;
    }
    return acc;
  }
  void update(int L, int R, int v) {
    if (L == R) return;
    L += p2;
    R += p2;
    auto touch = [&](int ix) {
      lazy[ix] = std::min(v, lazy[ix]);
      qs[ix] = std::min(qs[ix], lazy[ix]);
      return;
    };
    auto prop = [&](int ix) { qs[ix] = std::min(qs[2 * ix], qs[2 * ix + 1]); };
    {
      int Li = L;
      int Ri = R;
      while (Li < Ri) {
        touch(Li);
        touch(Ri - 1);
        Li = (Li + 1) >> 1;
        Ri >>= 1;
        L >>= 1;
        R = (R + 1) >> 1;
        prop(L);
        prop(R);
      }
    }
    while (L) {
      prop(L);
      L >>= 1;
    }
    return;
  }
};
struct VerifyingST {
  ST inner;
  VI arr;
  VerifyingST(int size)
      : inner{size}, arr{VI(size, std::numeric_limits<int>::max())} {}
  VerifyingST(VI& source) : inner{source}, arr{source} {}
  int query(int L, int R) const {
    int sr = inner.query(L, R);
    int res = std::numeric_limits<int>::max();
    for (int ix = L; ix < R; ++ix) res = std::min(res, arr[ix]);
    if (sr != res) {
      std::cerr << "query(" << L << ", " << R << ") called" << std::endl;
      std::cerr << "actual result was " << sr << std::endl;
      std::cerr << "expected result was " << res << std::endl;
    }
    assert(sr == res);
    return res;
  }
  void update(int L, int R, int v) {
    std::cerr << "update(" << L << ", " << R << ", " << v << ") called"
              << std::endl;
    inner.update(L, R, v);
    for (int ix = L; ix < R; ++ix) arr[ix] = std::min(arr[ix], v);
    int n = int(arr.size());
    for (int x = 0; x < n; ++x)
      for (int y = x + 1; y <= n; ++y) query(x, y);
    std::cerr << "update(" << L << ", " << R << ", " << v << ") succeeded"
              << std::endl;
    return;
  }
};
template <class T>
T ceilDiv(T p, T q) {
  return (p + q - 1) / q;
}
int main() {
  using namespace std;
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  LL L, R;
  cin >> L >> R;
  ST bestFactors{m + 1};
  struct Ans {
    int x1;
    int y1;
    int x2;
    int y2;
  };
  vector<Ans> ans = vector<Ans>(n + 1, Ans{-1, m + 1, n + 1, m + 1});
  for (int currFactor = m; currFactor > 0; --currFactor) {
    for (int currX = currFactor; currX <= n; currX += currFactor) {
      LL yL = ceilDiv(L, LL(currX));
      LL yR = min(LL(m), R / currX);
      if (yL > yR) continue;
      int altFactor = bestFactors.query(int(yL), int(yR) + 1);
      assert(altFactor > currFactor);
      if (altFactor == numeric_limits<int>::max()) continue;
      LL x2 = LL(currX) * altFactor / currFactor;
      assert(currX < x2);
      if (x2 > n) continue;
      int y1 = ceilDiv(int(yL), altFactor) * altFactor;
      assert(yL <= y1);
      assert(y1 <= yR);
      LL prod = LL(currX) * y1;
      assert(prod % x2 == 0);
      assert(L <= prod);
      assert(prod <= R);
      LL y2 = prod / x2;
      assert(y2 < y1);
      if (y1 < ans[currX].y1) ans[currX] = Ans{currX, y1, int(x2), int(y2)};
    }
    for (int currY = currFactor; currY <= m; currY += currFactor)
      bestFactors.update(currY, currY + 1, currFactor);
  }
  for (int x1 = 1; x1 <= n; ++x1) {
    Ans cv = ans[x1];
    if (cv.y1 > m) {
      cout << "-1\n";
      continue;
    }
    assert(cv.x1 == x1);
    cout << cv.x1 << ' ' << cv.y1 << ' ' << cv.x2 << ' ' << cv.y2 << '\n';
  }
  return 0;
}
