#include <bits/stdc++.h>
#define REP(i, a, n) for(ll i ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;

struct query {
  ll d, a, b, idx;

  bool operator<(const query& q) const {
    return d < q.d;
  }
};

template<typename T, typename E> class LazySegmentTree {
public:
  typedef function<T (T, T)> Operator;
  typedef function<E (E, E)> Merge;
  typedef function<T (T, E)> Apply;
  typedef function<E (E, ll)> Product;

  vector<T> data;
  vector<E> lazy;
  ll n;        // size of elements (2^x alignment)
  T e;         // identity of monoid
  Operator op; // binary operator of monoid
  E d;         // identity of effect
  Merge merge; // merge effects
  Apply apply; // apply effect to monoid
  Product p;   // calculate effect * n

  // construction with size of elements
  LazySegmentTree(ll _n, T e, Operator op, E d, Merge merge, Apply apply, Product p):
    e(e), op(op), d(d), merge(merge), apply(apply), p(p) {
    for(n = 1; n < _n; n *= 2);
    data.resize(n * 2 - 1, e);
    lazy.resize(n * 2 - 1, d);
  }

  // construction with initial values
  LazySegmentTree(const vector<T> &vec, T e, Operator op, E d, Merge merge, Apply apply, Product p):
    e(e), op(op), d(d), merge(merge), apply(apply), p(p) {
    for(n = 1; n < (ll) vec.size(); n *= 2);
    data.resize(n * 2 - 1, e);
    lazy.resize(n * 2 - 1, d);
    REP(i, 0, vec.size()) data[i + n - 1] = vec[i];
    for(ll i = n - 2; i >= 0; i--) data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
  }

  // evaluate lazy update
  void eval(ll k, ll l, ll r) {
    if(r - l > 1) {
      lazy[k * 2 + 1] = merge(lazy[k * 2 + 1], lazy[k]);
      lazy[k * 2 + 2] = merge(lazy[k * 2 + 2], lazy[k]);
    }
    data[k] = apply(data[k], p(lazy[k], r - l));
    lazy[k] = d;
  }

  // query for [a, b)
  T query(ll a, ll b) { return query(a, b, 0, 0, n); }
  T query(ll a, ll b, ll k, ll l, ll r) {
    eval(k, l, r);
    if(r <= a || b <= l) return e;
    if(a <= l && r <= b) return data[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return op(vl, vr);
  }

  // update values of [a, b)
  T update(ll a, ll b, E x) { return update(a, b, x, 0, 0, n); }
  T update(ll a, ll b, E x, ll k, ll l, ll r) {
    eval(k, l, r);
    if(r <= a || b <= l) return data[k];
    if(a <= l && r <= b) {
      lazy[k] = merge(lazy[k], x);
      return apply(data[k], p(lazy[k], r - l));
    }
    T vl = update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    T vr = update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    return data[k] = op(vl, vr);
  }
};

int main(void) {
  ll N, M, Q;
  cin >> N >> M >> Q;
  vector<query> P;
  REP(i, 0, M) {
    ll D, A, B; cin >> D >> A >> B; A--; B--;
    P.push_back((query) { D * 2 + 1, A, B, -1 });
  }
  REP(i, 0, Q) {
    ll E, S, T; cin >> E >> S >> T; S--; T--;
    P.push_back((query) { E * 2, S, T, i });
  }

  sort(P.begin(), P.end());

  const ll INF = 1LL << 60;
  vector<ll> A(N * 2, 0);
  LazySegmentTree<ll, ll>::Operator op = [](ll a, ll b) { return min(a, b); };
  LazySegmentTree<ll, ll>::Merge merge = [](ll x, ll y) { return x + y; };
  LazySegmentTree<ll, ll>::Apply apply = [](ll a, ll x) { return a + x; };
  LazySegmentTree<ll, ll>::Product p = [](ll x, ll n) { return x; };
  LazySegmentTree<ll, ll> segtree(A, INF, op, 0, merge, apply, p);

  vector<bool> ans(Q);
  for(auto p : P) {
    if(p.d % 2 == 0) {
      if(segtree.query(p.a * 2, p.b * 2) > 0) {
        ans[p.idx] = true;
      } else {
        ans[p.idx] = false;
      }
    } else {
      segtree.update(p.a * 2, p.b * 2, 1);
    }
  }

  REP(i, 0, Q) cout << (ans[i] ? "Yes" : "No") << endl;
}



Measured memory_bytes: 18896