import ru.ifmo.testlib.Checker;
import ru.ifmo.testlib.InStream;
import ru.ifmo.testlib.Outcome;

import java.util.HashSet;
import java.util.Set;
import java.util.*;

public class Check implements Checker {
    public Outcome test(InStream inf, InStream ouf, InStream ans) {
        int n = inf.nextInt();
        int m = inf.nextInt();
        int s = inf.nextInt();
        int r = inf.nextInt();
        int jAns = ans.nextInt();
        int pAns = ouf.nextInt();
        if (pAns == -1) {
            if (jAns == -1) {
                return new Outcome(Outcome.Type.OK, "No solution");
            }
            return new Outcome(Outcome.Type.WA, "Solution exists, but participant didn't find any");
        }
        Edge[] g = new Edge[m];
        g[0] = new Edge(pAns - 1, ouf.nextInt() - 1, ouf.nextInt());
        for (int i = 1; i < m; i++) {
            int from = ouf.nextInt() - 1;
            int to = ouf.nextInt() - 1;
            int w = ouf.nextInt();
            g[i] = new Edge(from, to, w);
        }
        Set<Edge> edges = new HashSet<>();
        for (int i = 0; i < m; i++) {
            if (g[i].from < 0 || g[i].from >= n || g[i].to < 0 || g[i].to >= n || g[i].from == g[i].to) {
                return new Outcome(Outcome.Type.WA, "Edge #" + (i + 1) + " = [" + (g[i].from + 1) + ", " + (g[i].to + 1) + "], while n = " + n);
            }
            if (!edges.add(new Edge(g[i].from, g[i].to, 0))) {
                return new Outcome(Outcome.Type.WA, "Edge [" + (g[i].from + 1) + ", " + (g[i].to + 1) + "] has appeared twice in the graph");
            }
            if (g[i].w <= 0 || g[i].w > r) {
                return new Outcome(Outcome.Type.WA, "Edge #" + (i + 1) + " has weight = " + g[i].w + ", while r = " + r);
            }
        }
        DSU dsu = new DSU(n);
        Arrays.sort(g);
        int cnt = n;
        int sum = 0;
        for (int i = 0; i < m; i++) {
            if (dsu.get(g[i].from) != dsu.get(g[i].to)) {
                dsu.union(g[i].from, g[i].to);
                cnt--;
                sum += g[i].w;
            }
        }
        if (sum != s) {
            return new Outcome(Outcome.Type.WA, "weight of the tree is " + sum + " != " + s);
        }
        if (cnt != 1) {
            return new Outcome(Outcome.Type.WA, "There's no connectivity :( ");
        }
        if (jAns == -1) {
            return new Outcome(Outcome.Type.FAIL, "participant did find correct solution, but jury couldn't");
        }
        return new Outcome(Outcome.Type.OK, "n = " + n + ", m = " + m + ", s = " + s + ", r = " + r);
    }

    static class DSU {
        int[] p;

        DSU(int n) {
            p = new int[n];
            for (int i = 0; i < n; i++) {
                p[i] = i;
            }
        }

        int get(int x) {
            return x == p[x] ? x : (p[x] = get(p[x]));
        }

        void union(int x, int y) {
            p[get(x)] = get(y);
        }
    }

    static class Edge implements Comparable<Edge> {
        int from;
        int to;
        int w;

        Edge(int from, int to, int w) {
            if (from > to) {
                int t = from;
                from = to;
                to = t;
            }
            this.from = from;
            this.to = to;
            this.w = w;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Edge edge = (Edge) o;

            if (from != edge.from) return false;
            if (to != edge.to) return false;
            if (w != edge.w) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = from;
            result = 31 * result + to;
            result = 31 * result + w;
            return result;
        }

        @Override
        public int compareTo(Edge o) {
            return Integer.compare(w, o.w);
        }
    }
}
