//#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <bitset>
#define mp make_pair
#define pb push_back

#ifdef LOCAL
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
#define eprintf(...)
#endif

#define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", clock()*1.0/CLOCKS_PER_SEC)
#define TIMESTAMPf(x,...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, clock()*1.0/CLOCKS_PER_SEC)

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

using namespace std;

#define TASKNAME "zoo"

#ifdef LOCAL
static struct __timestamper {
    string what;
    __timestamper(const char* what) : what(what){};
    __timestamper(const string& what) : what(what){};
	~__timestamper(){
        TIMESTAMPf("%s", what.data());
	}
} __TIMESTAMPER("end");
#else 
struct __timestamper {};
#endif

typedef long long ll;
typedef long double ld;

vector< pair<int, int> > es;

struct Changer {
	int a, b;
	Changer(int a, int b):a(a),b(b) { swap(es[a], es[b]);}
	~Changer() { swap(es[a], es[b]);}
};

vector<vector<int>> paths;

bool check(int a, int b) {
	Changer _(a, b);
	for (const auto& path : paths) {
		int st = path[0];
		vector<int> vs;
		vs.pb(st);
		for (int i = 1; i + 1 < (int)path.size(); i++) {
			if (es[path[i]].first != st)
				return false;
			st = es[path[i]].second;
			vs.pb(st);
		}
		if (st != path.back()) return false;
		sort(vs.begin(), vs.end());
		if (unique(vs.begin(), vs.end()) != vs.end()) return false;
	}
	return true;
}

void fixNext(const vector<int>& path, int id, vector<pair<int,int>>& cand) {
	int v = (id ==  1 ? path[0] : es[path[id-1]].second);
	int u = (id + 2 == (int)path.size() ? path[id+1] : es[path[id+1]].first);
//	eprintf("fixNext: (%d, %d) should be replaced by (%d, %d)\n", es[path[id]].first, es[path[id]].second,v, u);
	int x = find(es.begin(), es.end(), mp(v, u)) - es.begin();
	if (x != (int)es.size())
		cand.pb(mp(path[id], x));
}

int main(){
    assert(freopen(TASKNAME".in","r",stdin));
    assert(freopen(TASKNAME".out","w",stdout));
	int n, m;
	scanf("%d%d",&n,&m);
	es.resize(m);
	for (int i = 0; i < m; i++) {
		int a, b, id;
		scanf("%d%d%d",&a,&b,&id);
		--a,--b,--id;
		es[id] = mp(a, b);
	}      
	int q;
	scanf("%d",&q);
	paths.resize(q);
	for (auto& path : paths) {
		int len;
		scanf("%d",&len);
		len += 2;
		path.resize(len);
		for (int& x : path)
			scanf("%d",&x), x--;
		rotate(path.begin()+1, path.begin()+2, path.end());
	}
	/*for (const auto& path : paths) {
		for (int x : path)
			eprintf("%d ", x);
		eprintf("\n");
	}*/
	assert(!check(0,0));
	for (const auto& path : paths) {
		int st = path[0];
		vector<pair<int, int>> cand;
		for (int i = 1; i + 1 < (int)path.size() && cand.empty(); i++) {
//			eprintf("st = %d; edge[%d] = {%d, %d}\n", st, path[i], es[path[i]].first, es[path[i]].second);
			if (es[path[i]].first != st) {
			    if (i != 1) cand.pb(mp(path[i], path[i-1]));
			    if (i + 2 != (int)path.size()) cand.pb(mp(path[i], path[i+1]));
			    fixNext(path, i, cand);
			    if (i != 1) fixNext(path, i-1, cand);
			}
			st = es[path[i]].second;
		}
		if (st != path.back() && cand.empty()) {
			fixNext(path, path.size() - 2, cand);
			assert(!cand.empty());
		}
		if (!cand.empty()) {
		    for (auto x : cand) {
//		    	eprintf("Checking pair %d %d\n", x.first, x.second);
		    	if (check(x.first, x.second)) {
	    			printf("%d %d\n", x.first+1, x.second+1);
	    			return 0;
		    	}
		    }
			assert(false);
	    }
	}

    return 0;
}