//package tinkoff2017.e;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		int[] a = na(4);
		for(int i = 0;i < 4;i++){
			a[i]--;
		}
		int[] par = new int[n];
		par[0] = -1;
		for(int i = 1;i <n;i++){
			par[i] = ni()-1;
		}
		int[][] g = parentToG(par);
		int[][] pars = parents3(g, 0);
		int[] ord = pars[1];
		boolean[][] dp = new boolean[n][];
		int[] dom = new int[n];
		Arrays.fill(dom, -1);
		int[] des = new int[n];
		des[0]++;
		outer:
		for(int i = n-1;i >= 1;i--){
			int cur = ord[i];
			des[cur]++;
			des[par[cur]] += des[cur];
			for(int j = 0;j < 4;j++){
				if(a[j] == cur){
					dom[cur] = j;
					dp[cur] = new boolean[]{true};
					continue outer;
				}
			}
			int dome = -1;
			for(int e : g[cur]){
				if(par[cur] == e)continue;
				if(dom[e] != -1){
					dom[cur] = dom[e];
					dome = e;
					break;
				}
			}
			if(dom[cur] == -1)continue;
			dp[cur] = new boolean[2*des[cur]-1];
			for(int j = 0;j < dp[dome].length;j++){
				dp[cur][j+1] = dp[dome][j];
			}
			for(int e : g[cur]){
				if(par[cur] == e)continue;
				if(dome == e)continue;
				for(int j = dp[cur].length-1-(des[e]+1);j >= 0;j--){
					dp[cur][j+des[e]+1] |= dp[cur][j];
				}
			}
//			tr(dom[cur]);
//			tf(dp[cur]);
		}
//		tr(dom);

		boolean[][] ep = new boolean[n+1][n+1];
		ep[0][0] = true;
		int[] xds = new int[n+1];
		boolean[][] dps = new boolean[4][];
		int[] fa = new int[4];
		for(int e : g[0]){
			if(dom[e] == -1){
				xds[des[e]+1]++;
			}else{
				dps[dom[e]] = dp[e];
				fa[dom[e]] = dp[e].length;
			}
		}
		int rem = 0;
		for(int i = 1;i <= n;i++){
			if(xds[i] == 0)continue;
			rem += xds[i]*i;
			int j = 1;
			for(;j <= xds[i];j *=2){
				for(int k = 0;k <= rem-i*j;k++){
					for(int l = 0;l <= rem-i*j;l++){
						ep[k+i*j][l+i*j] |= ep[k][l];
						ep[k+i*j][l] |= ep[k][l];
						ep[k][l+i*j] |= ep[k][l];
					}
				}
			}
			xds[i] -= j/2;
			if(xds[i] > 0){
				j = xds[i];
				for(int k = 0;k <= rem-i*j;k++){
					for(int l = 0;l <= rem-i*j;l++){
						ep[k+i*j][l+i*j] |= ep[k][l];
						ep[k+i*j][l] |= ep[k][l];
						ep[k][l+i*j] |= ep[k][l];
					}
				}
			}
		}
		// a c b d
		{
			boolean[] canab = new boolean[n+1];
			for(int i = 0;i < dps[0].length;i++){
				for(int j = 0;j < dps[1].length;j++){
					if(dps[0][i] && dps[1][j]){
						int len = n-2-(dps[0].length-i-1 + j + 1) - (fa[2]+1);
						if(len >= 0)canab[len] = true;
					}
				}
			}
			boolean[] cancd = new boolean[n+1];
			for(int i = 0;i < dps[2].length;i++){
				for(int j = 0;j < dps[3].length;j++){
					if(dps[2][i] && dps[3][j]){
						int len = n-2-(dps[2].length-i-1 + j + 1) - (fa[1]+1);
						if(len >= 0)cancd[len] = true;
					}
				}
			}
			for(int i = 0;i <= n;i++){
				for(int j = 0;j <= n;j++){
					if(ep[i][j] && canab[i] && cancd[j]){
						out.println("YES");
						return;
					}
				}
			}
		}
		{
			boolean[] canab = new boolean[n+1];
			for(int i = 0;i < dps[0].length;i++){
				for(int j = 0;j < dps[1].length;j++){
					if(dps[0][i] && dps[1][j]){
						int len = n-2-(dps[0].length-i-1 + j + 1) - (fa[3]+1);
						if(len >= 0)canab[len] = true;
					}
				}
			}
			boolean[] cancd = new boolean[n+1];
			for(int i = 0;i < dps[3].length;i++){
				for(int j = 0;j < dps[2].length;j++){
					if(dps[3][i] && dps[2][j]){
						int len = n-2-(dps[3].length-i-1 + j + 1) - (fa[1]+1);
						if(len >= 0)cancd[len] = true;
					}
				}
			}
			for(int i = 0;i <= n;i++){
				for(int j = 0;j <= n;j++){
					if(ep[i][j] && canab[i] && cancd[j]){
						out.println("YES");
						return;
					}
				}
			}
		}
		out.println("NO");
	}

	public static void tf(boolean... r)
	{
		for(boolean x : r)System.out.print(x?'#':'.');
		System.out.println();
	}

	public static int[][] parents3(int[][] g, int root) {
		int n = g.length;
		int[] par = new int[n];
		Arrays.fill(par, -1);

		int[] depth = new int[n];
		depth[0] = 0;

		int[] q = new int[n];
		q[0] = root;
		for (int p = 0, r = 1; p < r; p++) {
			int cur = q[p];
			for (int nex : g[cur]) {
				if (par[cur] != nex) {
					q[r++] = nex;
					par[nex] = cur;
					depth[nex] = depth[cur] + 1;
				}
			}
		}
		return new int[][] { par, q, depth };
	}

	public static int[][] parentToG(int[] par)
	{
		int n = par.length;
		int[] ct = new int[n];
		for(int i = 0;i < n;i++){
			if(par[i] >= 0){
				ct[i]++;
				ct[par[i]]++;
			}
		}
		int[][] g = new int[n][];
		for(int i = 0;i < n;i++){
			g[i] = new int[ct[i]];
		}
		for(int i = 0;i < n;i++){
			if(par[i] >= 0){
				g[par[i]][--ct[par[i]]] = i;
				g[i][--ct[i]] = par[i];
			}
		}
		return g;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
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);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public int n;
        public int s;
        public int m;
        public List<Integer>[] graph;
        public int[][] dist;
        public boolean[] leaf;
        public int[] cc;
        public int MAXANS = 50 * 50 * 50;
        public ArrayList<Integer> leaves;
        public int count;
        public int[][] dp;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            n = in.nextInt();
            dist = new int[n][n];
            for (int[] x : dist) Arrays.fill(x, 1 << 29);
            for (int i = 0; i < n; i++) dist[i][i] = 0;
            graph = LUtils.genArrayList(n);
            for (int i = 0; i < n - 1; i++) {
                int a = in.nextInt() - 1, b = in.nextInt() - 1, c = in.nextInt();
                dist[a][b] = dist[b][a] = c;
                graph[a].add(b);
                graph[b].add(a);
            }
            leaf = new boolean[n];
            for (int i = 0; i < n; i++) {
                leaf[i] = graph[i].size() == 1;
            }
            for (int k = 0; k < n; k++) {
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < n; j++) {
                        dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
                    }
                }
            }
            s = in.nextInt() - 1;
            m = in.nextInt();
            cc = new int[n];
            for (int i = 0; i < m; i++) cc[in.nextInt() - 1]++;

            dp = new int[n + 1][m + 1];
            int best = Integer.MAX_VALUE;
            for (int[] x : dp) Arrays.fill(x, -1);
            for (int j : graph[s]) {
                count = 0;
                leaves = new ArrayList<>();
                dfs(j, s);

                if (count > 0) {
                    int lo = 0, hi = MAXANS;
                    while (lo < hi) {
                        int mid = (lo + hi + 1) / 2;
                        if (can2(mid, count)) lo = mid;
                        else hi = mid - 1;
                    }
                    best = Math.min(best, lo);
                }
            }
            out.println(best);
        }

        public boolean can2(int target, int have) {
            int tot = 0;
            for (int j : leaves) {
                int add = dist[s][j];
                if (solve(j, m - 1) + add >= target) {
                    int canadd = 1;
                    while (canadd < have && solve(j, m - canadd - 1) + add >= target) canadd++;
                    tot += canadd;
                }
            }
            return tot >= have;
        }

        public void dfs(int node, int par) {
            if (leaf[node]) leaves.add(node);
            count += cc[node];
            for (int next : graph[node]) {
                if (next == par) continue;
                dfs(next, node);
            }
        }

        public int solve(int node, int crim) {
            if (crim == 0) return 0;
            if (dp[node][crim] != -1) return dp[node][crim];
            int lo = 0, hi = MAXANS;
            while (lo < hi) {
                int mid = (lo + hi + 1) / 2;
                if (can(mid, node, crim)) lo = mid;
                else hi = mid - 1;
            }
            return dp[node][crim] = lo;
        }

        public boolean can(int target, int node, int crim) {
            int tot = 0;
            for (int j = 0; j < n; j++) {
                if (leaf[j] && j != node) {
                    int add = dist[node][j];
                    if (solve(j, crim - 1) + add >= target) {
                        int canadd = 1;
                        while (canadd < crim && solve(j, crim - canadd - 1) + add >= target) canadd++;
                        tot += canadd;
                    }
                }
            }
            return tot >= crim;
        }

    }

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

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

        public int read() {
            if (this.numChars == -1) {
                throw new InputMismatchException();
            } else {
                if (this.curChar >= this.numChars) {
                    this.curChar = 0;

                    try {
                        this.numChars = this.stream.read(this.buf);
                    } catch (IOException var2) {
                        throw new InputMismatchException();
                    }

                    if (this.numChars <= 0) {
                        return -1;
                    }
                }

                return this.buf[this.curChar++];
            }
        }

        public int nextInt() {
            int c;
            for (c = this.read(); isSpaceChar(c); c = this.read()) {
                ;
            }

            byte sgn = 1;
            if (c == 45) {
                sgn = -1;
                c = this.read();
            }

            int res = 0;

            while (c >= 48 && c <= 57) {
                res *= 10;
                res += c - 48;
                c = this.read();
                if (isSpaceChar(c)) {
                    return res * sgn;
                }
            }

            throw new InputMismatchException();
        }

        public static boolean isSpaceChar(int c) {
            return c == 32 || c == 10 || c == 13 || c == 9 || c == -1;
        }

    }

    static class LUtils {
        public static <E> List<E>[] genArrayList(int size) {
            return Stream.generate(ArrayList::new).limit(size).toArray(List[]::new);
        }

    }

    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 close() {
            writer.close();
        }

        public void println(int i) {
            writer.println(i);
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskE {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            TaskE.Vertex[] v = new TaskE.Vertex[n];
            for (int i = 0; i < n; ++i) {
                v[i] = new TaskE.Vertex();
            }
            for (int i = 0; i < n - 1; ++i) {
                TaskE.Vertex a = v[in.nextInt() - 1];
                TaskE.Vertex b = v[in.nextInt() - 1];
                long len = in.nextLong();
                TaskE.Edge ab = new TaskE.Edge(a, b, len);
                TaskE.Edge ba = new TaskE.Edge(b, a, len);
                ab.rev = ba;
                ba.rev = ab;
                a.edges.add(ab);
                b.edges.add(ba);
            }
            TaskE.Vertex police = v[in.nextInt() - 1];
            int m = in.nextInt();
            for (int i = 0; i < m; ++i) {
                ++v[in.nextInt() - 1].startCount;
            }
            for (TaskE.Vertex u : v) {
                for (TaskE.Edge e : u.edges) {
                    e.res = new long[m + 1][m + 1];
                    for (long[] x : e.res) Arrays.fill(x, -1);
                }
            }
            police.findSubtreeSums(null);
            long res = Long.MAX_VALUE;
            for (TaskE.Edge e : police.edges)
                if (e.dst.subtreeSum > 0) {
                    res = Math.min(res, e.solve(m, e.dst.subtreeSum));
                }
            out.println(res);
        }

        static class Edge {
            TaskE.Vertex src;
            TaskE.Vertex dst;
            TaskE.Edge rev;
            long[][] res;
            long len;

            public Edge(TaskE.Vertex src, TaskE.Vertex dst, long len) {
                this.src = src;
                this.dst = dst;
                this.len = len;
            }

            public long solve(int totalRemaining, int inSubtree) {
                if (totalRemaining == 0) return 0;
                if (res[totalRemaining][inSubtree] >= 0) return res[totalRemaining][inSubtree];
                boolean any = false;
                long[] worst = new long[totalRemaining + 1];
                Arrays.fill(worst, -1);
                worst[0] = Long.MAX_VALUE;
                for (TaskE.Edge e : dst.edges) {
                    if (e.dst != src) {
                        any = true;
                        for (int before = worst.length - 1; before >= 0; --before)
                            if (worst[before] >= 0) {
                                for (int here = 1; before + here <= totalRemaining; ++here) {
                                    long got = e.solve(totalRemaining, here);
                                    worst[before + here] = Math.max(worst[before + here], Math.min(worst[before], got));
                                }
                            }
                    }
                }
                if (!any) {
                    for (int a = 1; a <= totalRemaining; ++a) {
                        res[totalRemaining][a] = len + rev.solve(totalRemaining - a, totalRemaining - a);
                    }
                } else {
                    for (int a = 1; a <= totalRemaining; ++a) {
                        res[totalRemaining][a] = len + worst[a];
                    }
                }
                return res[totalRemaining][inSubtree];
            }

        }

        static class Vertex {
            int startCount;
            int subtreeSum;
            List<TaskE.Edge> edges = new ArrayList<>();

            public void findSubtreeSums(TaskE.Vertex parent) {
                subtreeSum = startCount;
                for (TaskE.Edge e : edges)
                    if (e.dst != parent) {
                        e.dst.findSubtreeSums(this);
                        subtreeSum += e.dst.subtreeSum;
                    }
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.io.IOException;
import java.util.ArrayList;
import java.io.UncheckedIOException;
import java.util.List;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            EPolicemanAndATree solver = new EPolicemanAndATree();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class EPolicemanAndATree {
        Debug debug = new Debug(true);
        int[][] fdp;
        int inf = (int) 1e9;
        int[][] f;
        Node[] nodes;

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            nodes = new Node[n];
            for (int i = 0; i < n; i++) {
                nodes[i] = new Node();
                nodes[i].id = i;
            }

            for (int i = 0; i < n - 1; i++) {
                Node a = nodes[in.readInt() - 1];
                Node b = nodes[in.readInt() - 1];
                Edge e = new Edge();
                e.a = a;
                e.b = b;
                e.w = in.readInt();
                a.next.add(e);
                b.next.add(e);
            }

            Node root = nodes[in.readInt() - 1];

            int m = in.readInt();
            for (int i = 0; i < m; i++) {
                Node node = nodes[in.readInt() - 1];
                node.thief++;
            }
            m -= root.thief;
            root.thief = 0;
            if (m == 0) {
                out.println(0);
                return;
            }

            f = new int[n][m + 1];
            List<Node> leaf = new ArrayList<>(n);
            fdp = new int[n + 1][m + 1];

            for (int i = 1; i <= m; i++) {
                for (int j = 0; j < n; j++) {
                    if (!isLeaf(nodes[j])) {
                        continue;
                    }
                    leaf.clear();
                    dfs(nodes[j], null, 0, leaf);
                    f[j][i] = maxStep(leaf, i, i);
                }
            }

            debug.debug("f", f);
            int ans = inf;
            for (Edge e : root.next) {
                Node node = e.other(root);
                leaf.clear();
                int thief = dfs(node, root, e.w, leaf);
                if (thief == 0) {
                    continue;
                }
                int against = maxStep(leaf, thief, m);
                ans = Math.min(ans, against);
            }

            out.println(ans);
        }

        public int maxStep(List<Node> leaf, int m, int total) {
            SequenceUtils.deepFill(fdp, -inf);
            fdp[0][0] = 0;
            int n = leaf.size();
            for (int i = 1; i <= n; i++) {
                Node node = leaf.get(i - 1);
                for (int j = 0; j <= m; j++) {
                    fdp[i][j] = fdp[i - 1][j];
                    for (int k = 1; k <= j; k++) {
                        if (j - k > 0) {
                            fdp[i][j] = Math.max(fdp[i][j], Math.min(fdp[i - 1][j - k], node.depth + f[node.id][total - k]));
                        } else {
                            fdp[i][j] = Math.max(fdp[i][j], node.depth + f[node.id][total - k]);
                        }
                    }
                }
            }
            return fdp[n][m];
        }

        public boolean isLeaf(Node node) {
            return node.next.size() == 1;
        }

        public int dfs(Node root, Node p, int depth, List<Node> leaf) {
            root.depth = depth;
            boolean isLeaf = true;
            int ans = root.thief;
            for (Edge e : root.next) {
                Node node = e.other(root);
                if (node == p) {
                    continue;
                }
                isLeaf = false;
                ans += dfs(node, root, depth + e.w, leaf);
            }

            if (isLeaf) {
                leaf.add(root);
            }
            return ans;
        }

    }

    static class Debug {
        private boolean offline;
        private PrintStream out = System.err;
        static int[] empty = new int[0];

        public Debug(boolean enable) {
            offline = enable && System.getSecurityManager() == null;
        }

        public Debug debug(String name, Object x) {
            return debug(name, x, empty);
        }

        public Debug debug(String name, Object x, int... indexes) {
            if (offline) {
                if (x == null || !x.getClass().isArray()) {
                    out.append(name);
                    for (int i : indexes) {
                        out.printf("[%d]", i);
                    }
                    out.append("=").append("" + x);
                    out.println();
                } else {
                    indexes = Arrays.copyOf(indexes, indexes.length + 1);
                    if (x instanceof byte[]) {
                        byte[] arr = (byte[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof short[]) {
                        short[] arr = (short[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof boolean[]) {
                        boolean[] arr = (boolean[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof char[]) {
                        char[] arr = (char[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof int[]) {
                        int[] arr = (int[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof float[]) {
                        float[] arr = (float[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof double[]) {
                        double[] arr = (double[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else if (x instanceof long[]) {
                        long[] arr = (long[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    } else {
                        Object[] arr = (Object[]) x;
                        for (int i = 0; i < arr.length; i++) {
                            indexes[indexes.length - 1] = i;
                            debug(name, arr[i], indexes);
                        }
                    }
                }
            }
            return this;
        }

    }

    static class SequenceUtils {
        public static void deepFill(Object array, int val) {
            if (!array.getClass().isArray()) {
                throw new IllegalArgumentException();
            }
            if (array instanceof int[]) {
                int[] intArray = (int[]) array;
                Arrays.fill(intArray, val);
            } else {
                Object[] objArray = (Object[]) array;
                for (Object obj : objArray) {
                    deepFill(obj, val);
                }
            }
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Edge {
        Node a;
        Node b;
        int w;

        Node other(Node x) {
            return a == x ? b : a;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class Node {
        List<Edge> next = new ArrayList<>();
        int id;
        int thief;
        int depth;

        public String toString() {
            return "" + id;
        }

    }
}


import java.io.*;
import java.util.*;

public class Main {
	static Scanner in; static int next() throws Exception {return in.nextInt();}
	static PrintWriter out;
//	static StreamTokenizer in;

	static int h;
	static int m;
	static int k;

	static long count(int hh, int mm) {
		int c = ((m - 1) + "").length();

		if (k > c) {
			int kk = k;
			kk -= c;

			for (int i = 0; i < kk - 1; i++) hh /= 10;
			return hh;
		} else {
			int m0 = m;

			for (int i = 0; i < k - 1; i++) m0 /= 10;
			for (int i = 0; i < k - 1; i++) mm /= 10;

			return (long)m0 * hh + mm;
		}
	}

	public static void main(String[] args) throws Exception {
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);
//		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

		h = next();
		m = next();
		k = next();

		int h1 = next();
		int m1 = next();

		int h2 = next();
		int m2 = next();

//		out.println(count(h2, m2));
//		out.println(count(h1, m1));

		long answ = count(h2, m2) - count(h1, m1);

		if (answ < 0) answ += count(h, 0);

		out.println(answ);

		out.close();
	}
}


import java.io.*;
import java.util.*;

public class Main {
	static Scanner in; static int next() throws Exception {return in.nextInt();}
	static PrintWriter out;
//	static StreamTokenizer in;

	static int h;
	static int m;
	static int k;

	static long count(int hh, int mm) {
		int c = ((m - 1) + "").length();

		if (k > c) {
			int kk = k;
			kk -= c;

			for (int i = 0; i < kk - 1; i++) hh /= 10;
			return hh;
		} else {
			int m0 = m;

			for (int i = 0; i < k - 1; i++) m0 /= 10;
			int m1 = m0;
			for (int i = 0; i < k - 1; i++) m1 *= 10;
			if (m1 < m) m0++;
			for (int i = 0; i < k - 1; i++) mm /= 10;

			return (long)m0 * hh + mm;
		}
	}

	public static void main(String[] args) throws Exception {
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);
//		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

		h = next();
		m = next();
		k = next();

		int h1 = next();
		int m1 = next();

		int h2 = next();
		int m2 = next();

//		out.println(count(h2, m2));
//		out.println(count(h1, m1));

		long answ = count(h2, m2) - count(h1, m1);

		if (answ < 0) answ += count(h - 1, m - 1) + 1;

		out.println(answ);

		out.close();
	}
}


//package prac;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class R86E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
//		for(int h = 0;h <= 1;h++){
//			for(int i = 0;i <= 100;i++){
//				tr(h, i, count(h, 12, i, 101));
//			}
//		}
//		tr(count(2, 12, 0, 60));

		int h = ni(), m = ni(), K = ni();
		int h1 = ni(), m1 = ni();
		int h2 = ni(), m2 = ni();
		if(h1 < h2 || (h1 == h2 && m1 <= m2)){
			out.println(count(h2, h, m2, m)[K] - count(h1, h, m1, m)[K]);
		}else{
//			tr(count(h-1, h, m-1, m));
//			tr(count(h, h, 0, m));
//			tr(count(h1, h, m1, m));
//			tr(count(h2, h, m2, m));
			out.println(count(h, h, 0, m)[K] - count(h1, h, m1, m)[K]
					 + count(h2, h, m2, m)[K]);
		}
	}

	long[] count(int h, int hlim, int m, int mlim)
	{
		long[] ret = new long[24];
		if(h == hlim){
			h--;
			m = mlim-1;
			int eh = 0;
			for(int u = hlim-1;u > 0;u/=10){
				if(u%10 != 0)eh++;
			}
			int ec = 0;
			for(int u = mlim-1;u > 0;u/=10){
				if(u%10 != 0)ec++;
			}
			ret[eh+ec]++;
		}
		long[] hdis = count(h, hlim);
		long[] mdis = count(m, mlim);
		long[] madis = count(mlim-1, mlim);

		int ec = 0;
		for(int u = mlim-1;u > 0;u/=10){
			if(u%10 != 0)ec++;
		}
		for(int i = 0;i < hdis.length;i++){
			ret[i+ec] += hdis[i];
		}
		for(int i = 0;i < mdis.length;i++){
			ret[i] += mdis[i] + madis[i] * h;
		}

		for(int i = ret.length-2;i >= 1;i--){
			ret[i] += ret[i+1];
		}

		return ret;
	}

	// 0->1, ..., m-1->m の分布
	long[] count(int m, int mlim)
	{
		long[] ret = new long[12];
		for(int i = 1, u = Math.min(m, mlim-1);i <= 10;i++, u/=10){
			ret[i] = u;
		}
		for(int i = 1;i <= 9;i++){
			ret[i] -= ret[i+1];
		}

		if(m == mlim){
			int ec = 0;
			for(int u = m;u > 0;u/=10){
				if(u%10 != 0)ec++;
			}
			ret[ec]++;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new R86E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;

public class Main {
	static Scanner in; static int next() throws Exception {return in.nextInt();}
	static PrintWriter out;
//	static StreamTokenizer in;

	static int h;
	static int m;
	static int k;

	static long count(int hh, int mm) {

		long answ = 0;

		String s = ((m - 1) + "");
		int cnt = 0;
		for (char cc : s.toCharArray()) if (cc != '0') cnt++;

        if (k <= cnt) {
        	answ += hh;
        } else {
        	int h0 = hh;
        	int kk = k - cnt;
        	for (int i = 0; i < kk - 1; i++) h0 /= 10;
        	answ += h0;
        }

		int c = ((m - 1) + "").length();

		if (k <= c) {
			int m0 = m - 1;

			for (int i = 0; i < k - 1; i++) m0 /= 10;

			for (int i = 0; i < k - 1; i++) mm /= 10;

			answ += (long) m0 * hh + mm;
		}

		return answ;
	}

	public static void main(String[] args) throws Exception {
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);
//		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

		h = next();
		m = next();
		k = next();

		int h1 = next();
		int m1 = next();

		int h2 = next();
		int m2 = next();

//		out.println(count(h2, m2));
//		out.println(count(h1, m1));

		long answ = count(h2, m2) - count(h1, m1);

		if (h2 < h1 || (h2 == h1 && m2 < m1)) {
			answ += count(h - 1, m - 1);
			String s = (h - 1) + "" + (m - 1);
			int cnt = 0;
			for (char cc : s.toCharArray()) if (cc != '0') cnt++;
			if (cnt >= k) answ++;
		}

		out.println(answ);

		out.close();
	}
}


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.io.*;

public class UpTheStrip {

	private static class MyScanner {
	    BufferedReader br;
	    StringTokenizer st;

	    public MyScanner() {
	       br = new BufferedReader(new InputStreamReader(System.in));
	    }

	    String next() {
	        while (st == null || !st.hasMoreElements()) {
	            try {
	                st = new StringTokenizer(br.readLine());
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        return st.nextToken();
	    }

	    int nextInt() {
	        return Integer.parseInt(next());
	    }

	    long nextLong() {
	        return Long.parseLong(next());
	    }

	    double nextDouble() {
	        return Double.parseDouble(next());
	    }

	    String nextLine(){
	        String str = "";
		  try {
		     str = br.readLine();
		  } catch (IOException e) {
		     e.printStackTrace();
		  }
		  return str;
	    }

	 }

	public static long solution(long n, long m) {

		long[] dp  = new long[(int)n];
		long[] sum  = new long[(int)n];
		dp[0] = 1;
		sum[0] = 0;
		long prev = 1;

		for(int i = 2; i<=n; i++) {

			dp[i-1] = prev;

			sum[i-1] = (sum[i-1] + sum[i-2])%m;
			sum[i-1] = (sum[i-1] + dp[0])%m;
			dp[i-1] = (dp[i-1] + sum[i-1])%m;

			prev = (prev + dp[i-1])%m;

            int j = i+i;

			while(j<=n)
			{
				sum[j-1] = (sum[j-1] + dp[i-1])%m;
				sum[j-1] = (sum[j-1] - dp[i-2] + m)%m;
				j+=i;
			}
		}

		return dp[(int)n-1];

	}

private static PrintWriter out = new PrintWriter(System.out);

public static void main (String[] args)
{
	MyScanner s =  new MyScanner();

    long n = s.nextLong();
    long m = s.nextLong();
    out.println(solutionn(n,m));

    out.flush();
    out.close();

}
}


import java.io.*;
import java.lang.*;
import java.util.*;

public class Main {
    public static MyScanner sc = new MyScanner(System.in);
    public static PrintWriter out = new PrintWriter(System.out);
    public static void main(String[] args) {
        var n = sc.nextint();
        int mod = sc.nextint();
        long[] dp1 = new long[n + 9];
        long[] dp2 = new long[n + 9];
        dp2[1] = 1;
        for(int i = 1; i <= n; i++){
            dp1[i] += dp1[i - 1];
            dp1[i] %= mod;
            dp2[i] = dp1[i];
            if(i == 1){
                dp2[i] = 1;
            }
            dp1[i + 1] += dp2[i];
            dp1[i + 1] %= mod;
            for(int j = 2; i * j <= n; j++){
                dp1[i * j] += dp2[i];
                dp1[i * j] %= mod;
                if((i + 1) * j <= n) {
                    dp1[(i + 1) * j] += mod - dp2[i];
                    dp1[(i + 1) * j] %= mod;
                }
            }
        }
        out.print(dp2[n]);
        out.close();
    }
}
class MyScanner {
    private BufferedReader br;
    private StringTokenizer tokenizer;

    public MyScanner(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextint() {
        return Integer.parseInt(next());
    }
    public long nextlong() {
        return Long.parseLong(next());
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Collections;
import java.util.ArrayList;
import java.util.TreeSet;

public class C {
	static int mod;
	static ArrayList<Integer> answers = new ArrayList<>();
	public static void main(String[] args) {
		FastScanner fs = new FastScanner();
		int n = fs.nextInt();
		mod = fs.nextInt();
		int[] dp = new int[n+1];
		int[] cs = new int[n+2];
		dp[n] = 1;
		cs[n] = 1;
		for(int fill = n - 1; fill >= 0 ; fill--) {
			int ans = 0;
			ans = sub(cs[fill] , cs[n+1]);

			//for(int i = fill+1 ; i <= n; i++) ans = add(ans, dp[i]);
			for(int mul = 2; true ; mul++) {
				int lower = mul * fill;
				int higher = mul * fill + mul - 1;
				if(lower > n) break;
				higher = Math.min(higher , n);
				//for(int i = lower ; i <= higher ; i++) ans = add(ans, dp[i]);
				ans = add(ans, sub(cs[lower] - cs[higher + 1]));
			}
			dp[fill] = ans;
			cs[fill] = add(cs[fill+1] , dp[fill]);

		}
		System.out.println(dp[1]);
}

	static int add(int a, int b) {
		a+=b;
		if(a >= mod) return a - mod;
		return a;
	}

	static int sub(int a , int b) {
		a -= b;
		if(a < 0) a += mod;
		else if(a >= mod) a -= mod;
		return a;

	}

	static int indof(int x , int[] a) {
		for(int i = 0; i < a.length; i++) if(a[i] == x) return i;
			throw null;
	}

	static void swap(int prefixSize , int[] a) {
		prefixSize++;
		if(prefixSize%2 != 1) throw null;
		int[] newA = a.clone();
		for(int i = 0; i < prefixSize; i++) {
			a[i] = newA[prefixSize - 1 - i];
		}
		answers.add(prefixSize);
	}

	static void sort(int[] a) {
		ArrayList<Integer> l = new ArrayList<>();
		for(int i : a) l.add(i);
		Collections.sort(l);
		for(int i = 0; i < a.length; i++) a[i] = l.get(i);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		public String next() {
			while (!st.hasMoreElements())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
	}
}


import java.io.*;
import java.util.*;

public class Main {
    static Random random;

    /* public static void main(String[] args){
        new Thread(null, new Template (), "Main", 1<<26).start();
    } */

    public static void main(String[] args) {
        FastScanner in = new FastScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        random = new Random();

        // long timeStamp = System.currentTimeMillis();
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
        // System.err.println("TIME: "+(System.currentTimeMillis()-timeStamp)+" ms");
    }

    /* ------------------------------------- START -------------------------------------------- */
    static class Solver {
        private static int mod;
        public void solve(FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            mod = in.nextInt();

            int dp[] = new int[n+1];
            int pref[] = new int[n+1];

            dp[1] = 1;
            pref[1] = 1;

            for(int i = 2; i<=n; i++){
                dp[i] = pref[i-1];

                int q = 1;
                while(q < i){
                    int l = i/(q+1) + 1;
                    int r = i/q;
                    // new Debug().d("q", q).d("l", l).d("r", r).d();
                    dp[i] = add(dp[i], mult(r-l+1, dp[q]));
                    //if(l == 1) break;
                    q = i/(l-1);
                }

                // new Debug().d(i, dp[i]).d();

                pref[i] = add(pref[i-1], dp[i]);
            }

            out.println(dp[n]);
        }

        private int add(int x, int y){
            x += y;
            if(x >= mod) x -= mod;
            return x;
        }

        private int mult(int x, int y){
            long r = (x * (long) y);
            if(r >= mod)
                r %= mod;
            return (int) r;
        }
    }
    /* -------------------------------------- END --------------------------------------------- */

    /* Shuffle function to shuffle before Arrays.sort */
    static void shuffle(int[] arr){
        int swapTemp;
        for(int i = arr.length-1; i>= 1; i--){
            int pos = random.nextInt(i+1);
            if(pos == i) continue;
            {swapTemp = arr[i]; arr[i] = arr[pos]; arr[pos] = swapTemp;}
        }
    }

    /* Fast Input reader */
    static class FastScanner {
        BufferedReader reader;
        StreamTokenizer tokenizer;
        public FastScanner() {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = new StreamTokenizer(reader);
            tokenizer.resetSyntax();
            tokenizer.whitespaceChars(0, 32);
            tokenizer.wordChars(33, 126);
        }
        private void nextToken(){
            try{ tokenizer.nextToken(); }
            catch (Exception e) { e.printStackTrace(); }
        }
        String next() {
            nextToken();
            return tokenizer.sval;
        }
        int nextInt() {
            nextToken();
            return Integer.parseInt(tokenizer.sval);
        }
        long nextLong() {
            nextToken();
            return Long.parseLong(tokenizer.sval);
        }
        double nextDouble() {
            nextToken();
            return Double.parseDouble(tokenizer.sval);
        }
        String nextLine() {
            try{
                String string = reader.readLine();
                return string;
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        }
    }
}


import java.io.*;
import java.util.*;

public class cf275E {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	List<Integer>[] g;
	long outp;

	void dbg(Node[] a) {
		for (Node v : a) {
			System.err.println(v.val + (v.l == null ? "" : ": l = " + v.l.val)
					+ (v.r == null ? "" : ": r = " + v.r.val)
					+ (!v.isRoot() || v.up == null ? "" : ": up = " + v.up.val)
					+ ", here = " + v.lcaHere + ", delta = " + v.delta + ", sizeOther = " + v.sizeNotLC);
		}
		System.err.println();
	}

	void solve() throws IOException {
		int n = nextInt();

		g = new List[n];
		for (int i = 0; i < n; i++) {
			g[i] = new ArrayList<>();
		}

		int[] par = new int[n];

		for (int i = 1; i < n; i++) {
			par[i] = nextInt() - 1;
		}

		int[] vals = new int[n];

		Node[] a = new Node[n];

		outp = 0;

		for (int i = 0; i < n; i++) {
			vals[i] = nextInt();
			a[i] = new Node(vals[i]);
			outp += vals[i];
		}

		for (int i = 1; i < n; i++) {
			Node v = a[par[i]];
			Node u = a[i];
			link(v, u);
		}
		out.println(1.0 * outp / n / n);

//		dbg(a);

		int q = nextInt();
		while (q-- > 0) {
			char type = nextToken().charAt(0);
			int vId = nextInt() - 1;
			Node v = a[vId];
			if (type == 'P') {
				int uId = nextInt() - 1;
				Node u = a[uId];
				LinkCut.expose(u);
				LinkCut.splay(v);
				if (v.up == null) { // v is above u
					makeParent(v, u);
				} else {
					makeParent(u, v);
				}
			} else {
				int newVal = nextInt();
				LinkCut.splay(v);
				outp += (newVal - v.val)
						* (v.lcaHere + 2L * v.delta * v.sizeNotLC);
				v.val = newVal;
				v.update();
			}
			out.println(1.0 * outp / n / n);
//			dbg(a);
		}
	}

	void makeParent(Node v, Node u) { // make v parent of u
		LinkCut.expose(u);
		LinkCut.splay(u);

		Node t = u.l;
		if (t == null) {
			throw new AssertionError();
		}

		u.l = null;
		t.up = null;
		u.update();
		outp -= 2L * t.sum * u.size;
		t.applyDelta(-u.size);

		link(v, u);
	}

	void link(Node v, Node u) {
		LinkCut.expose(v);
		LinkCut.splay(v);
		LinkCut.splay(u); // is root, so no need to expose

		outp += 2 * v.sum * u.size;
		v.applyDelta(u.size);
		v.sizeNotLC += u.size;
		u.up = v;
		v.update();
	}

	static class Node {
		Node l, r, up;
		int val, size, sizeNotLC;
		long sum, lcaHere; // lcaHere without delta

		int delta;

		void update() {
			sum = getSum(l) + getSum(r) + 1L * sizeNotLC * val;
			size = getSize(l) + getSize(r) + sizeNotLC;
		}

		void push() {
			if (l != null) {
				l.applyDelta(delta);
			}
			if (r != null) {
				r.applyDelta(delta);
			}
			delta = 0;
		}

		void applyDelta(int delta) {
			lcaHere += 2L * delta * sizeNotLC;
			this.delta += delta;
		}

		static long getSum(Node v) {
			return v == null ? 0 : v.sum;
		}

		static int getSize(Node v) {
			return v == null ? 0 : v.size;
		}

		boolean isRoot() {
			return up == null || (up.l != this && up.r != this);
		}

		public Node(int val) {
			this.val = val;
			sizeNotLC = 1;
			lcaHere = 1;

			update();
		}

		static private void relink(Node v, Node u) {
			Node t = u.up;
			if (v != null) {
				v.up = t;
			}
			if (t != null) {
				if (t.l == u) {
					t.l = v;
				} else if (t.r == u) {
					t.r = v;
				}
			}
		}

		private void rotate() {
			Node u = up;

			if (u.l == this) {
				relink(r, this);
				r = u;
			} else {
				relink(l, this);
				l = u;
			}

			relink(this, u);
			u.up = this;
			u.update();
		}

	}

	static class LinkCut {

		public static void splay(Node v) {
			if (v.isRoot()) {
				v.push();
				return;
			}
			do {
				Node u = v.up;
				Node t = u.up;
				boolean uRoot = u.isRoot();
				if (!uRoot) {
					t.push();
				}
				u.push();
				v.push();
				if (!uRoot) {
					((t.l == u) == (u.l == v) ? u : v).rotate();
				}
				v.rotate();
			} while (!v.isRoot());
			v.update();
		}

		public static void expose(Node v) {
			// TODO: return rest? might help to find lca and whatnot, see
			// http://codeforces.com/contest/482/submission/8750934
			for (Node rest = null; v != null; rest = v, v = v.up) {
				splay(v);
				if (v.r != null) {
					v.sizeNotLC += v.r.size;
				}
				if (rest != null) {
					v.sizeNotLC -= rest.size;
				}
				v.r = rest;
				v.update();
			}
		}

	}

	cf275E() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	public static void main(String[] args) throws IOException {
		new cf275E();
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
}

/*

5
1 2 2 1
1 2 3 4 5
4
P 3 4
P 4 5
P 5 2
P 1 4
 */


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Locale;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

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

class TaskE {
    static class Query {
        int kind;
        Vertex v;
        Vertex u;
        int t;
    }

    static class Vertex {
        long s;
        long subtreeSize;
        boolean hasInterestingInSubtree = false;
        long subtreeAnswer;
        long childSquareSum;
        Vertex parent;
        Vertex firstChild;
        Vertex nextSibling;
        Vertex interestingParent;
        Vertex firstInterestingChild;
        Vertex nextInterestingSibling;
        long multiplierForIntermediates;
        long constantForIntermediates;
        long intermediatesSize;
        long boringChildrenSize;
        long boringChildrenSquareSum;
        long boringChildrenAnswer;
        boolean interesting;

        void propagateInteresting() {
            Vertex v = firstChild;
            int numIntChild = 0;
            while (v != null) {
                v.propagateInteresting();
                if (v.hasInterestingInSubtree) ++numIntChild;
                v = v.nextSibling;
            }
            if (numIntChild >= 2) interesting = true;
            if (interesting || numIntChild >= 1) hasInterestingInSubtree = true;
        }

        void init() {
            subtreeSize = 1;
            subtreeAnswer = 0;
            childSquareSum = 0;
            boringChildrenSize = 0;
            boringChildrenAnswer = 0;
            boringChildrenSquareSum = 0;
            Vertex v = firstChild;
            while (v != null) {
                v.init();
                subtreeSize += v.subtreeSize;
                subtreeAnswer += v.subtreeAnswer;
                childSquareSum += v.subtreeSize * (long) v.subtreeSize;
                if (interesting && !v.hasInterestingInSubtree) {
                    boringChildrenSize += v.subtreeSize;
                    boringChildrenAnswer += v.subtreeAnswer;
                    boringChildrenSquareSum += v.subtreeSize * (long) v.subtreeSize;
                }
                v = v.nextSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void interestingInit() {
            subtreeSize = 1 + boringChildrenSize;
            subtreeAnswer = boringChildrenAnswer;
            childSquareSum = boringChildrenSquareSum;
            Vertex v = firstInterestingChild;
            while (v != null) {
                v.interestingInit();
                long childSize = v.subtreeSize + v.intermediatesSize;
                subtreeSize += childSize;
                subtreeAnswer += v.subtreeAnswer;
                subtreeAnswer += v.multiplierForIntermediates * v.subtreeSize + v.constantForIntermediates;
                childSquareSum += childSize * (long) childSize;
                v = v.nextInterestingSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void initIntermediates() {
            Vertex tmp = this;
            intermediatesSize = 0;
            multiplierForIntermediates = 0;
            constantForIntermediates = 0;
            while (!tmp.parent.interesting) {
                long curExtra = tmp.parent.subtreeSize - tmp.subtreeSize;
                intermediatesSize += curExtra;
                multiplierForIntermediates += 2 * curExtra * (long) tmp.parent.s;
                constantForIntermediates += tmp.parent.subtreeAnswer - tmp.subtreeAnswer - 2 * subtreeSize * (long) (tmp.parent.subtreeSize - tmp.subtreeSize) * tmp.parent.s;
                tmp = tmp.parent;
            }
            interestingParent = tmp.parent;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        /*char[] buf = new char[100000];
        int size;
        try {
            size = in.reader.read(buf);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (size == buf.length) throw new RuntimeException();
        String input = new String(buf, 0, size);
        StringWriter sw1 = new StringWriter();
        PrintWriter pw1 = new PrintWriter(sw1);
        doit(new InputReader(new StringInputStream(input)), pw1, 1);
        pw1.close();
        StringWriter sw2 = new StringWriter();
        PrintWriter pw2 = new PrintWriter(sw2);
        doit(new InputReader(new StringInputStream(input)), pw2, 500);
        pw2.close();
        String s1 = sw1.toString();
        String s2 = sw2.toString();
        if (!s1.equals(s2)) throw new RuntimeException();
        out.print(s1);*/
        doit(in, out, 250);
    }

    private void doit(InputReader in, PrintWriter out, int BUBEN) {
        Locale.setDefault(Locale.US);
        int n = in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; ++i) vs[i] = new Vertex();
        for (int i = 1; i < n; ++i) {
            vs[i].parent = vs[in.nextInt() - 1];
        }
        for (int i = 0; i < n; ++i) {
            vs[i].s = in.nextInt();
        }
        Vertex root = vs[0];
        int numQueries = in.nextInt();
        Query[] queries = new Query[numQueries];
        for (int i = 0; i < numQueries; ++i) {
            Query query = new Query();
            String ss = in.next();
            if (ss.equals("P")) query.kind = 1; else if (ss.equals("V")) query.kind = 2; else throw new RuntimeException();
            if (query.kind == 1) {
                query.v = vs[in.nextInt() - 1];
                query.u = vs[in.nextInt() - 1];
            } else {
                query.v = vs[in.nextInt() - 1];
                query.t = in.nextInt();
            }
            queries[i] = query;
        }
        double mult = 1.0 / n / n;
        Vertex[] inters = new Vertex[n];
        for (int blockFirst = 0; blockFirst < numQueries; blockFirst += BUBEN) {
            int blockLast = Math.min(numQueries, blockFirst + BUBEN);
            for (Vertex vv : vs) {
                vv.interesting = false;
                vv.hasInterestingInSubtree = false;
            }
            root.interesting = true;
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    query.v.interesting = true;
                    if (query.v.parent != null) query.v.parent.interesting = true;
                    query.u.interesting = true;
                    if (query.u.parent != null) query.u.parent.interesting = true;
                } else {
                    query.v.interesting = true;
                }
            }
            for (Vertex vv : vs) {
                vv.firstChild = null;
                vv.nextSibling = null;
            }
            for (Vertex vv : vs) {
                if (vv.parent != null) {
                    vv.nextSibling = vv.parent.firstChild;
                    vv.parent.firstChild = vv;
                }
            }
            root.propagateInteresting();
            int ninters = 0;
            for (Vertex vv : vs) if (vv.interesting) {
                inters[ninters++] = vv;
            }
            root.init();
            for (int i = 0; i < ninters; ++i) {
                Vertex vv = inters[i];
                if (vv.parent != null) vv.initIntermediates();
            }
            if (blockFirst == 0) {
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    Vertex tmp = query.u;
                    while (tmp != null && tmp != query.v) tmp = tmp.interestingParent;
                    if (tmp == null) {
                        query.v.parent = query.u;
                        query.v.interestingParent = query.u;
                    } else {
                        query.u.parent = query.v;
                        query.u.interestingParent = query.v;
                    }
                } else {
                    query.v.s = query.t;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    vv.firstInterestingChild = null;
                    vv.nextInterestingSibling = null;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    if (vv.interestingParent != null) {
                        vv.nextInterestingSibling = vv.interestingParent.firstInterestingChild;
                        vv.interestingParent.firstInterestingChild = vv;
                    }
                }
                root.interestingInit();
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

}


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Locale;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

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

class TaskE {
    static class Query {
        int kind;
        Vertex v;
        Vertex u;
        int t;
    }

    static class Vertex {
        long s;
        long subtreeSize;
        boolean hasInterestingInSubtree = false;
        long subtreeAnswer;
        long childSquareSum;
        Vertex parent;
        Vertex firstChild;
        Vertex nextSibling;
        Vertex interestingParent;
        Vertex firstInterestingChild;
        Vertex nextInterestingSibling;
        long multiplierForIntermediates;
        long constantForIntermediates;
        long intermediatesSize;
        long boringChildrenSize;
        long boringChildrenSquareSum;
        long boringChildrenAnswer;
        boolean interesting;

        void propagateInteresting() {
            Vertex v = firstChild;
            int numIntChild = 0;
            while (v != null) {
                v.propagateInteresting();
                if (v.hasInterestingInSubtree) ++numIntChild;
                v = v.nextSibling;
            }
            if (numIntChild >= 2) interesting = true;
            if (interesting || numIntChild >= 1) hasInterestingInSubtree = true;
        }

        void init() {
            subtreeSize = 1;
            subtreeAnswer = 0;
            childSquareSum = 0;
            boringChildrenSize = 0;
            boringChildrenAnswer = 0;
            boringChildrenSquareSum = 0;
            Vertex v = firstChild;
            while (v != null) {
                v.init();
                subtreeSize += v.subtreeSize;
                subtreeAnswer += v.subtreeAnswer;
                childSquareSum += v.subtreeSize * (long) v.subtreeSize;
                if (interesting && !v.hasInterestingInSubtree) {
                    boringChildrenSize += v.subtreeSize;
                    boringChildrenAnswer += v.subtreeAnswer;
                    boringChildrenSquareSum += v.subtreeSize * (long) v.subtreeSize;
                }
                v = v.nextSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void interestingInit() {
            subtreeSize = 1 + boringChildrenSize;
            subtreeAnswer = boringChildrenAnswer;
            childSquareSum = boringChildrenSquareSum;
            Vertex v = firstInterestingChild;
            while (v != null) {
                v.interestingInit();
                long childSize = v.subtreeSize + v.intermediatesSize;
                subtreeSize += childSize;
                subtreeAnswer += v.subtreeAnswer;
                subtreeAnswer += v.multiplierForIntermediates * v.subtreeSize + v.constantForIntermediates;
                childSquareSum += childSize * (long) childSize;
                v = v.nextInterestingSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void initIntermediates() {
            Vertex tmp = this;
            intermediatesSize = 0;
            multiplierForIntermediates = 0;
            constantForIntermediates = 0;
            while (!tmp.parent.interesting) {
                long curExtra = tmp.parent.subtreeSize - tmp.subtreeSize;
                intermediatesSize += curExtra;
                multiplierForIntermediates += 2 * curExtra * (long) tmp.parent.s;
                constantForIntermediates += tmp.parent.subtreeAnswer - tmp.subtreeAnswer - 2 * subtreeSize * (long) (tmp.parent.subtreeSize - tmp.subtreeSize) * tmp.parent.s;
                tmp = tmp.parent;
            }
            interestingParent = tmp.parent;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        /*char[] buf = new char[100000];
        int size;
        try {
            size = in.reader.read(buf);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (size == buf.length) throw new RuntimeException();
        String input = new String(buf, 0, size);
        StringWriter sw1 = new StringWriter();
        PrintWriter pw1 = new PrintWriter(sw1);
        doit(new InputReader(new StringInputStream(input)), pw1, 1);
        pw1.close();
        StringWriter sw2 = new StringWriter();
        PrintWriter pw2 = new PrintWriter(sw2);
        doit(new InputReader(new StringInputStream(input)), pw2, 500);
        pw2.close();
        String s1 = sw1.toString();
        String s2 = sw2.toString();
        if (!s1.equals(s2)) throw new RuntimeException();
        out.print(s1);*/
        doit(in, out, 200);
    }

    private void doit(InputReader in, PrintWriter out, int BUBEN) {
        Locale.setDefault(Locale.US);
        int n = in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; ++i) vs[i] = new Vertex();
        for (int i = 1; i < n; ++i) {
            vs[i].parent = vs[in.nextInt() - 1];
        }
        for (int i = 0; i < n; ++i) {
            vs[i].s = in.nextInt();
        }
        Vertex root = vs[0];
        int numQueries = in.nextInt();
        Query[] queries = new Query[numQueries];
        for (int i = 0; i < numQueries; ++i) {
            Query query = new Query();
            String ss = in.next();
            if (ss.equals("P")) query.kind = 1; else if (ss.equals("V")) query.kind = 2; else throw new RuntimeException();
            if (query.kind == 1) {
                query.v = vs[in.nextInt() - 1];
                query.u = vs[in.nextInt() - 1];
            } else {
                query.v = vs[in.nextInt() - 1];
                query.t = in.nextInt();
            }
            queries[i] = query;
        }
        double mult = 1.0 / n / n;
        Vertex[] inters = new Vertex[n];
        for (int blockFirst = 0; blockFirst < numQueries; blockFirst += BUBEN) {
            int blockLast = Math.min(numQueries, blockFirst + BUBEN);
            for (Vertex vv : vs) {
                vv.interesting = false;
                vv.hasInterestingInSubtree = false;
            }
            root.interesting = true;
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    query.v.interesting = true;
                    if (query.v.parent != null) query.v.parent.interesting = true;
                    query.u.interesting = true;
                    if (query.u.parent != null) query.u.parent.interesting = true;
                } else {
                    query.v.interesting = true;
                }
            }
            for (Vertex vv : vs) {
                vv.firstChild = null;
                vv.nextSibling = null;
            }
            for (Vertex vv : vs) {
                if (vv.parent != null) {
                    vv.nextSibling = vv.parent.firstChild;
                    vv.parent.firstChild = vv;
                }
            }
            root.propagateInteresting();
            int ninters = 0;
            for (Vertex vv : vs) if (vv.interesting) {
                inters[ninters++] = vv;
            }
            root.init();
            for (int i = 0; i < ninters; ++i) {
                Vertex vv = inters[i];
                if (vv.parent != null) vv.initIntermediates();
            }
            if (blockFirst == 0) {
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    Vertex tmp = query.u;
                    while (tmp != null && tmp != query.v) tmp = tmp.interestingParent;
                    if (tmp == null) {
                        query.v.parent = query.u;
                        query.v.interestingParent = query.u;
                    } else {
                        query.u.parent = query.v;
                        query.u.interestingParent = query.v;
                    }
                } else {
                    query.v.s = query.t;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    vv.firstInterestingChild = null;
                    vv.nextInterestingSibling = null;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    if (vv.interestingParent != null) {
                        vv.nextInterestingSibling = vv.interestingParent.firstInterestingChild;
                        vv.interestingParent.firstInterestingChild = vv;
                    }
                }
                root.interestingInit();
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

}


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Locale;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

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

class TaskE {
    static class Query {
        int kind;
        Vertex v;
        Vertex u;
        int t;
    }

    static class Vertex {
        long s;
        long subtreeSize;
        boolean hasInterestingInSubtree = false;
        long subtreeAnswer;
        long childSquareSum;
        Vertex parent;
        Vertex firstChild;
        Vertex nextSibling;
        Vertex interestingParent;
        Vertex firstInterestingChild;
        Vertex nextInterestingSibling;
        long multiplierForIntermediates;
        long constantForIntermediates;
        long intermediatesSize;
        long boringChildrenSize;
        long boringChildrenSquareSum;
        long boringChildrenAnswer;
        boolean interesting;

        void propagateInteresting() {
            Vertex v = firstChild;
            int numIntChild = 0;
            while (v != null) {
                v.propagateInteresting();
                if (v.hasInterestingInSubtree) ++numIntChild;
                v = v.nextSibling;
            }
            if (numIntChild >= 2) interesting = true;
            if (interesting || numIntChild >= 1) hasInterestingInSubtree = true;
        }

        void init() {
            subtreeSize = 1;
            subtreeAnswer = 0;
            childSquareSum = 0;
            boringChildrenSize = 0;
            boringChildrenAnswer = 0;
            boringChildrenSquareSum = 0;
            Vertex v = firstChild;
            while (v != null) {
                v.init();
                subtreeSize += v.subtreeSize;
                subtreeAnswer += v.subtreeAnswer;
                childSquareSum += v.subtreeSize * (long) v.subtreeSize;
                if (interesting && !v.hasInterestingInSubtree) {
                    boringChildrenSize += v.subtreeSize;
                    boringChildrenAnswer += v.subtreeAnswer;
                    boringChildrenSquareSum += v.subtreeSize * (long) v.subtreeSize;
                }
                v = v.nextSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void interestingInit() {
            subtreeSize = 1 + boringChildrenSize;
            subtreeAnswer = boringChildrenAnswer;
            childSquareSum = boringChildrenSquareSum;
            Vertex v = firstInterestingChild;
            while (v != null) {
                v.interestingInit();
                long childSize = v.subtreeSize + v.intermediatesSize;
                subtreeSize += childSize;
                subtreeAnswer += v.subtreeAnswer;
                subtreeAnswer += v.multiplierForIntermediates * v.subtreeSize + v.constantForIntermediates;
                childSquareSum += childSize * (long) childSize;
                v = v.nextInterestingSibling;
            }
            subtreeAnswer += (subtreeSize * (long) subtreeSize - childSquareSum) * s;
        }

        public void initIntermediates() {
            Vertex tmp = this;
            intermediatesSize = 0;
            multiplierForIntermediates = 0;
            constantForIntermediates = 0;
            while (!tmp.parent.interesting) {
                long curExtra = tmp.parent.subtreeSize - tmp.subtreeSize;
                intermediatesSize += curExtra;
                multiplierForIntermediates += 2 * curExtra * (long) tmp.parent.s;
                constantForIntermediates += tmp.parent.subtreeAnswer - tmp.subtreeAnswer - 2 * tmp.subtreeSize * (long) (tmp.parent.subtreeSize - tmp.subtreeSize) * tmp.parent.s;
                tmp = tmp.parent;
            }
            interestingParent = tmp.parent;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        doit(in, out, 500);
    }

    private void doit(InputReader in, PrintWriter out, int BUBEN) {
        Locale.setDefault(Locale.US);
        int n = in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; ++i) vs[i] = new Vertex();
        for (int i = 1; i < n; ++i) {
            vs[i].parent = vs[in.nextInt() - 1];
        }
        for (int i = 0; i < n; ++i) {
            vs[i].s = in.nextInt();
        }
        Vertex root = vs[0];
        int numQueries = in.nextInt();
        Query[] queries = new Query[numQueries];
        for (int i = 0; i < numQueries; ++i) {
            Query query = new Query();
            String ss = in.next();
            if (ss.equals("P")) query.kind = 1; else if (ss.equals("V")) query.kind = 2; else throw new RuntimeException();
            if (query.kind == 1) {
                query.v = vs[in.nextInt() - 1];
                query.u = vs[in.nextInt() - 1];
            } else {
                query.v = vs[in.nextInt() - 1];
                query.t = in.nextInt();
            }
            queries[i] = query;
        }
        double mult = 1.0 / n / n;
        Vertex[] inters = new Vertex[n];
        for (int blockFirst = 0; blockFirst < numQueries; blockFirst += BUBEN) {
            int blockLast = Math.min(numQueries, blockFirst + BUBEN);
            for (Vertex vv : vs) {
                vv.interesting = false;
                vv.hasInterestingInSubtree = false;
            }
            root.interesting = true;
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    query.v.interesting = true;
                    if (query.v.parent != null) query.v.parent.interesting = true;
                    query.u.interesting = true;
                    if (query.u.parent != null) query.u.parent.interesting = true;
                } else {
                    query.v.interesting = true;
                }
            }
            for (Vertex vv : vs) {
                vv.firstChild = null;
                vv.nextSibling = null;
            }
            for (Vertex vv : vs) {
                if (vv.parent != null) {
                    vv.nextSibling = vv.parent.firstChild;
                    vv.parent.firstChild = vv;
                }
            }
            root.propagateInteresting();
            int ninters = 0;
            for (Vertex vv : vs) if (vv.interesting) {
                inters[ninters++] = vv;
            }
            root.init();
            for (int i = 0; i < ninters; ++i) {
                Vertex vv = inters[i];
                if (vv.parent != null) vv.initIntermediates();
            }
            if (blockFirst == 0) {
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
            for (int qid = blockFirst; qid < blockLast; ++qid) {
                Query query = queries[qid];
                if (query.kind == 1) {
                    Vertex tmp = query.u;
                    while (tmp != null && tmp != query.v) tmp = tmp.interestingParent;
                    if (tmp == null) {
                        query.v.parent = query.u;
                        query.v.interestingParent = query.u;
                    } else {
                        query.u.parent = query.v;
                        query.u.interestingParent = query.v;
                    }
                } else {
                    query.v.s = query.t;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    vv.firstInterestingChild = null;
                    vv.nextInterestingSibling = null;
                }
                for (int i = 0; i < ninters; ++i) {
                    Vertex vv = inters[i];
                    if (vv.interestingParent != null) {
                        vv.nextInterestingSibling = vv.interestingParent.firstInterestingChild;
                        vv.interestingParent.firstInterestingChild = vv;
                    }
                }
                root.interestingInit();
                out.println(String.format("%.12f", root.subtreeAnswer * mult));
            }
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

}