/*
 * Solution to lights
 */

import java.util.*;
import java.lang.reflect.*;

class Pair {
  public int id, dist;
  public Pair(int i, int d) {
    id = i; dist = d;
  }
}

class Node {
  public int id, gy, r; // node id, green+yellow time, red time
  public ArrayList<Pair> nbr; // edges (neighbors)

  public Node(int id, int gy, int r) {
    this.id = id; this.gy = gy; this.r = r;
    nbr = new ArrayList<Pair>();
  }

  public void add(Pair p) {
    nbr.add(p);
  }
}


public class Lights{
  public static int n, m, s, e; // #lights, #roads, start, end
  public static Node[] graph; // the modified graph (two nodes per light)
  public static ArrayList<Pair> base[]; // the underlying base graph
  public static int caseNum;
  public static Scanner in;
  public static boolean inFringe[]; // from the Dijkstra algorithm
  public static boolean used[]; // nodes already in the shortest path tree
  public static int dist[]; // current shortest distances from s
  public static int parent[]; // parent in the shortest path tree
  public static ArrayList<Integer> fringe; // set of fringe nodes

  public static void main(String[] args) {
    in = new Scanner(System.in);
    caseNum = 0;
    while(true) {
      n = in.nextInt(); m = in.nextInt(); s = in.nextInt(); e = in.nextInt();
      if (n == 0) break;
      caseNum++;
      graph = new Node[2*n];

      base = (ArrayList<Pair>[]) Array.newInstance(ArrayList.class,n);
      for (int i = 0; i < n; i++) {
        base[i] = new ArrayList<Pair>();
      }
      for (int i = 0; i < n; i++) {
        int g = in.nextInt();
        int y = in.nextInt();
        int r = in.nextInt();
        graph[2*i] = new Node(2*i,g+y,r);
        graph[2*i+1] = new Node(2*i+1,g+y,r);
      }
      for (int i = 0; i < m; i++) {
        int l1 = in.nextInt();
        int l2 = in.nextInt();
        int t = in.nextInt();
        base[l1].add(new Pair(l2,t));
        base[l2].add(new Pair(l1,t));
      }
      int answer = solve();
      int hrs = answer/60;
      int min = answer%60;
      System.out.printf("%d:%02d\n",hrs,min);
    }
  }

  public static int solve() {
    inFringe = new boolean[2*n];
    used = new boolean[2*n];
    Arrays.fill(used,false);
    dist = new int[2*n];
    Arrays.fill(dist,Integer.MAX_VALUE);
    parent = new int[2*n];
    fringe = new ArrayList<Integer>();
    
    fringe.add(2*s); // start node added to fringe
    dist[s] = 5; // since car starts from a standstill
    parent[2*s] = -1;
    inFringe[2*s] = true;

    while (!fringe.isEmpty()) {
      int k = deleteMin(fringe);
      if (!inFringe[k])
        continue;
      used[k] = true;
      used[2*(k/2)] = true;
      used[2*(k/2)+1] = true;
      int d = dist[k/2];

      int kb = k/2; // corresponding base graph node
      if (kb == e)
        return d;
      for (int i = 0; i < base[kb].size(); i++) {
        int ib = base[kb].get(i).id;
        if (used[2*ib] || used[2*ib+1])
          continue;
        int db = base[kb].get(i).dist;
        int gytime = graph[2*ib].gy; // could use either 2*ib or 2*ib+1 here
        int rtime = graph[2*ib].r;
        if ((d + db)%(gytime + rtime) < gytime || ib==e) {
          if (d+db < dist[ib]) {
            dist[ib] = d+db;
            parent[2*ib+1] = k;

            if (!inFringe[2*ib+1]) {
              inFringe[2*ib+1] = true;
              fringe.add(2*ib+1);
              inFringe[2*ib] = false;
            }
          }
        }
        else {
          if (ib != e) {
            db += (gytime+rtime) - (d+db)%(gytime+rtime);
            db += 5;
          }
          if (d+db < dist[ib]) {
            dist[ib] = d+db;
            parent[2*ib] = k;
            if (!inFringe[2*ib]) {
              inFringe[2*ib] = true;
              inFringe[2*ib+1] = false;
              fringe.add(2*ib);
            }
          }
        }
      }
    }
    return -1; // this shouldn't happen
  }

  public static int deleteMin(ArrayList<Integer> fringe) {
    int min = Integer.MAX_VALUE;
    int minLoc = 0;
    int minId = 0;
    for (int i = 0; i < fringe.size(); i++) {
      int d = dist[fringe.get(i)/2];
      if (d < min) {
        min = d;
        minId = fringe.get(i);
        minLoc = i;
      }
    }
    fringe.remove(minLoc);
    return minId;
  }
}
