Problem: Some country consists of n cities, connected by a railroad network. The transport communication of the country is so advanced that the network consists of a minimum required number of (n - 1) bidirectional roads (in the other words, the graph of roads is a tree). The i-th road that directly connects cities ai and bi, has the length of li kilometers.

The transport network is served by a state transporting company FRR (Fabulous Rail Roads). In order to simplify the price policy, it offers a single ride fare on the train. In order to follow the route of length t kilometers, you need to pay <image> burles. Note that it is forbidden to split a long route into short segments and pay them separately (a special railroad police, or RRP, controls that the law doesn't get violated).

A Large Software Company decided to organize a programming tournament. Having conducted several online rounds, the company employees determined a list of finalists and sent it to the logistical department to find a place where to conduct finals. The Large Software Company can easily organize the tournament finals in any of the n cities of the country, so the the main factor in choosing the city for the last stage of the tournament is the total cost of buying tickets for all the finalists. We know that the i-th city of the country has wi cup finalists living there.

Help the company employees find the city such that the total cost of travel of all the participants to it is minimum.

Input

The first line of the input contains number n (1 ≤ n ≤ 200 000) — the number of cities in the country.

The next line contains n integers w1, w2, ..., wn (0 ≤ wi ≤ 108) — the number of finalists living in each city of the country.

Next (n - 1) lines contain the descriptions of the railroad, the i-th line contains three integers, ai, bi, li (1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ li ≤ 1000).

Output

Print two numbers — an integer f that is the number of the optimal city to conduct the competition, and the real number c, equal to the minimum total cost of transporting all the finalists to the competition. Your answer will be considered correct if two conditions are fulfilled at the same time: 

  1. The absolute or relative error of the printed number c in comparison with the cost of setting up a final in city f doesn't exceed 10 - 6; 
  2. Absolute or relative error of the printed number c in comparison to the answer of the jury doesn't exceed 10 - 6. 



If there are multiple answers, you are allowed to print any of them.

Examples

Input

5
3 1 2 6 5
1 2 3
2 3 1
4 3 9
5 3 1


Output

3 192.0

Input

2
5 5
1 2 2


Output

1 14.142135623730951000

Note

In the sample test an optimal variant of choosing a city to conduct the finals of the competition is 3. At such choice the cost of conducting is <image> burles.

In the second sample test, whatever city you would choose, you will need to pay for the transport for five participants, so you will need to pay <image> burles for each one of them.

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author I and Bee
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        OutputWriter out;
        int n;
        long[] cntInV;
        BidirectionalGraph gr;
        BidirectionalGraph grBeg;
        int[] sz;
        int ansV;
        double ansTarget;

        private void getAns(final int v) {
            sz = new int[n];
            initSz(v, -1);

            int p = -1;
            int center = v;
            //
            for (boolean go = true; go; ) {
                go = false;
                for (int id = gr.firstOutbound(center); id != -1; id = gr.nextOutbound(id)) {
                    int to = gr.destination(id);
                    if (to == p) continue;
                    if (2 * sz[to] >= sz[v]) {
                        p = center;
                        center = to;
                        go = true;
                        break;
                    }
                }
            }
        /**/

            double sumGrad = 0;
            double[] grad = new double[n];
            for (int id = gr.firstOutbound(center); id != -1; id = gr.nextOutbound(id)) {
                int to = gr.destination(id);
                grad[to] = getSome(to, center, gr.weight(id), false);
                sumGrad += grad[to];
            }

            double maxGrad = Double.MIN_VALUE;
            int go = -1;
            for (int id = gr.firstOutbound(center); id != -1; id = gr.nextOutbound(id)) {
                int to = gr.destination(id);
                double curGrad = -sumGrad + 2 * grad[to];
//            System.err.printf("%2d %2d %15.2f\n", center, to, curGrad);
                if (maxGrad < curGrad) {
                    maxGrad = curGrad;
                    go = to;
                }
            }

            for (int id = gr.firstOutbound(center); id != -1; id = gr.nextOutbound(id)) {
                gr.removeEdge(id);
                gr.removeEdge(gr.transposed(id));
            }

            double curTarget = getSome(center, -1, 0, true);
            if (ansTarget > curTarget) {
                ansTarget = curTarget;
                ansV = center;
            }

            if (go != -1) {
                curTarget = getSome(go, -1, 0, true);
                if (ansTarget > curTarget) {
                    ansTarget = curTarget;
                    ansV = go;
                }
                getAns(go);
            }
        }

        private void initSz(int v, int p) {
            sz[v] = 1;
            for (int id = gr.firstOutbound(v); id != -1; id = gr.nextOutbound(id)) {
                int to = gr.destination(id);
                if (to == p) continue;
                initSz(to, v);
                sz[v] += sz[to];
            }
        }

        double getSome(int v, int p, long dist, boolean pow15) {
            double res = cntInV[v] * Math.sqrt(dist);
            if (pow15) res *= dist;
            for (int id = grBeg.firstOutbound(v); id != -1; id = grBeg.nextOutbound(id)) {
                int to = grBeg.destination(id);
                if (to == p) continue;
                res += getSome(to, v, dist + grBeg.weight(id), pow15);
            }
            return res;
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            this.out = out;
            n = in.readInt();
            cntInV = IOUtils.readLongArray(in, n);
            {
                int[] a, b, l;
                a = new int[n - 1];
                b = new int[n - 1];
                l = new int[n - 1];
                IOUtils.readIntArrays(in, a, b, l);
                MiscUtils.decreaseByOne(a, b);
                gr = BidirectionalGraph.createWeightedGraph(n, a, b, ArrayUtils.asLong(l));
                grBeg = BidirectionalGraph.createWeightedGraph(n, a, b, ArrayUtils.asLong(l));
            }

            ansV = -1;
            ansTarget = Double.MAX_VALUE;
            getAns(0);
            out.printFormat("%d %.20f\n", ansV + 1, ansTarget);
//        getAns(1);
//        getAns(7);
        }

    }

    static class IOUtils {
        public static long[] readLongArray(InputReader in, int size) {
            long[] array = new long[size];
            for (int i = 0; i < size; i++)
                array[i] = in.readLong();
            return array;
        }

        public static void readIntArrays(InputReader in, int[]... arrays) {
            for (int i = 0; i < arrays[0].length; i++) {
                for (int j = 0; j < arrays.length; j++)
                    arrays[j][i] = in.readInt();
            }
        }

    }

    static class BidirectionalGraph extends Graph {
        public int[] transposedEdge;

        public BidirectionalGraph(int vertexCount) {
            this(vertexCount, vertexCount);
        }

        public BidirectionalGraph(int vertexCount, int edgeCapacity) {
            super(vertexCount, 2 * edgeCapacity);
            transposedEdge = new int[2 * edgeCapacity];
        }

        public static BidirectionalGraph createWeightedGraph(int vertexCount, int[] from, int[] to, long[] weight) {
            BidirectionalGraph graph = new BidirectionalGraph(vertexCount, from.length);
            for (int i = 0; i < from.length; i++)
                graph.addWeightedEdge(from[i], to[i], weight[i]);
            return graph;
        }


        public int addEdge(int fromID, int toID, long weight, long capacity, int reverseEdge) {
            int lastEdgeCount = edgeCount;
            super.addEdge(fromID, toID, weight, capacity, reverseEdge);
            super.addEdge(toID, fromID, weight, capacity, reverseEdge == -1 ? -1 : reverseEdge + 1);
            this.transposedEdge[lastEdgeCount] = lastEdgeCount + 1;
            this.transposedEdge[lastEdgeCount + 1] = lastEdgeCount;
            return lastEdgeCount;
        }


        protected int entriesPerEdge() {
            return 2;
        }


        public final int transposed(int id) {
            return transposedEdge[id];
        }


        protected void ensureEdgeCapacity(int size) {
            if (size > edgeCapacity()) {
                super.ensureEdgeCapacity(size);
                transposedEdge = resize(transposedEdge, edgeCapacity());
            }
        }

    }

    static class Graph {
        public static final int REMOVED_BIT = 0;
        protected int vertexCount;
        protected int edgeCount;
        private int[] firstOutbound;
        private int[] firstInbound;
        private Edge[] edges;
        private int[] nextInbound;
        private int[] nextOutbound;
        private int[] from;
        private int[] to;
        private long[] weight;
        public long[] capacity;
        private int[] reverseEdge;
        private int[] flags;

        public Graph(int vertexCount) {
            this(vertexCount, vertexCount);
        }

        public Graph(int vertexCount, int edgeCapacity) {
            this.vertexCount = vertexCount;
            firstOutbound = new int[vertexCount];
            Arrays.fill(firstOutbound, -1);

            from = new int[edgeCapacity];
            to = new int[edgeCapacity];
            nextOutbound = new int[edgeCapacity];
            flags = new int[edgeCapacity];
        }

        public int addEdge(int fromID, int toID, long weight, long capacity, int reverseEdge) {
            ensureEdgeCapacity(edgeCount + 1);
            if (firstOutbound[fromID] != -1)
                nextOutbound[edgeCount] = firstOutbound[fromID];
            else
                nextOutbound[edgeCount] = -1;
            firstOutbound[fromID] = edgeCount;
            if (firstInbound != null) {
                if (firstInbound[toID] != -1)
                    nextInbound[edgeCount] = firstInbound[toID];
                else
                    nextInbound[edgeCount] = -1;
                firstInbound[toID] = edgeCount;
            }
            this.from[edgeCount] = fromID;
            this.to[edgeCount] = toID;
            if (capacity != 0) {
                if (this.capacity == null)
                    this.capacity = new long[from.length];
                this.capacity[edgeCount] = capacity;
            }
            if (weight != 0) {
                if (this.weight == null)
                    this.weight = new long[from.length];
                this.weight[edgeCount] = weight;
            }
            if (reverseEdge != -1) {
                if (this.reverseEdge == null) {
                    this.reverseEdge = new int[from.length];
                    Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
                }
                this.reverseEdge[edgeCount] = reverseEdge;
            }
            if (edges != null)
                edges[edgeCount] = createEdge(edgeCount);
            return edgeCount++;
        }

        protected final Graph.GraphEdge createEdge(int id) {
            return new Graph.GraphEdge(id);
        }

        public final int addFlowWeightedEdge(int from, int to, long weight, long capacity) {
            if (capacity == 0) {
                return addEdge(from, to, weight, 0, -1);
            } else {
                int lastEdgeCount = edgeCount;
                addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
                return addEdge(from, to, weight, capacity, lastEdgeCount);
            }
        }

        protected int entriesPerEdge() {
            return 1;
        }

        public final int addWeightedEdge(int from, int to, long weight) {
            return addFlowWeightedEdge(from, to, weight, 0);
        }

        protected final int edgeCapacity() {
            return from.length;
        }

        public final int firstOutbound(int vertex) {
            int id = firstOutbound[vertex];
            while (id != -1 && isRemoved(id))
                id = nextOutbound[id];
            return id;
        }

        public final int nextOutbound(int id) {
            id = nextOutbound[id];
            while (id != -1 && isRemoved(id))
                id = nextOutbound[id];
            return id;
        }

        public final int destination(int id) {
            return to[id];
        }

        public final long weight(int id) {
            if (weight == null)
                return 0;
            return weight[id];
        }

        public final boolean flag(int id, int bit) {
            return (flags[id] >> bit & 1) != 0;
        }

        public final void setFlag(int id, int bit) {
            flags[id] |= 1 << bit;
        }

        public final void removeEdge(int id) {
            setFlag(id, REMOVED_BIT);
        }

        public final boolean isRemoved(int id) {
            return flag(id, REMOVED_BIT);
        }

        protected void ensureEdgeCapacity(int size) {
            if (from.length < size) {
                int newSize = Math.max(size, 2 * from.length);
                if (edges != null)
                    edges = resize(edges, newSize);
                from = resize(from, newSize);
                to = resize(to, newSize);
                nextOutbound = resize(nextOutbound, newSize);
                if (nextInbound != null)
                    nextInbound = resize(nextInbound, newSize);
                if (weight != null)
                    weight = resize(weight, newSize);
                if (capacity != null)
                    capacity = resize(capacity, newSize);
                if (reverseEdge != null)
                    reverseEdge = resize(reverseEdge, newSize);
                flags = resize(flags, newSize);
            }
        }

        protected final int[] resize(int[] array, int size) {
            int[] newArray = new int[size];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }

        private long[] resize(long[] array, int size) {
            long[] newArray = new long[size];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }

        private Edge[] resize(Edge[] array, int size) {
            Edge[] newArray = new Edge[size];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }

        protected class GraphEdge implements Edge {
            protected int id;

            protected GraphEdge(int id) {
                this.id = id;
            }

        }

    }

    static class MiscUtils {
        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++)
                    array[i]--;
            }
        }

    }

    static interface Edge {
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long readLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class ArrayUtils {
        public static long[] asLong(int[] array) {
            long[] result = new long[array.length];
            for (int i = 0; i < array.length; i++)
                result[i] = array[i];
            return result;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void printFormat(String format, Object... objects) {
            writer.printf(format, objects);
        }

        public void close() {
            writer.close();
        }

    }
}