import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.PriorityQueue;
public class Main {
final private int BUFFER_SIZE = 1 << 16;
private byte[] buffer;
private int bufferPointer, bytesRead;
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
buffer = new byte[BUFFER_SIZE];
bufferPointer = bytesRead = 0;
}
byte[] buf = new byte[64]; // line length
int cnt = 0, c;
while ((c = read()) != -1) {
if (c == '\n') {
break;
}
buf[cnt++] = (byte) c;
}
return new String(buf,
0, cnt
);
}
int ret = 0;
byte c = read();
while (c <= ' ') {
c = read();
}
boolean neg = (c == '-');
if (neg) {
c = read();
}
do {
ret = ret * 10 + c - '0';
} while ((c = read()) >= '0' && c <= '9');
if (neg) {
return -ret;
}
return ret;
}
bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
if (bytesRead == -1) {
buffer[0] = -1;
}
}
if (bufferPointer == bytesRead) {
fillBuffer();
}
return buffer[bufferPointer++];
}
if (din == null) {
return;
}
din.close();
}
}
public static void main
(String[] args
) {
StringBuilder sba = new StringBuilder();
try {
int t = sc.nextInt();
while (t-- > 0) {
int n = sc.nextInt();
int numOfEdges = sc.nextInt();
int src = sc.nextInt();
int dest = sc.nextInt();
//System.out.println("n= "+n+" ,exitcell= "+exitCell+" ,timelimit= "+timeLimit+" and numedges= "+numOfEdges);
graph g = new graph(src - 1, dest - 1);
for (int i = 0; i < n; i++) {
g.addVertex(new vertex(i + 1));
}
// System.out.println("going to add edges");
for (int i = 0; i < numOfEdges; i++) {
int source = sc.nextInt();
int destination = sc.nextInt();
int weight = sc.nextInt();
// System.out.println("num of vertices: "+g.vertexList.size());
g.addEdge(g.vertexList.get(source - 1), g.vertexList.get(destination - 1), weight);
// System.out.println("i= "+i);
}
// System.out.println("calling disjktra ");
int count = g.primAlgo(g.vertexList.get(g.srcCellVertexIndex),g.vertexList.get(g.destCellVertexIndex));
sba.append(count).append("\n");
// System.out.println(count);
} else {
sba.append("NONE").append("\n");
// System.out.println("NONE");
}
}
// sba.deleteCharAt(sba.length()-1);
System.
out.
println(sba.
toString());
System.
out.
println(e.
getMessage());
}
}
}
class graph // it is a directed and weighted graph
{
public int srcCellVertexIndex, destCellVertexIndex;
;
public ArrayList<vertex> vertexList;
public int numOfVertices;
public ArrayList<LinkedList<edge>> adjList;
public graph(int src, int dest) {
srcCellVertexIndex = src;
destCellVertexIndex = dest;
vertexList = new ArrayList<>();
adjList = new ArrayList<>();
numOfVertices = 0;
}
public void addVertex(vertex vert) {
vertexList.add(vert);
adjList.add(new LinkedList<>());
numOfVertices++;
}
public void addEdge(vertex source, vertex destination, int weight) {
edge lp = new edge(source, destination, weight);
adjList.get(source.label-1).add(lp);
lp = new edge(destination, source, weight);
adjList.get(destination.label-1).add(lp);
}
public int primAlgo(vertex entryCell,vertex exitCell) {
// System.out.println("src cell "+v.label);
// System.out.println("dest cell "+exitCell.label);
PriorityQueue<vertex> pq = new PriorityQueue<>(new Comparator<vertex>() {
@Override
public int compare(vertex t, vertex t1) {
return t.key - t1.key;
}
});
int count=0;
entryCell.key=0;
entryCell.visited=true;
for(int i=0;i<vertexList.size();i++)
pq.offer(vertexList.get(i));
while(count<vertexList.size()) {
vertex curr=pq.poll();
// System.out.println("visited "+curr.label+" , ");
count+=1;
curr.visited=true;
adjList.get(curr.label - 1).forEach(e -> {
if(e.destination!=e.source && !e.destination.visited )
// {
if(e.destination.key>(e.source.key+e.weight))
{
pq.remove(e.destination);
e.destination.key=e.source.key+e.weight;
// System.out.println(e.destination.label+" new key is "+e.destination.key);
pq.add(e.destination);
}
// }
});
}
// System.out.println("returning "+exitCell.timeExhausted);
return exitCell.key;
}
}
class vertex {
public int label;
public int key;
public boolean visited;
public vertex(int label) {
this.label = label;
this.visited = false;
}
}
class edge {
vertex source, destination;
int weight;
public edge(vertex source, vertex destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
}