#include <bits/stdc++.h>
using namespace std;

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define PII pair < int, int >
#define PLL pair < LL, LL >
#define PIL pair < int, LL >
#define PLI pair < LL, int >
#define MP make_pair
#define PB push_back
#define PF push_front
#define POB pop_back
#define POF pop_front
#define PRF first
#define PRS second
#define INIT(ar,val) memset ( ar, val, sizeof ( ar ) )
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 2007;
const int MAXM = 8007;

struct eT
{
	void setd ( int _u, int _v, int _l )
	{
		u = _u, v = _v, last = _l;
	}
	
	int u, v, last;
}edge[MAXM];

int n, m;
int tans;
int ke, la[MAXN];
int wu[MAXM], wv[MAXM], kw;
AR(int) we[MAXM];
int vid[MAXN][MAXM];
bool vis[MAXN], evis[MAXM], wvis[MAXM], eok[MAXM];
bool dir[MAXM];
int deg[MAXN];
int q[MAXN], pre[MAXN];

void init ();
void input ();
void work ();

void getes ( int S, int T, int ni, AR(int) &es );
void dfs ( int rn );



int main()
{
	init();
	input();
	work();
}



void init ()
{
	// Init Everything Here
	
	ios::sync_with_stdio ( false );
}

void input ()
{
	// input method
	
	scanf ( "%d%d", &n, &m );
	int u, v;
	INIT ( la, -1 );
	lp ( i, 1, n ){
		scanf ( "%d%d", &u, &v );
		edge[ke].setd ( u, v, la[u] );
		la[u] = ke++;
		edge[ke].setd ( v, u, la[v] );
		la[v] = ke++;
		++deg[u], ++deg[v];
	}
	lpi ( i, 1, m ) scanf ( "%d%d", &wu[i], &wv[i] );
}

void work ()
{
	// main work
	
	INIT ( vid, -1 );
	
	kw = m;
	lpi ( i, 1, m ) getes ( wu[i], wv[i], i, we[i] );
	
//	lpi ( i, 1, m ) { cerr << i << " : "; for ( auto x : we[i] ) cerr << x << " "; cerr << endl; }
	
	int cans = 0, cur;
	lp ( i, 0, n-1 ){
		cur = 0;
		lpi ( j, 1, m ) cur += ( ~vid[i][j] ) ? 1 : 0;
		cans += qmin ( cur, 2 );
	}
	
	dfs ( n );
	
//	lpi ( i, 1, kw ) cerr << i << " : " << wu[i] << " " << wv[i] << endl;
	
//	cerr << tans << endl;
	printf ( "%d\n", cans );
	lpi ( i, 1, m ) printf ( "%d %d\n", !dir[i] ? wu[i] : wv[i], !dir[i] ? wv[i] : wu[i] );
}



void getes ( int S, int T, int ni, AR(int) &es )
{
	int l = 0, r = 0, now, v;
	INIT ( pre, -1 );
	pre[S] = 0;
	q[r++] = S;
	while ( l < r ){
		now = q[l++];
		for ( int i = la[now]; ~i; i = edge[i].last ){
			if ( pre[v=edge[i].v] == -1 ){
				pre[v] = i;
				q[r++] = v;
			}
		}
	}
	for ( int t = T; t ^ S; t = edge[pre[t]].u ) es.PB ( pre[t] );
	reverse ( es.begin (), es.end () );
	int size = es.size ();
	lp ( i, 0, size ) vid[es[i]>>1][ni] = i;
}

void dfs ( int rn )
{
	if ( rn == 1 ) return;
	
	int now = -1;
	lpi ( i, 1, n ){
		if ( !vis[i] && deg[i] == 1 ){
			now = i;
			break;
		}
	}
	vis[now] = true;
	
	int ne = -1;
	for ( int i = la[now]; ~i; i = edge[i].last ){
		if ( !vis[edge[i].v] ){
			ne = i;
			break;
		}
	}
	--deg[edge[ne].v];
	evis[ne>>1] = true;
	
//	cerr << rn << " : " << now << " " << ne << endl;
	
	int w1 = -1, w2 = -1, c1, c2;
	lpi ( i, 1, kw ){
		if ( !wvis[i] && ( ~vid[ne>>1][i] ) ){
			if ( w1 == -1 ) w1 = i;
			else{
				w2 = i;
				break;
			}
		}
	}
	
	if ( w2 == -1 || eok[ne>>1] ){
		if ( eok[ne>>1] ) /*cerr << "skip : " << now << " " << ne << endl, */tans += 2;
		else if ( ~w1 ) ++tans;
		dfs ( rn - 1 );   // if c2 != -1 and the walk end at edge[ne].v, dir will be 0
	}else{
		tans += 2;
		c1 = vid[ne>>1][w1], c2 = vid[ne>>1][w2];
		int v1, v2;
		bool d1, d2;
		if ( we[w1][c1] == ne ) v1 = wv[w1], d1 = false;
		else v1 = wu[w1], d1 = true;
//		if ( d1 && ( we[w1][c1] ^ ne ^ 1 ) ) cerr << "ERROR!" << endl;
		if ( we[w2][c2] == ne ) v2 = wv[w2], d2 = false;
		else v2 = wu[w2], d2 = true;
//		if ( d2 && ( we[w2][c2] ^ ne ^ 1 ) ) cerr << "ERROR!" << endl;
//		cerr << "intersect : " << now << " " << ne << " " << w1 << " " << w2 << " " << " : " << kw+1 << " " << v1 << " " << v2 << endl;
		int cw;
		if ( v1 ^ v2 ){
//			cerr << w1 << " " << w2 << " : " << c1 << " " << c2 << " : " << v1 << " " << v2 << " ( " << d1 << " " << d2 << endl;
			cw = ++kw;
			wu[kw] = v1, wv[kw] = v2;
			getes ( v1, v2, kw, we[kw] );
			lp ( i, 0, n-1 ){
				if ( !evis[i] && ( ~vid[i][w1] ) && ( ~vid[i][w2] ) && vid[i][kw] == -1 ){
//					if ( !eok[i] ) cerr << "skipping " << i << endl;
					eok[i] = true;
				}
			}
		}else{
			lp ( i, 0, n-1 ){
				if ( !evis[i] && ( ~vid[i][w1] ) ) eok[i] = true;
			}
		}
		wvis[w1] = wvis[w2] = true;
		dfs ( rn - 1 );
		if ( v1 ^ v2 ) dir[w1] = dir[cw] ^ d1 ^ 1, dir[w2] = dir[cw] ^ d2;
		else dir[w1] = d1, dir[w2] = d2 ^ 1;
//		cerr << d1 << " " << d2 << " " << dir[w1] << " " << dir[w2] << endl;
	}
}

Measured memory_bytes: 70144