/*
TASK:wireless
LANG:C
*/


#include <stdio.h>
#include <stdlib.h>

#define MAXN 4000
#define INF 0xEEFFFFFF

int n,a,b,c;
int *nasl_v[MAXN];
int *nasl_k[MAXN];
int nasl_sz[MAXN];
int *back_nasl_v[MAXN];
int *back_nasl_k[MAXN];
int back_nasl_sz[MAXN];

unsigned int dist[MAXN];
int visited[MAXN];
int parent[MAXN];
int parenti[MAXN];

unsigned int dist_a[MAXN],dist_b[MAXN],dist_c[MAXN];
int parent_a[MAXN],parent_b[MAXN],parent_c[MAXN];
int parenti_a[MAXN],parenti_b[MAXN],parenti_c[MAXN];

int min_d;
int split = -1;
int vr_b,vr_c;
int path_v[MAXN];
int path_k[MAXN];
int path_sz;
int path2_v[MAXN];
int path2_k[MAXN];
int path2_sz;

void Init()
  {
    int i,j;
    
//    freopen("wireless.in","rt",stdin);
    scanf("%d%d%d%d",&n,&a,&b,&c);
    a--;b--;c--;

    for (i = 0;i < n;i++)
      {
        scanf("%d",&nasl_sz[i]);

        nasl_v[i] = (int*)malloc(nasl_sz[i]*sizeof(int));
        nasl_k[i] = (int*)malloc(nasl_sz[i]*sizeof(int));

        for (j = 0;j < nasl_sz[i];j++)
          {
            scanf("%d%d",&nasl_v[i][j],&nasl_k[i][j]);
            nasl_v[i][j]--;
            back_nasl_sz[nasl_v[i][j]]++;
          }

      }
      
    // Make back edges
    for (i = 0;i < n;i++)
      {
        back_nasl_v[i] = (int*)malloc(back_nasl_sz[i]*sizeof(int));
        back_nasl_k[i] = (int*)malloc(back_nasl_sz[i]*sizeof(int));
        back_nasl_sz[i] = 0;
      }

    for (i = 0;i < n;i++)
      for (j = 0;j < nasl_sz[i];j++)
        {
          back_nasl_v[nasl_v[i][j]][back_nasl_sz[nasl_v[i][j]]  ] = i;
          back_nasl_k[nasl_v[i][j]][back_nasl_sz[nasl_v[i][j]]++] = nasl_k[i][j];
        }
        
  }

void Diiks(int vr)
  {
    int min,i;

    memset(visited,0,sizeof(visited));
    for (i = 0;i < n;i++) { dist[i] = INF;parent[i] = -1; }
    dist[vr] = 0;

    while (1)
      {
        min = -1;
        for (i = 0;i < n;i++)
          if (!visited[i] && (min == -1 || dist[min] > dist[i])) min = i;

        if (min == -1) break;
        visited[min] = 1;

        for (i = 0;i < nasl_sz[min];i++)
          if (dist[nasl_v[min][i]] > dist[min] + nasl_k[min][i])
            {
              dist[nasl_v[min][i]] = dist[min] + nasl_k[min][i];
              parent[nasl_v[min][i]] = min;
              parenti[nasl_v[min][i]] = i;
            }
      }
  }

void BackDiiks(int vr)
  {
    int min,i;

    memset(visited,0,sizeof(visited));
    for (i = 0;i < n;i++) { dist[i] = INF;parent[i] = -1; }
    dist[vr] = 0;

    while (1)
      {
        min = -1;
        for (i = 0;i < n;i++)
          if (!visited[i] && (min == -1 || dist[min] > dist[i])) min = i;

        if (min == -1) break;
        visited[min] = 1;

        for (i = 0;i < back_nasl_sz[min];i++)
          if (dist[back_nasl_v[min][i]] > dist[min] + back_nasl_k[min][i])
            {
              dist[back_nasl_v[min][i]] = dist[min] + back_nasl_k[min][i];
              parent[back_nasl_v[min][i]] = min;
              parenti[back_nasl_v[min][i]] = i;
            }
      }
  }

void Solve()
  {
    int vr1,vr2,i,j,k,min_b,min_c;
    
    Diiks(a);
    memcpy(dist_a,dist,sizeof(dist));
    memcpy(parent_a,parent,sizeof(parent));
    memcpy(parenti_a,parenti,sizeof(parent));
    BackDiiks(b);
    memcpy(dist_b,dist,sizeof(dist));
    memcpy(parent_b,parent,sizeof(parent));
    memcpy(parenti_b,parenti,sizeof(parent));
    BackDiiks(c);
    memcpy(dist_c,dist,sizeof(dist));
    memcpy(parent_c,parent,sizeof(parent));
    memcpy(parenti_c,parenti,sizeof(parent));

    // First try direct path
    memset(visited,0,sizeof(visited));
    vr1 = b;
    vr2 = c;
    while (1)
      {
        if ((visited[vr1] || parent_a[vr1] == -1) && (visited[vr2] || parent_a[vr2] == -1)) break;
        
        if (!visited[vr1] && parent_a[vr1] != -1)
          {
            min_d += nasl_k[parent_a[vr1]][parenti_a[vr1]];
            path_v[path_sz  ] = parent_a[vr1];
            path_k[path_sz++] = nasl_k[parent_a[vr1]][parenti_a[vr1]];
            visited[vr1] = 1;
            vr1 = parent_a[vr1];
          }
          
        if (!visited[vr2] && parent_a[vr2] != -1)
          {
            min_d += nasl_k[parent_a[vr2]][parenti_a[vr2]];
            path_v[path_sz  ] = parent_a[vr2];
            path_k[path_sz++] = nasl_k[parent_a[vr2]][parenti_a[vr2]];
            visited[vr2] = 1;
            vr2 = parent_a[vr2];
          }
      }
      
    // Try each splitting point
    for (i = 0;i < n;i++)
      if (dist_a[i] != INF && nasl_sz[i])
        {
          min_b = nasl_v[i][0];
          min_c = nasl_v[i][0];
          for (j = 1;j < nasl_sz[i];j++)
            {
              if (dist_b[nasl_v[i][j]] < dist_b[min_b]) min_b = nasl_v[i][j];
              if (dist_c[nasl_v[i][j]] < dist_c[min_c]) min_c = nasl_v[i][j];
              if (dist_b[min_b] != INF && dist_c[min_c] != INF && min_d > dist_b[min_b] + dist_c[min_c] + nasl_k[i][j] + dist_a[i])
                {
                  min_d = dist_b[min_b] + dist_c[min_c] + nasl_k[i][j] + dist_a[i];
                  split = i;
                  vr_b = min_b;
                  vr_c = min_c;
                }
            }
        }
  }

void Output()
  {
    int i,vr;
    int found;
    // Find the path itself
    if (split == -1)
      {
        // Direct path, which we have found
        printf("%d %d\n",path_sz,min_d);
        for (i = path_sz - 1;i >= 0;i--)
          printf("%d %d\n",path_v[i] + 1,path_k[i]);
      }
    else
      {
        // Split point
        path_sz = 0;
        vr = vr_b;
        while (parent_b[vr] != -1)
          {
            path_v[path_sz  ] = vr;
            path_k[path_sz++] = back_nasl_k[parent_b[vr]][parenti_b[vr]];
            vr = parent_b[vr];
          }
          
        vr = vr_c;
        while (parent_c[vr] != -1)
          {
            path_v[path_sz  ] = vr;
            path_k[path_sz++] = back_nasl_k[parent_c[vr]][parenti_c[vr]];
            vr = parent_c[vr];
          }

        vr = split;
        found = 0;
        for (i = 0;i < nasl_sz[split];i++)
          {
            if (nasl_v[split][i] == vr_b) found++;
            if (nasl_v[split][i] == vr_c) found++;
            if (found == 2)
              {
                path2_v[path2_sz  ] = split;
                path2_k[path2_sz++] = nasl_k[split][i];
                break;
              }
          }
          
        while (parent_a[vr] != -1)
          {
            path2_v[path2_sz  ] = parent_a[vr];
            path2_k[path2_sz++] = nasl_k[parent_a[vr]][parenti_a[vr]];
            vr = parent_a[vr];
          }

        printf("%d %d\n",path_sz + path2_sz,min_d);
        for (i = path2_sz - 1;i >= 0;i--)
          printf("%d %d\n",path2_v[i] + 1,path2_k[i]);
          
        for (i = 0;i < path_sz;i++)
          printf("%d %d\n",path_v[i] + 1,path_k[i]);
      }
  }
  
int main()
  {
    Init();
    Solve();
    Output();
    return 0;
  }
