#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <stack>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <sstream>
using namespace std;

#define REP(i,a,n) for(i=a; i<n; i++)
#define rep(i,n) REP(i,0,n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it,x) for(typeof(x.begin()) it=x.begin(); it!=x.end(); it++)

struct _node{
    int lb, rb, mb;
} node[1<<10];

bool used[1<<10];
int N,M,L, b[11], h[11], f[11], a[11], p[11],t[11];


void input(){
    int i;

    b[0] = 0, h[0] = 50;
    cin >> N;
    REP(i,1,N+1) cin >> b[i] >> h[i];
    b[N+1] = 100, h[N+1] = 50;

    cin >> M;
    rep(i,M) cin >> f[i] >> a[i];

    cin >> L;
    rep(i,L) cin >> p[i] >> t[i];
}

// ÍÍ(x1, x2)Ì¤¿ÅåÌ³ÌæØèÂÌidðÔ·
int findmax(int x1, int x2){
    int res = -1, tmp = 0;
    int i;

    REP(i,1,N+1) if( x1 < b[i] && b[i] < x2 ) {
        if( tmp < h[i] ){
            res = i;
            tmp = h[i];
        }
    }
    return res;
}

void build_tree(){
    int i;

    memset(used, false, sizeof(used));

    node[0].lb = 0;
    node[0].rb = N+1;
    node[0].mb = findmax(b[0], b[N+1]);
    used[0] = true;

    rep(i,1<<(N-1)) if( used[i] ) { // úð¢Äm[hªN-1ÂÅ«éÍ¸
        // ¶¤ð²×é
        int id = findmax(b[node[i].lb], b[node[i].mb]);
        if( id != -1 ){
            node[2*i+1].lb = node[i].lb;
            node[2*i+1].rb = node[i].mb;
            node[2*i+1].mb = id;
            used[2*i+1] = true;
        }

        // E¤ð²×é
        id = findmax(b[node[i].mb], b[node[i].rb]);
        if( id != -1 ){
            node[2*i+2].lb = node[i].mb;
            node[2*i+2].rb = node[i].rb;
            node[2*i+2].mb = id;
            used[2*i+2] = true;
        }
        //printf("i = %d, ¶ = %d, E = %d\n",i,used[2*i+1],used[2*i+2]);
    }
}


// (x1, x2)ÌÍÍÉüé1b ½èÌÊð²×é
int getwater(int x1, int x2){
    int i, res = 0;

    rep(i,M){
        if( x1 < f[i] && f[i] < x2 ){
            res += a[i];
        }
    }
    return res;
}

// lc,rcÍe©ç¬êÄ«½ÊAK¸Ç¿ç©Í0
double solve(int id, int px, int time, int lc, int rc){
    int la = lc + time * getwater(b[node[id].lb], b[node[id].mb]); // ¶¤ÉüéÊð²×é
    int ra = rc + time * getwater(b[node[id].mb], b[node[id].rb]); // E¤ÉüéÊð²×é

    // ¶¤ªìêéÀEl
    int tmp_l = (b[node[id].mb] - b[node[id].lb]) * h[node[id].mb] * 30;

    // E¤ªìêéÀEl
    int tmp_r = (b[node[id].rb] - b[node[id].mb]) * h[node[id].mb] * 30;

    if( (tmp_l + tmp_r) <= (la + ra) ){ // ¼ûìê½
        return min(50.0, (double)(la + ra) / (double)((b[node[id].rb] - b[node[id].lb]) * 30));
    }

    // ìê½Ù¤Ì³ðßéê
    if( (tmp_l <= la && b[node[id].lb] < px && px < b[node[id].mb] ||
         tmp_r <= ra && b[node[id].mb] < px && px < b[node[id].rb]) ){
        return (double)h[node[id].mb];
    }

    if( px < b[node[id].mb] ){ // ¶Ìq
        if( !used[2*id+1] ) return (double)(la+max(ra-tmp_r,0)) / (double)((b[node[id].mb] - b[node[id].lb]) * 30);
        return solve(2*id+1, px, time, lc, max(ra-tmp_r,0)); // ÓF½]
    }
    else{ // EÌq
        //printf("(rc=%d + ra=%d) / (%d - %d) * 30 = %lf\n",rc,ra,node[id].rb, node[id]
        if( !used[2*id+2] ) return (double)(ra+max(la-tmp_l,0)) / (double)((b[node[id].rb] - b[node[id].mb]) * 30);
        return solve(2*id+2, px, time, max(la-tmp_l,0), rc); 
    }
}


int main(){
    int D,i,j;

    cin >> D;
    while( D-- ){
        input();
        build_tree();

        rep(i,L){
            printf("%lf\n",solve(0,p[i],t[i],0,0));
        }
    }
    

    return 0;
}

Measured memory_bytes: 0