#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const long long INF = 1e9 + 19;
const int LOG = 52;
const int BASE = 2;
struct pt {
  int x, y;
  pt() {}
  pt(int xx, int yy) : x(xx), y(yy) {}
  void read() { scanf("%d%d", &x, &y); }
  pt operator+(const pt& A) const { return pt(x + A.x, y + A.y); }
  pt operator-(const pt& A) const { return pt(x - A.x, y - A.y); }
  int operator%(const pt& A) const { return x * A.x + y * A.y; }
  int operator*(const pt& A) const { return x * A.y - y * A.x; }
  bool operator==(const pt& A) const { return x == A.x && y == A.y; }
  long long len() { return abs(x) + abs(y); }
  pt operator*(int k) const { return pt(x * k, y * k); }
};
const pt dir[4] = {pt(1, 0), pt(0, 1), pt(-1, 0), pt(0, -1)};
struct Query {
  pt p;
  int dirId;
  long long tmr;
};
struct Tree {
  vector<int> data;
  void init(int n) { data.assign(n * 4, -1); }
  void push(int v) {
    if (data[v] != -2) {
      data[v * 2 + 1] = data[v];
      data[v * 2 + 2] = data[v];
      data[v] = -2;
    }
  }
  void add(int v, int tl, int tr, int l, int r, int val) {
    if (tr <= l || r <= tl) return;
    if (l <= tl && tr <= r) {
      data[v] = val;
      return;
    }
    push(v);
    add(v * 2 + 1, tl, (tl + tr) / 2, l, r, val);
    add(v * 2 + 2, (tl + tr) / 2, tr, l, r, val);
  }
  int get(int v, int tl, int tr, int pos) {
    if (data[v] != -2) {
      return data[v];
    }
    if (pos < (tl + tr) / 2)
      return get(v * 2 + 1, tl, (tl + tr) / 2, pos);
    else
      return get(v * 2 + 2, (tl + tr) / 2, tr, pos);
  }
};
struct Event {
  int t, type, id, l, r;
  void Epr() {
    cerr << "t type id l r: " << t << " " << type << " " << id << " " << l
         << " " << r << endl;
  }
};
struct State {
  pt A;
  pt v;
  int nextId;
  long long len;
};
pt getDir(pt A, pt B) {
  pt v = B - A;
  int len = abs(v.x) + abs(v.y);
  v.x /= len;
  v.y /= len;
  return v;
}
int n, b, q;
pair<pt, pt> p[N];
pt segDir[N];
Query query[N];
int nexttt[N * 2];
State go[N][LOG];
long long deg[LOG];
void read() {
  scanf("%d%d", &n, &b);
  for (int i = 0; i < n; i++) {
    p[i].first.read();
    p[i].second.read();
  }
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    char ch;
    scanf("%d%d %c%lld", &query[i].p.x, &query[i].p.y, &ch, &query[i].tmr);
    if (ch == 'R') query[i].dirId = 0;
    if (ch == 'U') query[i].dirId = 1;
    if (ch == 'L') query[i].dirId = 2;
    if (ch == 'D') query[i].dirId = 3;
  }
}
long long distToSeg(int segId, pt C) {
  pt v = segDir[segId];
  if ((C - p[segId].first) % v >= 0 && (C - p[segId].second) % v <= 0) {
    return abs(v * (C - p[segId].first));
  }
  return min((C - p[segId].first).len(), (C - p[segId].second).len());
}
int cc;
State eval(State st, int bound) {
  int i = bound;
  for (;;) {
    cc++;
    int rId = st.nextId;
    if (rId == -1) {
      long long mxDist = -1;
      if (st.v == dir[0]) mxDist = b - st.A.x;
      if (st.v == dir[1]) mxDist = b - st.A.y;
      if (st.v == dir[2]) mxDist = st.A.x;
      if (st.v == dir[3]) mxDist = st.A.y;
      long long d = min(mxDist, st.len);
      st.A = st.A + st.v * d;
      st.len -= d;
      return st;
    }
    long long d = min(st.len, distToSeg(rId, st.A));
    st.len -= d;
    st.A = st.A + st.v * d;
    if (st.len == 0) break;
    d = min(st.len, (p[rId].second - st.A).len());
    st.len -= d;
    st.A = st.A + segDir[rId] * d;
    if (st.len == 0) break;
    for (; st.len < deg[i]; i--)
      ;
    if (st.len >= deg[i]) {
      long long oldLen = st.len;
      st = go[rId][i];
      st.len = oldLen - deg[i];
    }
  }
  return st;
}
void solve() {
  deg[0] = 1;
  for (int i = 1; i < LOG; i++) deg[i] = deg[i - 1] * BASE;
  for (int i = 0; i < n; i++) segDir[i] = getDir(p[i].first, p[i].second);
  for (int t = 0; t < 4; t++) {
    vector<Event> event;
    pt v = dir[t];
    for (int i = 0; i < n; i++) {
      int tmr = max(v % p[i].first, v % p[i].second);
      int l = min(v * p[i].first, v * p[i].second);
      int r = max(v * p[i].first, v * p[i].second);
      event.push_back({tmr, 0, i, l, r});
    }
    for (int i = 0; i < n; i++) {
      pt u = segDir[i];
      if (u == v) {
        pt A = p[i].second + u;
        event.push_back({A % v, 1, i, v * A, v * A});
      }
    }
    for (int i = 0; i < q; i++) {
      if (dir[query[i].dirId] == v) {
        event.push_back(
            {query[i].p % v, 1, i + n, v * query[i].p, v * query[i].p});
      }
    }
    int mnT = 0;
    int mnY = 0;
    for (auto ee : event) {
      mnT = min(mnT, ee.t);
      mnY = min(mnY, ee.l);
    }
    for (auto& ee : event) {
      ee.t -= mnT;
      ee.l -= mnY;
      ee.r -= mnY;
    }
    sort((event).begin(), (event).end(), [](Event A, Event B) {
      return A.t > B.t || (A.t == B.t && A.type < B.type);
    });
    Tree tree;
    tree.init(b + 1);
    for (auto ee : event) {
      if (ee.type == 0) {
        tree.add(0, 0, b + 1, ee.l, ee.r + 1, ee.id);
      } else {
        nexttt[ee.id] = tree.get(0, 0, b + 1, ee.l);
      }
    }
  }
  for (int i = 0; i < n; i++) {
    pt v = segDir[i];
    go[i][0] = {p[i].second + v, v, nexttt[i], 0};
  }
  for (int j = 1; j < LOG; j++) {
    for (int i = 0; i < n; i++) {
      State st = {p[i].second, segDir[i], nexttt[i], deg[j]};
      cc = 0;
      go[i][j] = eval(st, j - 1);
    }
  }
  for (int i = 0; i < q; i++) {
    State st = {query[i].p, dir[query[i].dirId], nexttt[i + n], query[i].tmr};
    State res = eval(st, LOG - 1);
    printf("%d %d\n", res.A.x, res.A.y);
  }
}
void stress() {}
int main() {
  if (1) {
    read();
    solve();
  } else {
    stress();
  }
  return 0;
}
