#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

using namespace std;

// very very te nu ki
class Point{
public:
  double x,y;

  Point(double x = 0,double y = 0): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:(!equals(y,p.y)&&y<p.y); }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator <  (const Segment& s) const { return ( p2 == s.p2 ) ? p1 < s.p1 : p2 < s.p2; }
  bool operator == (const Segment& s) const { return ( s.p1 == p1 && s.p2 == p2 ) || ( s.p1 == p2 && s.p2 == p1 ); }

};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad ????§???????????????¢?????§?????????????????¨
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// ??????????????¢????????????
double toRad(double agl){ return agl*M_PI/180.0; }

// a => prev, b => cur, c=> next
// prev ?????? cur ????????£??? next ????????????????§????????±???????
double getArg(Point a,Point b,Point c){
  double arg1 = atan2(b.y-a.y,b.x-a.x);
  double arg2 = atan2(c.y-b.y,c.x-b.x);
  double arg = fabs( arg1 - arg2 );
  while( arg > M_PI ) arg -= 2.0 * M_PI;
  return fabs(arg);
}

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2-l.p1, m.p2-m.p1)) > EPS || // non-parallel
         abs(cross(l.p2-l.p1, m.p1-l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2-l.p1, s.p1-l.p1)*       // s[0] is left of l
         cross(l.p2-l.p1, s.p2-l.p1) < EPS; // s[1] is right of l
}
bool intersectLP(Line l,Point p) {
  return abs(cross(l.p2-p, l.p1-p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}
Point reflection(Line l,Point p) {
  return p + (projection(l, p) - p) * 2;
}
double distanceLP(Line l, Point p) {
  return abs(p - projection(l, p));
}
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

Point crosspoint(Line l,Line m){
  double A = cross(l.p2-l.p1,m.p2-m.p1);
  double B = cross(l.p2-l.p1,l.p2-m.p1);
  if(abs(A) < EPS && abs(B) < EPS){
    vector<Point> vec;
    vec.push_back(l.p1),vec.push_back(l.p2),vec.push_back(m.p1),vec.push_back(m.p2);
    sort(vec.begin(),vec.end());
    while(1);
    assert(vec[1] == vec[2]); //???????????°??????????????????
    return vec[1];
    //return m.p1;
  }
  if(abs(A) < EPS) while(1);
  return m.p1 + (m.p2-m.p1)*(B/A);
}

//

#define MAX 3100

int H,W,M,Q;
int px[MAX], py[MAX], qx[MAX], qy[MAX];
int sx[MAX], sy[MAX], gx[MAX], gy[MAX];

bool bmap[MAX][MAX];

void veryVeryTenukiKansuu(vector<int> &X,vector<int> &Y) {
  vector<Segment> segs;
  rep(i,M) segs.push_back(Segment(Point(px[i],py[i]),Point(qx[i],qy[i])));
  rep(i,M) REP(j,i+1,M) {
    Segment &s1 = segs[i], &s2 = segs[j];
    if( ( s1.p1.x == s1.p2.x ) && ( s2.p1.x == s2.p2.x ) ) continue;
    if( ( s1.p1.y == s1.p2.y ) && ( s2.p1.y == s2.p2.y ) ) continue;
    if( intersectSS(s1,s2) ) {
      Point cp = crosspoint(s1,s2);
      X.push_back(cp.x);
      Y.push_back(cp.y);
    }
  }
}

struct Data {
  int index,w;
  bool operator < (const Data &data) const {
    return w > data.w;
  }
};

int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};


int indexMap[MAX][MAX];
int V;

vector<int> G[MAX];

void makeVVV(int nW,int nH) {
  memset(indexMap,-1,sizeof indexMap);
  rep(i,nH) rep(j,nW) if( !bmap[i][j] && indexMap[i][j] == -1 ) {
    indexMap[i][j] = V;
    deque<int> deq;
    deq.push_back(j+i*nW);
    while( !deq.empty() ) {
      int tmp = deq.front(); deq.pop_front();
      int x = tmp % nW, y = tmp / nW;
      rep(i,4) {
        int nx = x + dx[i], ny = y + dy[i];
        if( !( 0 <= nx && nx < nW && 0 <= ny && ny < nH ) ) continue;
        if( bmap[ny][nx] ) continue;
        if( indexMap[ny][nx] != -1 ) continue;
        indexMap[ny][nx] = V;
        deq.push_back(nx+ny*nW);
      }
    }
    ++V;    
  }

  /*
  rep(i,nH) {
    rep(j,nW) {
      cout << indexMap[i][j] << " ";
    }
    puts("");
  } puts("");
  */
  
  rep(i,nH) rep(j,nW) if( indexMap[i][j] != -1 ) {
    set<int> used;
    rep(k,4) {
      int nx = j + dx[k] * 2, ny = i + dy[k] * 2;
      if( !( 0 <= nx && nx < nW && 0 <= ny && ny < nH ) ) continue;
      if( indexMap[ny][nx] == -1 || indexMap[ny][nx] == indexMap[i][j] ) continue;
      if( used.count(indexMap[ny][nx]) ) continue;
      used.insert(indexMap[ny][nx]);
      G[indexMap[i][j]].push_back(indexMap[ny][nx]);
    }
  }

  /*
  rep(i,V) 
    {
      cout << i << "-th" << endl;
      rep(j,(int)G[i].size()) cout << G[i][j] << " "; puts("");
    }
*/
  
}


int mini[MAX][MAX];

void dijkstra(int s) {
  mini[s][s] = 0;
  priority_queue<Data> Q;
  Q.push((Data){s,0});
  while( !Q.empty() ) {
    Data data = Q.top(); Q.pop();
    rep(i,(int)G[data.index].size()) {
      int next = G[data.index][i];
      if( mini[s][next] > data.w + 1 ) {
        mini[s][next] = data.w + 1;
        Q.push((Data){next,data.w+1});
      }
    }
  }
}

void calc() {
  rep(i,V) rep(j,V) mini[i][j] = INT_MAX;
  rep(i,V) dijkstra(i);
}

void compute() {
  vector<int> X, Y;
  X.push_back(0), Y.push_back(0);
  X.push_back(2*W), Y.push_back(2*H);
  rep(i,M) {
    X.push_back(px[i]), X.push_back(qx[i]);
    Y.push_back(py[i]), Y.push_back(qy[i]);
  }
  rep(i,Q) {
    X.push_back(sx[i]), X.push_back(gx[i]);
    Y.push_back(sy[i]), Y.push_back(gy[i]);
  }

  veryVeryTenukiKansuu(X,Y);

  {
    vector<int> nX;
    rep(i,(int)X.size()) {
      nX.push_back(X[i]);
      if( X[i]-1>=0 ) nX.push_back(X[i]-1);
      if( X[i]+1<=2*W ) nX.push_back(X[i]+1);
    }
    X = nX;
  }
  {
    vector<int> nY;
    rep(i,(int)Y.size()) {
      nY.push_back(Y[i]);
      if( Y[i]-1>=0 ) nY.push_back(Y[i]-1);
      if( Y[i]+1<=2*H ) nY.push_back(Y[i]+1);
    }
    Y = nY;
  }

  sort(X.begin(),X.end());
  X.erase(unique(X.begin(),X.end()),X.end());
  sort(Y.begin(),Y.end());
  Y.erase(unique(Y.begin(),Y.end()),Y.end());

  map<int,int> mpX,mpY;
  rep(i,(int)X.size()) mpX[X[i]] = i;
  rep(i,(int)Y.size()) mpY[Y[i]] = i;

  px[M  ] = 0, py[M  ] = 0, qx[M  ] = 2*W, qy[M  ] = 0;
  px[M+1] = 2*W, py[M+1] = 0, qx[M+1] = 2*W, qy[M+1] = 2*H;
  px[M+2] = 2*W, py[M+2] = 2*H, qx[M+2] = 0, qy[M+2] = 2*H;
  px[M+3] = 0, py[M+3] = 2*H, qx[M+3] = 0, qy[M+3] = 0;
  rep(i,M+4) {
    int x1 = mpX[px[i]], y1 = mpY[py[i]];
    int x2 = mpX[qx[i]], y2 = mpY[qy[i]];
    REP(y,min(y1,y2),max(y1,y2)+1) REP(x,min(x1,x2),max(x1,x2)+1) bmap[y][x] = 1;
  }

  int nH = (int)Y.size(), nW = (int)X.size();
  
  makeVVV(nW,nH);
  //cout << "V = " << V << endl;
  calc();
  
/*
  rep(i,nH) {
    rep(j,nW) {
      cout << bmap[i][j];
    } puts("");
  }
*/
  rep(i,Q) {
    int x1 = mpX[sx[i]], y1 = mpY[sy[i]];
    int x2 = mpX[gx[i]], y2 = mpY[gy[i]];
    assert( !bmap[y1][x1] );
    assert( !bmap[y2][x2] );
    int s1 = indexMap[y1][x1];
    int s2 = indexMap[y2][x2];
    assert( s1 != -1 );
    assert( s2 != -1 );
    cout << mini[s1][s2] << endl;
  }
  
}

int main() {
  /*
  cout << 1000000000 << " " << 1000000000 << " " << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+3 << " 999999999 " << i*3+3 << endl;
  }
  cout << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+4 << " 999999999 " << i*3+4 << endl;
  }
  return 0;
  */
  cin >> W >> H >> M;
  rep(i,M) cin >> px[i] >> py[i] >> qx[i] >> qy[i];
  cin >> Q;
  rep(i,Q) cin >> sx[i] >> sy[i] >> gx[i] >> gy[i];
  rep(i,M) px[i] <<= 1, py[i] <<= 1, qx[i] <<= 1, qy[i] <<= 1;
  rep(i,Q) sx[i] <<= 1, sy[i] <<= 1, gx[i] <<= 1, gy[i] <<= 1;
  compute();
  return 0;
}

Measured memory_bytes: 47644