/*
TASK:wireless
LANG:C
*/
#include <stdio.h>
#define MAX 1420

long low(long pasta, long pjure);
void find(int V);

struct
{
 int  v;
 long p;
} mas[MAX][MAX],tmp[MAX][MAX];

long to[3][MAX];
int fat[3][MAX];
int res[3][MAX];

long kosta;
int n,a,b,c;

int main()
{long i,p,k,kk,l,ll,s,ss,min,pom;
 //FILE *f=fopen("wireless.in","r");
 scanf("%d%d%d%d",&n,&a,&b,&c);
 a--;
 b--;
 c--;
 for(i=0; i<n; i++)
   {
   scanf("%d",&mas[i][0].p);
   for(p=0; p<mas[i][0].p; p++)
     {
     scanf("%d%d",&mas[i][p+1].v,&mas[i][p+1].p);
     mas[i][p+1].v--;
     }
   }
// fclose(f);

 for(p=0; p<3; p++)
  for(i=0; i<n; i++) to[p][i]=-1;
 to[0][a]=0;
 to[1][b]=0;
 to[2][c]=0;
 find(a);
 for(i=0; i<n; i++)
  for(p=1; p<=mas[i][0].p; p++)
    {
    k=mas[i][p].p;
    l=mas[i][p].v;
    tmp[l][0].p++;
    tmp[l][tmp[l][0].p].v=i;
    tmp[l][tmp[l][0].p].p=k;
    }
 for(i=0; i<=n; i++)
  for(p=0; p<=n; p++) mas[i][p]=tmp[i][p];
 find(b);
 find(c);
 fat[1][b]=n;
 fat[2][c]=n;
 to[1][n]=to[2][n]=0;
 min=-1;
 for(i=0; i<n; i++)
  {
  if((to[0][i]+to[1][fat[1][i]]+to[2][fat[2][i]]+low(to[1][i]-to[1][fat[1][i]],to[2][i]-to[2][fat[2][i]])<min)||(min==-1))
    {
    if(fat[1][i]==fat[2][i]) continue;
    kosta=low(to[1][i]-to[1][fat[1][i]],to[2][i]-to[2][fat[2][i]]);
    min=to[0][i]+to[1][fat[1][i]]+to[2][fat[2][i]]+low(to[1][i]-to[1][fat[1][i]],to[2][i]-to[2][fat[2][i]]);
    p=i;
    }
  }
 l=0;
 if(fat[0][p]==n) l=-1; else
 for(i=p; fat[0][i]!=a; )
   {
   i=fat[0][i];
   res[0][l++]=i;
   }
 if(l>-1) res[0][l]=a;
 k=0;
 if(fat[1][p]==n) k=-1; else
 for(i=p; fat[1][i]!=b; )
   {
   i=fat[1][i];
   res[1][k++]=i;
   }
 if(k>-1) res[1][k]=b;
 s=0;
 if(fat[2][p]==n) s=-1; else
 for(i=p; fat[2][i]!=b; )
   {
   i=fat[2][i];
   res[2][s++]=i;
   }
 if(s>-1) res[2][s]=b;
 l++;

 ll=l;
 kk=k;
 ss=s;
 if(s==-1) ss=0;
 if(k==-1) kk=0;
 if(l==-1) ll=0;
 printf("%ld %ld\n",ll+kk+ss+1,min);
 for(i=l-1; i>=0; i--)
  {
  if(i==0) pom=p; else pom=res[0][i-1];
  printf("%ld %ld\n",res[0][i]+1,to[0][pom]-to[0][res[0][i]]);
  }
 printf("%ld %ld\n",p+1,kosta);
 for(i=k-1; i>=0; i--)
  {
  if(i==0) pom=p; else pom=res[1][i-1];
  printf("%ld %ld\n",res[1][i]+1,to[1][pom]-to[1][res[1][i]]);
  }
 for(i=s-1; i>=0; i--)
  {
  if(i==0) pom=p; else pom=res[2][i-1];
  printf("%ld %ld\n",res[2][i]+1,to[2][pom]-to[2][res[2][i]]);
  }

return 0;
}

long low(long pasta, long pjure)
{
 if(pasta>pjure) return pasta;
 return pjure;
}

void find(int V)
{int i,ind,p,ttt;
 int bfs[MAX];
 int pos[MAX];

 for(i=0; i<n; i++) pos[i]=0;
 pos[V]=1;
 bfs[0]=V;
 ind=1;
 if(V==a) ttt=0; else if(V==b) ttt=1; else ttt=2;
 for(i=0; i<ind; i++)
   {
   for(p=1; p<=mas[bfs[i]][0].p; p++)
    if(!pos[mas[bfs[i]][p].v])
      {
      bfs[ind]=mas[bfs[i]][p].v;
      pos[mas[bfs[i]][p].v]=1;
      if((to[ttt][bfs[ind]]==-1)||(to[ttt][bfs[ind]]>to[ttt][bfs[i]]+mas[bfs[i]][p].p))
        {
        to[ttt][bfs[ind]]=to[ttt][bfs[i]]+mas[bfs[i]][p].p;
        fat[ttt][bfs[ind]]=bfs[i];
        }
      ind++;
      }
   }
/*
 for(i=0; i<n; i++) pos[i]=0;
 pos[a]=1;
 for(i=0; i<n; i++)
  if(!pos[bfs[i]])
   for()*/
}
