/*
 * Greater NY Regional - 2019
 * Fred Pickel
 * Pass The Buck solution
 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>

#define MAX_NODES	20
#define MAX_PAIRS	20

#define EPS (1.0e-4)
//#define ONE_SHOT

typedef unsigned short WORD;
typedef unsigned char BYTE;
char inbuf[256];

/*
 * let p(i,k) = probability that player k wins if starting with player i
 * SUM(over k: p(i,k) = 1	// someone must win
 * if k != i, when i plays there is 1/(deg9i0 + 1) chance i wins other wise each of i's
 * neighbors has 1/(deg9i- + 1) chance of being the next player so
 * p(i,k) = (1/(deg[i] + 1))*SUM(j neighbor of i: p(j,k))
 * if i == k then there is 1/(deg(i) + 1) chance of winning  otherwise neighbors have an equal
 * chance of being the next player so
 * p(k,k) = (1/(deg[i] + 1))*(1 + SUM(j neighbor of k: p(j,k)))
 * this gives equations:
 * (deg(i)+1)*p(i,k) - SUM(j neighbor of i: p(j,k)) = delta(i,k) = (1 if (i == k) else 0
 */

double coeffs[MAX_NODES+1][2*MAX_NODES+1];
double degrees[MAX_NODES];
int init[MAX_PAIRS], win[MAX_PAIRS];
int nNodes, nPairs;

void array_init()
{
	int i, j;
	for(i = 0; i < nNodes; i++) {
		for(j = 0; j < 2*nNodes ; j++) {
			coeffs[i][j] = 0.0;
		}
	}
}

int parseNodeData(int node, char *pbuf)
{
	int i, val;
	while(isspace(*pbuf)) pbuf++;
	if(!isdigit(*pbuf)) {
		return -21;
	}
	val = 0;
	while(isdigit(*pbuf)) {
		val = 10*val + (*pbuf - '0');
		pbuf++;
	}
	if(val > (nNodes - 1)) {
		return -22;
	}
	degrees[node] = val;
	coeffs[node][node] = (double)(val+1);
	coeffs[node][nNodes+node] = 1.0;
	for(i = 0; i < degrees[node]; i++) {
		while(isspace(*pbuf)) pbuf++;
		if(!isdigit(*pbuf)) {
			return -23;
		}
		val = 0;
		while(isdigit(*pbuf)) {
			val = 10*val + (*pbuf - '0');
			pbuf++;
		}
		if((val < 1) || (val > nNodes) || (val == (node+1))) {
			return -24;
		}
		coeffs[node][val-1] = -1.0;
	}
	return 0;
}

int solveArray()
{
	double fact;
	int i, j, k;
	for(i = 0; i < nNodes ; i++) {
		if(fabs(coeffs[i][i]) < EPS) {
			return -31;
		}
		fact = 1.0/coeffs[i][i];
		for(j = i; j < 2*nNodes; j++) {
			coeffs[i][j] *= fact;
		}
		for(j = 0; j < nNodes ; j++){
			if(j == i) {
				continue;
			}
			fact = coeffs[j][i];
			for(k = i; k < 2*nNodes ; k++) {
				coeffs[j][k] -= fact*coeffs[i][k];
			}
		}
	}
	return 0;
}

void printSoln()
{
	int i, j;
	double sum, csum;
	for(i = 0; i < nNodes; i++) {
		sum = 0.0;
		csum = 0.0;
		for(j = 0; j < nNodes ; j++) {
			sum += coeffs[i][nNodes+j];
			csum += coeffs[j][nNodes+i];
#ifdef DEBUG
			printf("%0.4lf ", coeffs[i][nNodes+j]);
#endif
		}
#ifdef DEBUG
		printf("%0.4lf\n", sum);
#endif
		coeffs[nNodes][i+nNodes] = csum;
	}
#ifdef DEBUG
	for(i = 0; i < nNodes; i++) {
		printf("%0.4lf ", coeffs[nNodes][i+nNodes]);
	}
	printf("\n");
#endif
}

int main()
{
	int ret, i, ind, start, end;
#ifdef ONE_SHOT
	int nprob, curprob, index;
	if(fgets(&(inbuf[0]), 255, stdin) == NULL)
	{
		fprintf(stderr, "Read failed on problem count\n");
		return -1;
	}
	if(sscanf(&(inbuf[0]), "%d", &nprob) != 1)
	{
		fprintf(stderr, "Scan failed on problem count\n");
		return -2;
	}
	for(curprob = 1; curprob <= nprob ; curprob++)
	{
		if(fgets(&(inbuf[0]), 255, stdin) == NULL)
		{
			fprintf(stderr, "Read failed on problem %d header\n", curprob);
			return -3;
		}
		// get prob num degree
		if(sscanf(&(inbuf[0]), "%d %d", &index, &i) != 2)
		{
			fprintf(stderr, "scan failed on problem header problem index %d\n",
				curprob);
			return -6;
		}
		if(index != curprob)
		{
			fprintf(stderr, "problem index %d not = expected problem %d\n",
				index, curprob);
			return -7;
		}
#endif
		// get nNodes and nPairs
		if(fgets(&(inbuf[0]), 255, stdin) == NULL)
		{
			fprintf(stderr, "Read failed on nodes/pairs\n");
			return -6;
		}
		if(sscanf(&(inbuf[0]), "%d %d", &nNodes, &nPairs) != 2)
		{
			fprintf(stderr, "scan failed on nodes/pairs\n");
			return -7;
		}
		if((nNodes < 3) || (nNodes > MAX_NODES)) {
			fprintf(stderr, "node cnt %d not in range 3 .. %d\n",
				nNodes, MAX_NODES);
			return -8;
		}
		if((nPairs < 1) || (nPairs > MAX_PAIRS) || (nPairs > nNodes*nNodes)) {
			fprintf(stderr, "pair cnt %d not in range 1 .. %d\n",
				nPairs, MAX_PAIRS);
			return -9;
		}
		array_init();	// init first atate
		for(i = 0; i < nNodes ; i++) {
			if(fgets(&(inbuf[0]), 255, stdin) == NULL)
			{
				fprintf(stderr, "Read failed on degree/adjacent node %d\n", i+1);
				return -10;
			}
			if((ret = parseNodeData(i, &(inbuf[0]))) != 0) {
				return ret;
			}
		}
		for(i = 0; i < nPairs; i++) {
			if(fgets(&(inbuf[0]), 255, stdin) == NULL)
			{
				fprintf(stderr, "Read failed on pair %d\n", i+1);
				return -11;
			}
			if(sscanf(&(inbuf[0]), "%d %d %d", &ind, &start, &end) != 3)
			{
				fprintf(stderr, "scan failed on pair %d\n", i+1);
				return -12;
			}
			if((ind != (i+1)) || (start < 1) || (start > nNodes) || (end < 1) || (end > nNodes)) {
				fprintf(stderr, "bad pair %d: ind %d start %d end %d\n",
					i+1, ind, start, end);
				return -13;
			}
			init[i] = start;
			win[i] = end;
		}
		if((ret = solveArray()) != 0) {
			fprintf(stderr, "solveArray ret %d\n", ret);
			return -14;
		}
#ifdef ONE_SHOT
		printf("%d\n", curprob);
#endif
		printSoln();
		for(i = 0; i < nPairs ; i++) {
			printf("%d %0.5lf\n", i+1, coeffs[init[i]-1][nNodes+win[i]-1]);
		}
#ifdef ONE_SHOT
	}
#endif
	return 0;
}

