1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <bits/stdc++.h>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); i--)
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

const int N = 1 << 17;


vector<PII> edges[2];

VI g[2][N];
int d[N];
bool used[N];

void dfs(int v, int t)
{
	used[v] = 1;
	for(int to : g[t][v])
	{
		if(!used[to])
		{
			d[to] = d[v] + 1;
			dfs(to, t);
		}
	}
}
vector<tuple<int, int, int>> solve(int n, int t)
{
	d[0] = 0;
	fill(used, used + n, 0);
	dfs(0, t);
	
	set<PII> edgesWas, edgesNeed;
	FOR(it, 0, 2)
	{
		for(auto x : edges[it])
		{
			if(it == t)
				edgesWas.insert(x);
			edgesNeed.insert(x);
		}
	}
	for(auto e : edgesWas)
		edgesNeed.erase(e);
	
	VI order(n);
	iota(ALL(order), 0);
	sort(ALL(order), [&](int a, int b){return d[a] < d[b];});
	
	vector<tuple<int, int, int>> ans;
	
	for(int v : order)
	{
		if(v == 0 || edgesWas.count(MP(0, v)))
			continue;
		ans.PB({1, 0, v});	
		edgesNeed.erase(MP(0, v));
	}
	for(auto [a, b] : edgesNeed)
		ans.PB({1, a, b});
	
	return ans;
}




int main()
{
	ios::sync_with_stdio(0); 
	cin.tie(0);
	cout << fixed << setprecision(15);
	
	int n;
	cin >> n;
	FOR(it, 0, 2)
	{
		int m;
		cin >> m;
		FOR(i, 0, m)
		{
			int a, b;
			cin >> a >> b;
			a--; b--;
			if(a > b)
				swap(a, b);
			g[it][a].PB(b);
			g[it][b].PB(a);
			edges[it].PB(MP(a, b));
		}
	}
	vector<tuple<int, int, int>> ansL = solve(n, 0);
	vector<tuple<int, int, int>> ansR = solve(n, 1);
	reverse(ALL(ansR));
	
	
	cout << SZ(ansL) + SZ(ansR) << "\n";
	FOR(it, 0, 2)
	{
		for(auto [x, a, b] : ansL)
		{
			cout << ((x ^ it) ? '+' : '-') << " " << a + 1 << " " << b + 1 << "\n";
		}
		swap(ansL, ansR);
	}




	return 0;
}