/*
TASK:wireless
LANG:C++
*/

#include <stdio.h>
#include <vector>
using namespace std;

const int inf = 1023456789;
const int N = 4*1024;

struct Type{
	Type(){}
  Type(int _neib, int _ener){
   	neib = _neib;
    ener = _ener;
  }
	int neib;
  int ener;
};


vector<int> ret;
int END;
bool first = true;


vector<Type> data[N];
int energy[N];
int distB[N], distC[N];

int i, j, n;
int a, b, c;

void Input(){

	//freopen("wireless.in", "rt", stdin);

	scanf("%d%d%d%d", &n, &a, &b, &c);
  for(i=1; i<=n; i++){
  	int m;
    scanf("%d", &m);
    data[i].resize(m);
    
    for(j=1; j<=m; j++){
    	int neib, ener;
      scanf("%d%d", &neib, &ener);
      data[i][j-1] = Type(neib, ener);
    }
  }
  
}


void PrintData(){
	for(i=1; i<=n; i++){
  	for(j=0; j<data[i].size(); j++)
    	printf("(%d,%d) ", data[i][j].neib, data[i][j].ener);
		printf("\n");
  }
}

void Djkstra(int start, int end){
	bool used[N];
  int dist[N];
  Type prev[N];

  for(i=0; i<=n; i++){
  	used[i] = 0;
    dist[i] = inf;
  }

  for(i=1; i<=n; i++)
  	if(energy[i])
    	for(j=0; j<data[i].size(); j++)
      	if(data[i][j].ener <= energy[i]){
        	dist[ data[i][j].neib ] = 0;
          prev[ data[i][j].neib ].neib = 0;
          prev[ data[i][j].neib ].ener = 0;
          
        }
  
  int best = start;
  dist[best] = 0;

  while(best != end){

    used[best] = 1;
    
  	for(i=0; i<data[best].size(); i++)
    	if(dist[ data[best][i].neib ] > dist[best] + data[best][i].ener){
      	dist[ data[best][i].neib ] = dist[best] + data[best][i].ener;
        prev[ data[best][i].neib ].neib = best;
        prev[ data[best][i].neib ].ener = i;
      }

    best = 0;

		for(i=1; i<=n; i++)
    	if(!used[i] && dist[i] < dist[best])
      	best = i;
  }
  //printf("DIST = %d\n", dist[end]);
  while(end != start && end != 0){

  	int p = prev[end].neib;
    int q = prev[end].ener;
    energy[p]  = max(energy[p], data[p][q].ener);
		ret.push_back(p);
    //printf("%d ", p);
    end = p;
  }

  if(first){
  	END = ret.size();
  }
  first = false;
  /*
  printf("ENERGY ---\n");
  for(i=0; i<=n; i++)
  	printf("%d ", energy[i]);
	printf("\n");
  */
}

void Output(){
	int sum = 0;
  for(i=1; i<=n; i++)
  	sum += energy[i];

	vector<Type> save_res;

	for(i=END-1; i>=0; i--)
  	if(energy[ ret[i] ]){
      save_res.push_back(Type(ret[i], energy[ret[i]]));
      energy[i] = 0;
    }
    
	for(i=ret.size()-1; i>END; i--)
  	if(energy[ ret[i] ]){
      save_res.push_back(Type(ret[i], energy[ret[i]]));
      energy[i] = 0;
    }
    
  printf("%d %d\n", save_res.size(), sum);
  for(i=0; i<save_res.size(); i++)
  	printf("%d %d\n", save_res[i].neib, save_res[i].ener);

}

int main(){
	Input();
  data[0].push_back(Type(0,0));
  //PrintData();//for debug mode
  Djkstra(a, b);
  Djkstra(a, c);
  Output();
  return 0;
}



