You are given an unweighted tree with n vertices. Then n - 1 following operations are applied to the tree. A single operation consists of the following steps:   choose two leaves;  add the length of the simple path between them to the answer;  remove one of the chosen leaves from the tree. Initial answer (before applying operations) is 0. Obviously after n - 1 such operations the tree will consist of a single vertex. Calculate the maximal possible answer you can achieve, and construct a sequence of operations that allows you to achieve this answer!

The first line contains one integer number n (2 ≤ n ≤ 2·105) — the number of vertices in the tree.  Next n - 1 lines describe the edges of the tree in form ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi). It is guaranteed that given graph is a tree.

In the first line print one integer number — maximal possible answer.  In the next n - 1 lines print the operations in order of their applying in format ai, bi, ci, where ai, bi — pair of the leaves that are chosen in the current operation (1 ≤ ai, bi ≤ n), ci (1 ≤ ci ≤ n, ci = ai or ci = bi) — choosen leaf that is removed from the tree in the current operation.  See the examples for better understanding.

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop;

void main() {
    auto N = readln.chomp.to!int;
    auto G = new int[][](N);

    foreach (_; 0..N-1) {
        auto s = readln.split.map!(to!int);
        G[s[0]-1] ~= s[1]-1;
        G[s[1]-1] ~= s[0]-1;
    }

    auto depth1 = new int[](N);
    auto depth2 = new int[](N);
    int[] route;

    void dfs1(int n, int p, int d, int[] dd) {
        dd[n] = d;
        foreach (m; G[n]) {
            if (m != p) dfs1(m, n, d+1, dd);
        }
    }

    bool dfs2(int n, int p, int dest) {
        if (n == dest) {
            route ~= n;
            return true;
        }

        foreach (m; G[n]) {
            if (m != p && dfs2(m, n, dest)) {
                route ~= n;
                return true;
            }
        }

        return false;
    }

    void dfs3(int n, int p) {

    }

    dfs1(0, -1, 0, depth1);
    int a = depth1.enumerate.maxElement!"a.value"[0].to!int;
    dfs1(a, -1, 0, depth1);
    int b = depth1.enumerate.maxElement!"a.value"[0].to!int;
    dfs1(b, -1, 0, depth2);
    dfs2(a, -1, b);

    long maxd = depth1.maxElement.to!long;
    long ans = maxd * (maxd + 1) / 2;
    Tuple!(int, int, int)[] anst;
    auto dist1 = new int[](N);
    auto dist2 = new int[](N);
    auto used = new bool[](N);
    foreach (i, n; route.enumerate) {
        used[n] = true;
        if (n != route.front) anst ~= tuple(n+1, route.front+1, n+1);
    }

    auto pq = new BinaryHeap!(Array!(Tuple!(int, int)), "a[1] < b[1]");
    foreach (n; route) {
        foreach (m; G[n]) {
            if (used[m]) continue;
            pq.insert(tuple(m, max(depth1[m], depth2[m])));
        }
    }

    while (!pq.empty) {
        auto t = pq.front;
        pq.removeFront;
        ans += t[1];
        used[t[0]] = true;
        int x = depth1[t[0]] > depth2[t[0]] ? a : b;
        anst ~= tuple(t[0]+1, x+1, t[0]+1);
        foreach (m; G[t[0]]) {
            if (used[m]) continue;
            pq.insert(tuple(m, max(depth1[m], depth2[m])));
        }
    }

    ans.writeln;
    anst.reverse();
    anst.each!(a => writeln(a[0], " ", a[1], " ", a[2]));
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop;

void main() {
    auto N = readln.chomp.to!int;
    auto G = new int[][](N);

    foreach (_; 0..N-1) {
        auto s = readln.split.map!(to!int);
        G[s[0]-1] ~= s[1]-1;
        G[s[1]-1] ~= s[0]-1;
    }

    auto depth1 = new int[](N);
    auto depth2 = new int[](N);
    int[] route;

    void dfs1(int n, int p, int d, int[] dd) {
        dd[n] = d;
        foreach (m; G[n]) {
            if (m != p) dfs1(m, n, d+1, dd);
        }
    }

    bool dfs2(int n, int p, int dest) {
        if (n == dest) {
            route ~= n;
            return true;
        }

        foreach (m; G[n]) {
            if (m != p && dfs2(m, n, dest)) {
                route ~= n;
                return true;
            }
        }

        return false;
    }

    void dfs3(int n, int p) {

    }

    dfs1(0, -1, 0, depth1);
    int a = depth1.enumerate.maxElement!"a.value"[0].to!int;
    dfs1(a, -1, 0, depth1);
    int b = depth1.enumerate.maxElement!"a.value"[0].to!int;
    dfs1(b, -1, 0, depth2);
    dfs2(a, -1, b);

    auto dist1 = new int[](N);
    auto dist2 = new int[](N);
    auto used = new bool[](N);
    foreach (n; route) used[n] = true;
    long maxd = depth1.maxElement.to!long;
    long ans = maxd * (maxd + 1) / 2;

    auto pq = new BinaryHeap!(Array!(Tuple!(int, int)), "a[1] < b[1]");
    foreach (n; route) {
        foreach (m; G[n]) {
            if (used[m]) continue;
            pq.insert(tuple(m, max(depth1[m], depth2[m])));
        }
    }

    while (!pq.empty) {
        auto t = pq.front;
        pq.removeFront;
        ans += t[1];
        used[t[0]] = true;
        foreach (m; G[t[0]]) {
            if (used[m]) continue;
            pq.insert(tuple(m, max(depth1[m], depth2[m])));
        }
    }

    ans.writeln;
}


Devu is a dumb guy, his learning curve is very slow. You are supposed to teach him n subjects, the ith subject has ci chapters. When you teach him, you are supposed to teach all the chapters of a subject continuously.Let us say that his initial per chapter learning power of a subject is x hours. In other words he can learn a chapter of a particular subject in x hours.Well Devu is not complete dumb, there is a good thing about him too. If you teach him a subject, then time required to teach any chapter of the next subject will require exactly 1 hour less than previously required (see the examples to understand it more clearly). Note that his per chapter learning power can not be less than 1 hour.You can teach him the n subjects in any possible order. Find out minimum amount of time (in hours) Devu will take to understand all the subjects and you will be free to do some enjoying task rather than teaching a dumb guy.Please be careful that answer might not fit in 32 bit data type.

The first line will contain two space separated integers n, x (1 ≤ n, x ≤ 105). The next line will contain n space separated integers: c1, c2, ..., cn (1 ≤ ci ≤ 105).

Output a single integer representing the answer to the problem.

NoteLook at the first example. Consider the order of subjects: 1, 2. When you teach Devu the first subject, it will take him 3 hours per chapter, so it will take 12 hours to teach first subject. After teaching first subject, his per chapter learning time will be 2 hours. Now teaching him second subject will take 2 × 1 = 2 hours. Hence you will need to spend 12 + 2 = 14 hours.Consider the order of subjects: 2, 1. When you teach Devu the second subject, then it will take him 3 hours per chapter, so it will take 3 × 1 = 3 hours to teach the second subject. After teaching the second subject, his per chapter learning time will be 2 hours. Now teaching him the first subject will take 2 × 4 = 8 hours. Hence you will need to spend 11 hours.So overall, minimum of both the cases is 11 hours.Look at the third example. The order in this example doesn't matter. When you teach Devu the first subject, it will take him 3 hours per chapter. When you teach Devu the second subject, it will take him 2 hours per chapter. When you teach Devu the third subject, it will take him 1 hours per chapter. In total it takes 6 hours.

import core.thread;
import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex;

//	Input
class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { tokens = readln.split; if (stdin.eof) throw new EOFException; } auto token = tokens[0]; tokens.popFront; return token; }
int readInt() { return to!int(readToken); }
long readLong() { return to!long(readToken); }
real readReal() { return to!real(readToken); }

//	chmin/chmax
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

//	Pair
struct Pair(S, T) {
	S x; T y;
	int opCmp(    const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	int opCmp(ref const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	string toString() const { return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")"; }
}
auto pair(S, T)(inout(S) x, inout(T) y) { return Pair!(S, T)(x, y); }

//	Array
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = as.length; for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <  val); }); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <= val); }); }
T[] unique(T)(in T[] as) { T[] bs; foreach (a; as) if (bs.empty || bs[$ - 1] != a) bs ~= a; return bs; }

int N;
long X;
long[] C;

void main(string[] args) {
	try {
	for (; ; ) {
		N = readInt;
		X = readLong;
		C = new long[N];
		foreach (i; 0 .. N) {
			C[i] = readLong;
		}

		C.sort();
		long ans;
		foreach (i; 0 .. N) {
			ans += C[i] * max(X - i, 1);
		}
		writeln(ans);

	}
	} catch (EOFException) {}
}


A boy named Vasya has taken part in an Olympiad. His teacher knows that in total Vasya got at least x points for both tours of the Olympiad. The teacher has the results of the first and the second tour of the Olympiad but the problem is, the results have only points, no names. The teacher has to know Vasya's chances.Help Vasya's teacher, find two numbers — the best and the worst place Vasya could have won. Note that the total results' table sorts the participants by the sum of points for both tours (the first place has the participant who has got the most points). If two or more participants have got the same number of points, it's up to the jury to assign places to them according to their choice. It is guaranteed that each participant of the Olympiad participated in both tours of the Olympiad.

The first line contains two space-separated integers n, x (1 ≤ n ≤ 105; 0 ≤ x ≤ 2·105) — the number of Olympiad participants and the minimum number of points Vasya earned. The second line contains n space-separated integers: a1, a2, ..., an (0 ≤ ai ≤ 105) — the participants' points in the first tour. The third line contains n space-separated integers: b1, b2, ..., bn (0 ≤ bi ≤ 105) — the participants' points in the second tour. The participants' points are given in the arbitrary order. It is guaranteed that Vasya was present in the Olympiad — there are two integers i, j (1 ≤ i, j ≤ n) such, that ai + bj ≥ x.

Print two space-separated integers — the best and the worst place Vasya could have got on the Olympiad.

NoteIn the first text sample all 5 participants earn 2 points each in any case. Depending on the jury's decision, Vasya can get the first (the best) as well as the last (the worst) fifth place.In the second test sample in the best case scenario Vasya wins again: he can win 12 points and become the absolute winner if the total results' table looks like that — {4:8, 6:4, 3:6, 4:4, 4:3, 5:0}.In this table all participants are sorted by decreasing points and we can see how much a participant earned in the first and in the second tour.In the worst case scenario Vasya can get the fifth place if the table looks like that — {4:8, 4:6, 6:4, 5:4, 4:3, 3:0}, and he earned 4 and 3 points in the first and second tours, correspondingly.

import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

void main() {
    int N, X; scanf("%d %d\n", &N, &X);
    auto A = readln.chomp.split(" ").map!(to!int).array;
    auto B = readln.chomp.split(" ").map!(to!int).array;

    A.sort;
    B.sort;

    void first() {
        auto a = A.dup,
             b = B.dup;
        int L = a.back + b.back;
        a.popBack; b.popBack;
        int bi = 0;
        int ans = 1;
        for (int ai = N - 2; ai >= 0; ai--) {
            if (a[ai] + b[bi] <= L) {
                bi++;
            } else {
                ans++;
            }
        }
        write(ans);
    }
    void second() {
        auto a = A.dup,
             b = B.dup;
        auto set = redBlackTree!(true)(b);
        int ans = 0;
        for (int ai = 0; ai < N; ai++) {
            auto r = set.upperBound(X - a[ai] - 1);
            if (r.empty) continue;
            set.removeKey(r.front);
            ans++;
        }
        write(ans);
    }
    first(); write(" "); second();
    writeln;
}

import core.bitop, std.bitmanip;
import core.checkedint;
import std.algorithm, std.functional;
import std.array, std.container;
import std.bigint;
import std.conv;
import std.datetime.stopwatch;
import std.math, std.numeric;
import std.range, std.range.interfaces;
import std.stdio, std.string;
import std.typecons;

immutable int MX = 2 ^^ 14 - 1;

void main()
{
    int n, x;
    readf("%s %s", &n, &x);
    readln;

    auto arr = new int[][] (2);
    foreach (i; 0 .. 2) {
        arr[i] = readln.chomp.split.map!(to!int).array;
        arr[i].sort().reverse();
    }

    debug { arr[0].writeln; }

    int chk(int idx1) {
        int ans = 0, mv = n-1;
        foreach (i; 0 .. n) {
            while (mv >= 0 && arr[idx1][i] + arr[1-idx1][mv] < x) { --mv; }

            if (mv >= 0) {
                ++ans;
                --mv;
            }
        }

        return ans;
    }

    int ans = max(chk(0), chk(1));
    writeln("1 ", ans);
}


The last contest held on Johnny's favorite competitive programming platform has been received rather positively. However, Johnny's rating has dropped again! He thinks that the presented tasks are lovely, but don't show the truth about competitors' skills.The boy is now looking at the ratings of consecutive participants written in a binary system. He thinks that the more such ratings differ, the more unfair is that such people are next to each other. He defines the difference between two numbers as the number of bit positions, where one number has zero, and another has one (we suppose that numbers are padded with leading zeros to the same length). For example, the difference of $$$5 = 101_2$$$ and $$$14 = 1110_2$$$ equals to $$$3$$$, since $$$0101$$$ and $$$1110$$$ differ in $$$3$$$ positions. Johnny defines the unfairness of the contest as the sum of such differences counted for neighboring participants.Johnny has just sent you the rating sequence and wants you to find the unfairness of the competition. You have noticed that you've got a sequence of consecutive integers from $$$0$$$ to $$$n$$$. That's strange, but the boy stubbornly says that everything is right. So help him and find the desired unfairness for received numbers.

The input consists of multiple test cases. The first line contains one integer $$$t$$$ ($$$1 \leq t \leq 10\,000$$$) — the number of test cases. The following $$$t$$$ lines contain a description of test cases. The first and only line in each test case contains a single integer $$$n$$$ ($$$1 \leq n \leq 10^{18})$$$.

Output $$$t$$$ lines. For each test case, you should output a single line with one integer — the unfairness of the contest if the rating sequence equals to $$$0$$$, $$$1$$$, ..., $$$n - 1$$$, $$$n$$$.

NoteFor $$$n = 5$$$ we calculate unfairness of the following sequence (numbers from $$$0$$$ to $$$5$$$ written in binary with extra leading zeroes, so they all have the same length):   $$$000$$$  $$$001$$$  $$$010$$$  $$$011$$$  $$$100$$$  $$$101$$$ The differences are equal to $$$1$$$, $$$2$$$, $$$1$$$, $$$3$$$, $$$1$$$ respectively, so unfairness is equal to $$$1 + 2 + 1 + 3 + 1 = 8$$$.

import core.bitop,std.conv,std.stdio,std.string;
alias f=n=>(n*=2)-n.popcnt;
void main(){foreach(t;0..readln.strip.to!int)readln.strip.to!long.f.writeln;}

import core.bitop, std.algorithm, std.conv, std.stdio, std.string;
alias f = n => (n *= 2) - n.popcnt;
void main() {foreach (t; 0..readln.strip.to!int) readln.strip.to!long.f.writeln;}

import std.stdio;
import std.stdio;
import std.algorithm;
import std.range;
import std.functional;
import std.conv;
import std.string;
import std.math;
import core.bitop;

ulong diff(ulong a, ulong b) {
	ulong res = 0;
	foreach (bit; 0 .. 64) {
		if ((a & (1UL << bit)) != (b & (1UL << bit))) {
			res++;
		}
	}
	return res;
}

ulong calc(ulong a) {
	if ((a & (a - 1)) == 0) {
		return a | (a - 1);
	}
	else {
		ulong highestBit = 1UL << bsr(a);
		return calc(a - highestBit) + calc(highestBit);
	}
}

void main() {
	// ulong res = 0;
	// foreach (i; 0 .. 1000) {
	// 	res += diff(i, i + 1);
	// 	write("f(", (i + 1).to!string.padLeft(' ', 10), ") = ", res.to!string(2).padLeft('0', 10));
	// 	writeln("; ", calc(i + 1).to!string(2).padLeft('0', 10));
	// }
	int tt = readln().chomp.to!int;
	outer: foreach (t; 0 .. tt) {
		ulong n = readln().chomp.to!ulong;
		// writeln(n.to!string(2).padLeft('0', 64));
		writeln(calc(n));
	}
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

//long mod = 10^^9 + 7;
long mod = 998_244_353;
//long mod = 1_000_003;
void moda(T)(ref T x, T y) { x = (x + y) % mod; }
void mods(T)(ref T x, T y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(T)(ref T x, T y) { x = (x * y) % mod; }
void modpow(T)(ref T x, T y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }
void modd(T)(ref T x, T y) { y.modpow(mod - 2); x.modm(y); }

void main()
{
	auto t = RD!int;
	auto ans = new long[](t);
	foreach (ti; 0..t)
	{
		auto n = RD;

		auto cnt = new long[](64);
		cnt[0] = 1;
		foreach (i; 1..64)
		{
			cnt[i] = cnt[i-1] * 2 + 1;
		}

		foreach (i; 0..64)
		{
			auto bit = 1L << i;
			if (n & bit)
			{
				ans[ti] += cnt[i];
			}
		}
	}

	foreach (e; ans)
	{
		writeln(e);
	}
	stdout.flush;
	debug readln;
}


Mike and Ann are sitting in the classroom. The lesson is boring, so they decided to play an interesting game. Fortunately, all they need to play this game is a string $$$s$$$ and a number $$$k$$$ ($$$0 \le k < |s|$$$).At the beginning of the game, players are given a substring of $$$s$$$ with left border $$$l$$$ and right border $$$r$$$, both equal to $$$k$$$ (i.e. initially $$$l=r=k$$$). Then players start to make moves one by one, according to the following rules: A player chooses $$$l^{\prime}$$$ and $$$r^{\prime}$$$ so that $$$l^{\prime} \le l$$$, $$$r^{\prime} \ge r$$$ and $$$s[l^{\prime}, r^{\prime}]$$$ is lexicographically less than $$$s[l, r]$$$. Then the player changes $$$l$$$ and $$$r$$$ in this way: $$$l := l^{\prime}$$$, $$$r := r^{\prime}$$$. Ann moves first. The player, that can't make a move loses.Recall that a substring $$$s[l, r]$$$ ($$$l \le r$$$) of a string $$$s$$$ is a continuous segment of letters from s that starts at position $$$l$$$ and ends at position $$$r$$$. For example, "ehn" is a substring ($$$s[3, 5]$$$) of "aaaehnsvz" and "ahz" is not.Mike and Ann were playing so enthusiastically that they did not notice the teacher approached them. Surprisingly, the teacher didn't scold them, instead of that he said, that he can figure out the winner of the game before it starts, even if he knows only $$$s$$$ and $$$k$$$.Unfortunately, Mike and Ann are not so keen in the game theory, so they ask you to write a program, that takes $$$s$$$ and determines the winner for all possible $$$k$$$.

The first line of the input contains a single string $$$s$$$ ($$$1 \leq |s| \leq 5 \cdot 10^5$$$) consisting of lowercase English letters.

Print $$$|s|$$$ lines. In the line $$$i$$$ write the name of the winner (print Mike or Ann) in the game with string $$$s$$$ and $$$k = i$$$, if both play optimally

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    string s = readln.strip;
    int n = to!int(s.length);

    int[26] min_idx = n;

    for (int i = n-1; i >= 0; i--) {
        min_idx[s[i]-'a'] = i;
    }

    debug {
        writefln!"%s"(min_idx);
    }

    foreach (i; 0 .. n) {
        int j = s[i] - 'a';
        if (min_idx[0 .. j].find!( (a,b) => a < b )(i).empty) {
            writeln("Mike");
        } else {
            writeln("Ann");
        }
    }
}

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    string s = readln.strip;
    int n = to!int(s.length);

    int[26] min_idx = n;

    for (int i = n-1; i >= 0; i--) {
        min_idx[s[i]-'a'] = i;
    }

    debug {
        writefln!"%s"(min_idx);
    }

    foreach (i; 0 .. n) {
        int j = s[i] - 'a';
        if (min_idx[0 .. j].any!( (a) => a < i )) {
            write("Ann\n");
        } else {
            write("Mike\n");
        }
    }
}

import std.algorithm;
import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.string;

void main() {
    string s = readln.strip;
    int n = to!int(s.length);

    int[26] min_idx = n;

    for (int i = n-1; i >= 0; i--) {
        min_idx[s[i]-'a'] = i;
    }

    debug {
        writefln!"%s"(min_idx);
    }

    foreach (i; 0 .. n) {
        int j = s[i] - 'a';
        if (min_idx[0 .. j].any!( (a) => a < i )) {
            writeln("Ann");
        } else {
            writeln("Mike");
        }
    }
}

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.complex, std.container, std.math, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

void main() {
  try {
    for (; ; ) {
      const S = readToken();

      char mn = 'z' + 1;
      foreach (c; S) {
        writeln((mn < c) ? "Ann" : "Mike");
        chmin(mn, c);
      }
    }
  } catch (EOFException e) {
  }
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static string[] s_rd;
T RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
string RDR()() { return readln.chomp; }
T[] ARR(T = long)(in string str, T fix = 0) { auto r = str.split.to!(T[]); r[] += fix; return r; }
T[] RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[][] RDA2(T = long)(size_t n, T[] fix = []) { auto r = new T[][](n); foreach (i; 0..n) { r[i] = readln.chomp.split.to!(T[]); foreach (j, e; fix) r[i][j] += e; } return r; }
size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * y / gcd(x, y); }

//long mod = 10^^9 + 7;
long mod = 998_244_353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto s = RD!string;
	char best = s[0];
	writeln("Mike");
	foreach (c; s[1..$])
	{
		if (c <= best)
		{
			writeln("Mike");
		}
		else
		{
			writeln("Ann");
		}
		best = min(best, c);
	}

	stdout.flush();
	debug readln();
}


Maxim wants to buy some games at the local game shop. There are $$$n$$$ games in the shop, the $$$i$$$-th game costs $$$c_i$$$.Maxim has a wallet which can be represented as an array of integers. His wallet contains $$$m$$$ bills, the $$$j$$$-th bill has value $$$a_j$$$.Games in the shop are ordered from left to right, Maxim tries to buy every game in that order.When Maxim stands at the position $$$i$$$ in the shop, he takes the first bill from his wallet (if his wallet is empty then he proceeds to the next position immediately) and tries to buy the $$$i$$$-th game using this bill. After Maxim tried to buy the $$$n$$$-th game, he leaves the shop.Maxim buys the $$$i$$$-th game if and only if the value of the first bill (which he takes) from his wallet is greater or equal to the cost of the $$$i$$$-th game. If he successfully buys the $$$i$$$-th game, the first bill from his wallet disappears and the next bill becomes first. Otherwise Maxim leaves the first bill in his wallet (this bill still remains the first one) and proceeds to the next game.For example, for array $$$c = [2, 4, 5, 2, 4]$$$ and array $$$a = [5, 3, 4, 6]$$$ the following process takes place: Maxim buys the first game using the first bill (its value is $$$5$$$), the bill disappears, after that the second bill (with value $$$3$$$) becomes the first one in Maxim's wallet, then Maxim doesn't buy the second game because $$$c_2 > a_2$$$, the same with the third game, then he buys the fourth game using the bill of value $$$a_2$$$ (the third bill becomes the first one in Maxim's wallet) and buys the fifth game using the bill of value $$$a_3$$$.Your task is to get the number of games Maxim will buy.

The first line of the input contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n, m \le 1000$$$) — the number of games and the number of bills in Maxim's wallet. The second line of the input contains $$$n$$$ integers $$$c_1, c_2, \dots, c_n$$$ ($$$1 \le c_i \le 1000$$$), where $$$c_i$$$ is the cost of the $$$i$$$-th game. The third line of the input contains $$$m$$$ integers $$$a_1, a_2, \dots, a_m$$$ ($$$1 \le a_j \le 1000$$$), where $$$a_j$$$ is the value of the $$$j$$$-th bill from the Maxim's wallet.

Print a single integer — the number of games Maxim will buy.

NoteThe first example is described in the problem statement.In the second example Maxim cannot buy any game because the value of the first bill in his wallet is smaller than the cost of any game in the shop.In the third example the values of the bills in Maxim's wallet are large enough to buy any game he encounter until he runs out of bills in his wallet.

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, std.bitmanip;

void main() {
    auto s = readln.split.map!(to!int);
    auto N = s[0];
    auto M = s[1];
    auto C = readln.split.map!(to!int).array;
    auto A = readln.split.map!(to!int).array;
    int ans = 0;

    for (int i = 0, p = 0; i < N && p < M; ++i) {
        if (C[i] <= A[p]) {
            ans += 1;
            p += 1;
        }
    }

    ans.writeln;
}

import core.bitop;
import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.functional;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;
import std.range.interfaces;

void main()
{
    readln;

    auto r = () => readln.chomp.split.map!(to!int).array;
    auto c = r();
    auto a = r();

    debug { c.writeln; a.writeln; }

    auto ans = 0;
    int aidx = 0;
    foreach (e; c) {
        if (e > a[aidx]) continue;

        ans += 1;
        ++aidx;

        if (aidx == a.length) break;
    }

    ans.writeln;
}

void main(){
  import std.stdio, std.string, std.conv, std.algorithm;

  int n, m; rd(n, m);
  auto c=readln.split.to!(int[]);
  auto a=readln.split.to!(int[]);

  int cnt=0;
  for(int i=0, j=0; i<n && j<m; ){
    if(c[i]<=a[j]){
      cnt++;
      i++; j++;
    }else{
      i++;
    }
  }

  writeln(cnt);
}

void rd(T...)(ref T x){
  import std.stdio, std.string, std.conv;
  auto l=readln.split;
  assert(l.length==x.length);
  foreach(i, ref e; x) e=l[i].to!(typeof(e));
}


Lolek and Bolek are about to travel abroad by plane. The local airport has a special "Choose Your Plane" offer. The offer's conditions are as follows:  it is up to a passenger to choose a plane to fly on;  if the chosen plane has x (x > 0) empty seats at the given moment, then the ticket for such a plane costs x zlotys (units of Polish currency). The only ticket office of the airport already has a queue of n passengers in front of it. Lolek and Bolek have not stood in the queue yet, but they are already wondering what is the maximum and the minimum number of zlotys the airport administration can earn if all n passengers buy tickets according to the conditions of this offer?The passengers buy tickets in turn, the first person in the queue goes first, then goes the second one, and so on up to n-th person.

The first line contains two integers n and m (1 ≤ n, m ≤ 1000) — the number of passengers in the queue and the number of planes in the airport, correspondingly. The next line contains m integers a1, a2, ..., am (1 ≤ ai ≤ 1000) — ai stands for the number of empty seats in the i-th plane before the ticket office starts selling tickets. The numbers in the lines are separated by a space. It is guaranteed that there are at least n empty seats in total.

Print two integers — the maximum and the minimum number of zlotys that the airport administration can earn, correspondingly.

NoteIn the first test sample the number of passengers is equal to the number of empty seats, so regardless of the way the planes are chosen, the administration will earn the same sum.In the second sample the sum is maximized if the 1-st person in the queue buys a ticket to the 1-st plane, the 2-nd person — to the 2-nd plane, the 3-rd person — to the 3-rd plane, the 4-th person — to the 1-st plane. The sum is minimized if the 1-st person in the queue buys a ticket to the 1-st plane, the 2-nd person — to the 1-st plane, the 3-rd person — to the 2-nd plane, the 4-th person — to the 2-nd plane.

module cf_218B;

import std.stdio, std.algorithm;

void main() {
    int n, m;
    int[] freePlaces;

    readf("%d %d", &n, &m);
    freePlaces = new int[m];
    for (int i = 0; i < m; ++i) {
        readf(" %d", &freePlaces[i]);
    }

    int minPrice = 0, maxPrice = 0;

    int[] places = freePlaces.dup;
    sort(places);
    for (int i = 0; i < n; ++i) {
        minPrice += places[0]--;

        if (places[0] == 0) {
            places[0] = int.max;
        }

        int cur = 1;
        while (cur < m && places[cur] < places[cur - 1]) {
            swap(places[cur - 1], places[cur]);
            ++cur;
        }
    }

    places = freePlaces.dup;
    sort!("a > b")(places);
    for (int i = 0; i < n; ++i) {
        maxPrice += places[0]--;

        int cur = 1;
        while (cur < m && places[cur] > places[cur - 1]) {
            swap(places[cur - 1], places[cur]);
            ++cur;
        }
    }

    writeln(maxPrice, " ", minPrice);
}


Julia is conducting an experiment in her lab. She placed several luminescent bacterial colonies in a horizontal testtube. Different types of bacteria can be distinguished by the color of light they emit. Julia marks types of bacteria with small Latin letters "a", ..., "z".The testtube is divided into n consecutive regions. Each region is occupied by a single colony of a certain bacteria type at any given moment. Hence, the population of the testtube at any moment can be described by a string of n Latin characters.Sometimes a colony can decide to conquer another colony in one of the adjacent regions. When that happens, the attacked colony is immediately eliminated and replaced by a colony of the same type as the attacking colony, while the attacking colony keeps its type. Note that a colony can only attack its neighbours within the boundaries of the testtube. At any moment, at most one attack can take place.For example, consider a testtube with population "babb". There are six options for an attack that may happen next: the first colony attacks the second colony (1 → 2), the resulting population is "bbbb"; 2 → 1, the result is "aabb"; 2 → 3, the result is "baab"; 3 → 2, the result is "bbbb" (note that the result is the same as the first option); 3 → 4 or 4 → 3, the population does not change.The pattern of attacks is rather unpredictable. Julia is now wondering how many different configurations of bacteria in the testtube she can obtain after a sequence of attacks takes place (it is possible that no attacks will happen at all). Since this number can be large, find it modulo 109 + 7.

The first line contains an integer n — the number of regions in the testtube (1 ≤ n ≤ 5 000). The second line contains n small Latin letters that describe the initial population of the testtube.

Print one number — the answer to the problem modulo 109 + 7.

NoteIn the first sample the population can never change since all bacteria are of the same type.In the second sample three configurations are possible: "ab" (no attacks), "aa" (the first colony conquers the second colony), and "bb" (the second colony conquers the first colony).To get the answer for the third sample, note that more than one attack can happen.

import std.algorithm;
import std.array;
import std.range;
import std.stdio;
import std.string;

immutable int letters = 26;
immutable int mod = 10 ^^ 9 + 7;

void main () {
	int n;
	while (readf (" %s", &n) > 0) {
		readln;
		auto s = readln.strip.map !(x => x - 'a').array;

		auto next = new int [] [] (n, letters);
		foreach (let; 0..letters) {
			int pos = n;
			foreach_reverse (i; 0..n) {
				if (s[i] == let) pos = i;
				next[i][let] = pos;
			}
		}

		auto f = new long [] [] (2, n + 1);
		int b = 0;
		f[b][] = 0;
		f[b][0] = 1;
		foreach (num; 0..n)
		{
			b ^= 1;
			f[b][] = 0;
			foreach (pos; 0..n) {
				auto cur = f[!b][pos];
				auto ptr = next[pos].ptr;
				foreach (let; 0..letters) f[b][*(ptr + let)] += cur;
			}
			foreach (pos; 0..n) f[b][pos] %= mod;
		}

		int res = 0;
		foreach (pos; 0..n) res = (res + f[b][pos]) % mod;
		writeln (res);
	}
}

import core.bitop;
import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

immutable int letters = 26;
immutable int mod = 10 ^^ 9 + 7;

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		readln;
		auto s = readln.strip.map !(x => x - 'a').array;

		auto next = new int [] [] (n, letters);
		foreach (let; 0..letters)
		{
			int pos = n;
			foreach_reverse (i; 0..n)
			{
				if (s[i] == let)
				{
					pos = i;
				}
				next[i][let] = pos;
			}
		}

		auto f = new long [] [] (2, n + 1);
		int b = 0;
		f[b][] = 0;
		f[b][0] = 1;
		foreach (num; 0..n)
		{
			b ^= 1;
			f[b][] = 0;
			foreach (pos; 0..n)
			{
				auto cur = f[!b][pos];
				auto ptr = next[pos].ptr;
				f[b][*(ptr +  0)] += cur;
				f[b][*(ptr +  1)] += cur;
				f[b][*(ptr +  2)] += cur;
				f[b][*(ptr +  3)] += cur;
				f[b][*(ptr +  4)] += cur;
				f[b][*(ptr +  5)] += cur;
				f[b][*(ptr +  6)] += cur;
				f[b][*(ptr +  7)] += cur;
				f[b][*(ptr +  8)] += cur;
				f[b][*(ptr +  9)] += cur;
				f[b][*(ptr + 10)] += cur;
				f[b][*(ptr + 11)] += cur;
				f[b][*(ptr + 12)] += cur;
				f[b][*(ptr + 13)] += cur;
				f[b][*(ptr + 14)] += cur;
				f[b][*(ptr + 15)] += cur;
				f[b][*(ptr + 16)] += cur;
				f[b][*(ptr + 17)] += cur;
				f[b][*(ptr + 18)] += cur;
				f[b][*(ptr + 19)] += cur;
				f[b][*(ptr + 20)] += cur;
				f[b][*(ptr + 21)] += cur;
				f[b][*(ptr + 22)] += cur;
				f[b][*(ptr + 23)] += cur;
				f[b][*(ptr + 24)] += cur;
				f[b][*(ptr + 25)] += cur;
			}
			foreach (pos; 0..n)
			{
				f[b][pos] %= mod;
			}
		}

		int res = 0;
		foreach (pos; 0..n)
		{
			res += f[b][pos];
			if (res >= mod)
			{
				res -= mod;
			}
		}
		writeln (res);
	}
}


Iahub is so happy about inventing bubble sort graphs that he's staying all day long at the office and writing permutations. Iahubina is angry that she is no more important for Iahub. When Iahub goes away, Iahubina comes to his office and sabotage his research work.The girl finds an important permutation for the research. The permutation contains n distinct integers a1, a2, ..., an (1 ≤ ai ≤ n). She replaces some of permutation elements with -1 value as a revenge. When Iahub finds out his important permutation is broken, he tries to recover it. The only thing he remembers about the permutation is it didn't have any fixed point. A fixed point for a permutation is an element ak which has value equal to k (ak = k). Your job is to proof to Iahub that trying to recover it is not a good idea. Output the number of permutations which could be originally Iahub's important permutation, modulo 1000000007 (109 + 7).

The first line contains integer n (2 ≤ n ≤ 2000). On the second line, there are n integers, representing Iahub's important permutation after Iahubina replaces some values with -1.  It's guaranteed that there are no fixed points in the given permutation. Also, the given sequence contains at least two numbers -1 and each positive number occurs in the sequence at most once. It's guaranteed that there is at least one suitable permutation.

Output a single integer, the number of ways Iahub could recover his permutation, modulo 1000000007 (109 + 7).

NoteFor the first test example there are two permutations with no fixed points are [2, 5, 4, 3, 1] and [5, 1, 4, 3, 2]. Any other permutation would have at least one fixed point.


Once Bob took a paper stripe of n squares (the height of the stripe is 1 square). In each square he wrote an integer number, possibly negative. He became interested in how many ways exist to cut this stripe into three pieces so that the sum of numbers from each piece is equal to the sum of numbers from any other piece, and each piece contains positive integer amount of squares. Would you help Bob solve this problem?

The first input line contains integer n (1 ≤ n ≤ 105) — amount of squares in the stripe. The second line contains n space-separated numbers — they are the numbers written in the squares of the stripe. These numbers are integer and do not exceed 10000 in absolute value.

Output the amount of ways to cut the stripe into three non-empty pieces so that the sum of numbers from each piece is equal to the sum of numbers from any other piece. Don't forget that it's allowed to cut the stripe along the squares' borders only.

import std.stdio, std.string;

void solve(int[] s)
{
    auto sum = 0;
    foreach (val; s)
    {
        sum += val;
    }
    if (sum % 3 != 0)
    {
        writeln("0");
        return;
    }
    sum /= 3;
    auto n = cast(int)s.length;
    auto cnt = new int[n];
    auto last = 0;
    auto acc = 0;
    for (int i = n - 1; i >= 0; -- i)
    {
        cnt[i] = last;
        acc += s[i];
        if (acc == sum)
        {
            ++ cnt[i];
        }
        last = cnt[i];
    }
    long ans = 0;
    last = 0;
    acc = 0;
    foreach (i; 0 .. n)
    {
        acc += s[i];
        if (acc == sum && i + 2 < n)
        {
            ans += cnt[i + 2];
        }
    }
    writeln(ans);
}

int main(string[] args)
{
    int n;
    while (readf("%d\n", &n) == 1)
    {
        auto s = new int[n];
        foreach (i; 0 .. n)
        {
            readf(" %d", &s[i]);
        }
        readln();
        solve(s);
    }
    return 0;
}

import core.thread;
import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex;

//	Input
class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { tokens = readln.split; if (stdin.eof) throw new EOFException; } auto token = tokens[0]; tokens.popFront; return token; }
int readInt() { return to!int(readToken); }
long readLong() { return to!long(readToken); }
real readReal() { return to!real(readToken); }

//	chmin/chmax
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

//	Pair
struct Pair(S, T) {
	S x; T y;
	int opCmp(    const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	int opCmp(ref const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	string toString() const { return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")"; }
}
auto pair(S, T)(inout(S) x, inout(T) y) { return Pair!(S, T)(x, y); }

//	Array
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = as.length; for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <  val); }); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <= val); }); }
T[] unique(T)(in T[] as) { T[] bs; foreach (a; as) if (bs.empty || bs[$ - 1] != a) bs ~= a; return bs; }

int N;
long[] A;

void main(string[] args) {
	try {
	for (; ; ) {
		N = readInt;
		A = new long[N];
		foreach (i; 0 .. N) {
			A[i] = readLong;
		}

		long[] ASum = new long[N + 1];
		foreach (i; 0 .. N) {
			ASum[i + 1] = ASum[i] + A[i];
		}

		long ans;

		if (ASum[N] % 3 == 0) {
			const target = ASum[N] / 3;
			long cnt;
			foreach (i; 1 .. N) {
				if (ASum[i] == target * 2) {
					ans += cnt;
				}
				if (ASum[i] == target) {
					++cnt;
				}
			}
		}

		writeln(ans);

	}
	} catch (EOFException) {}
}


Pasha is a good student and one of MoJaK's best friends. He always have a problem to think about. Today they had a talk about the following problem.We have a forest (acyclic undirected graph) with n vertices and m edges. There are q queries we should answer. In each query two vertices v and u are given. Let V be the set of vertices in the connected component of the graph that contains v, and U be the set of vertices in the connected component of the graph that contains u. Let's add an edge between some vertex  and some vertex in  and compute the value d of the resulting component. If the resulting component is a tree, the value d is the diameter of the component, and it is equal to -1 otherwise. What is the expected value of d, if we choose vertices a and b from the sets uniformly at random?Can you help Pasha to solve this problem?The diameter of the component is the maximum distance among some pair of vertices in the component. The distance between two vertices is the minimum number of edges on some path between the two vertices.Note that queries don't add edges to the initial forest.

The first line contains three integers n, m and q(1 ≤ n, m, q ≤ 105) — the number of vertices, the number of edges in the graph and the number of queries. Each of the next m lines contains two integers ui and vi (1 ≤ ui, vi ≤ n), that means there is an edge between vertices ui and vi. It is guaranteed that the given graph is a forest. Each of the next q lines contains two integers ui and vi (1 ≤ ui, vi ≤ n) — the vertices given in the i-th query.

For each query print the expected value of d as described in the problem statement. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6. Let's assume that your answer is a, and the jury's answer is b. The checker program will consider your answer correct, if .

NoteIn the first example the vertices 1 and 3 are in the same component, so the answer for the first query is -1. For the second query there are two options to add the edge: one option is to add the edge 1 - 2, the other one is 2 - 3. In both ways the resulting diameter is 2, so the answer is 2.In the second example the answer for the first query is obviously -1. The answer for the second query is the average of three cases: for added edges 1 - 2 or 1 - 3 the diameter is 3, and for added edge 1 - 4 the diameter is 2. Thus, the answer is .

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos].dup;
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			foreach(v;r[x])
			{
				auto p=assumeSorted(r[y]).lowerBound(diam-v-1).length;
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos].dup;
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			foreach(v;parallel(r[x]))
			{
				auto p=r[y].upb(diam-v-1);
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos].dup;
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			foreach(v;r[x])
			{
				auto p=r[y].upb(diam-v-1);
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos].dup;
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			auto a=assumeSorted(r[y]);
			foreach(v;r[x])
			{
				auto p=a.lowerBound(diam-v-1).length;
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos];
				foreach_reverse(j;0..ss[pos].length-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			foreach(v;r[x])
			{
				auto p=upb(r[y],diam-v-1);
				ans+=p*diam;
				if(p<r[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos];
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			auto a=assumeSorted(r[y]);
			foreach(v;r[x])
			{
				auto p=a.lowerBound(diam-x-1).length;
				ans+=p*diam;
				if(p<r[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos];
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		double cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			auto a=assumeSorted(r[y]);
			foreach(v;r[x])
			{
				auto p=a.lowerBound(diam-v-1).length;
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos];
				foreach_reverse(j;0..sz(ss[pos])-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			foreach(v;r[x])
			{
				auto p=r[y].upb(diam-v-1);
				ans+=p*diam;
				if(p<ss[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,std.parallelism,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.stdio,std.variant,
	core.stdc.stdio : freopen;
alias RedBlackTree Rbt;alias redBlackTree rbt;alias BigInt big;
alias pair(X,Y)=Tuple!(X,"fi",Y,"se");alias long lint;const int mod=1000000007;
alias pair!(int,int) pii;alias pair!(long,long) pll;alias BoyerMooreFinder strfind;
alias make_pair mp;alias binary_search bins;alias gcd=std.numeric.gcd;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b){return a/gcd(a,b)*b;}
	pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_){return tuple!(X,"fi",Y,"se")(x_,y_);}
	big gcd(big a,big b){while(b){a%=b;swap(a,b);}return a;}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	int sz(T)(T a) if(hasLength!T){return cast(int)a.length;}
	size_t lowb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		if(pos==a.length)return pos;
		else return a[pos]==g?pos+1:pos;
	}
	size_t binf(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		auto pos=lowb(a,g);
		return (g==a[pos])?pos:a.length;
	}
	bool binary_search(T,X)(T a,auto ref X g)
	 if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n=a.length,in size_t m=a.front.length)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	return s==ptrs.length;
}
bool read(T...)(auto ref T ptrs) if (ptrs.length > 0)
{
	size_t s=0;
	foreach(ref e;ptrs)
	{
		if(isSomeChar!(Unqual!(typeof(e))))s+=readf(" %c",&e);
		else s+=readf(" %s",&e);
	}
	readln;
	return s==ptrs.length;
}
nothrow auto inf(in char* name) {return freopen(name,"r",core.stdc.stdio.stdin);}
nothrow auto ouf(in char* name) {return freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//foreach_reverse isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold return static heapify join filter foreach
//------------------------------------------program beginning--------------------------

void main()
{
	version(ONLINE_JUDGE){}
	else
	{
		assert(freopen("input.txt","r",core.stdc.stdio.stdin));
		assert(freopen("output.txt","w",core.stdc.stdio.stdout));
	}
	int n,q,m;
loop:while(read(n,m,q))
	{
		auto g=new int[][n+2],r=new long[][n+2],ss=new long[][n+2],comps=new int[][n+2];
		auto c=new int[n+2],d=new int[n+2];
		int pos=1;
		foreach(i;0..m)
		{
			int u,v;
			read(u,v);
			g[u]~=v;
			g[v]~=u;
		}
		void dfs0(int v,int pr=-1)
		{
			comps[pos]~=v;
			c[v]=pos;
			foreach(x;g[v])if(x!=pr)dfs0(x,v);
		}
		void dfs(int v,int pr=-1,int h=0)
		{
			d[v]=max(d[v],h);
			foreach(x;g[v])if(x!=pr)dfs(x,v,h+1);
		}
		foreach(i;1..n+1)
		{
			if(c[i]==0)
			{
				dfs0(i);
				dfs(i);
				int ans=0,v=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
					d[x]=0;
				}
				dfs(v);
				ans=0;
				foreach(x;comps[pos])
				{
					if(ans<d[x])
					{
						ans=d[x];
						v=x;
					}
				}
				dfs(v);
				foreach(x;comps[pos])
				{
					r[pos]~=d[x];
				}
				sort(r[pos]);
				ss[pos]=r[pos];
				foreach_reverse(j;0..ss[pos].length-1)
				{
					ss[pos][j]+=ss[pos][j+1];
				}
				pos++;
			}
		}
		real cel(int x,int y)
		{
			long ans;
			long diam=max(r[x].back,r[y].back);
			auto a=assumeSorted(r[y]);
			foreach(v;r[x])
			{
				auto p=a.lowerBound(diam-x-1).length;
				ans+=p*diam;
				if(p<r[y].length)ans+=ss[y][p]+(ss[y].length-p)*(v+1);
			}
			return ans*1.00000L/(1L*r[x].length*r[y].length);
		}
		alias getans=memoize!cel;
		foreach(ii;0..q)
		{
			int u,v;
			read(u,v);
			int p1=c[u],p2=c[v];
			if(r[p1].length>r[p2].length)swap(p2,p1);
			if(p1==p2)write("-1\n");
			else writef("%.10f\n",getans(p1,p2));
		}
	}
}


Roma works in a company that sells TVs. Now he has to prepare a report for the last year.Roma has got a list of the company's incomes. The list is a sequence that consists of n integers. The total income of the company is the sum of all integers in sequence. Roma decided to perform exactly k changes of signs of several numbers in the sequence. He can also change the sign of a number one, two or more times.The operation of changing a number's sign is the operation of multiplying this number by -1.Help Roma perform the changes so as to make the total income of the company (the sum of numbers in the resulting sequence) maximum. Note that Roma should perform exactly k changes.

The first line contains two integers n and k (1 ≤ n, k ≤ 105), showing, how many numbers are in the sequence and how many swaps are to be made. The second line contains a non-decreasing sequence, consisting of n integers ai (|ai| ≤ 104). The numbers in the lines are separated by single spaces. Please note that the given sequence is sorted in non-decreasing order.

In the single line print the answer to the problem — the maximum total income that we can obtain after exactly k changes.

NoteIn the first sample we can get sequence [1, 1, 1], thus the total income equals 3.In the second test, the optimal strategy is to get sequence [-1, 1, 1], thus the total income equals 1.

import std.algorithm;
import std.stdio;

void main() {
    int N, K;
    readf(" %s %s", &N, &K);
    int[] A = new int[N];
    foreach (i, ref a; A) {
        readf(" %s", &a);
        if (a < 0 && K > 0) {
            a *= -1;
            K--;
        }
    }
    sort(A);
    while (K > 0) {
        A[0] *= -1;
        K--;
    }
    writeln(reduce!("a + b")(0, A));
}

import std.stdio : write, writeln, writefln, stdin;
import std.array;
import std.range;
import std.typecons;
import std.algorithm : max, min;

int n;
int k;
int[] a;

T sum(T)(T[] l ...){
	T s;
	foreach(v; l){
		s += v;
	}
	return s;
}

void main(){
	n.next;
	k.next;
	a = a.init;
	foreach(i; n.iota){
		a ~= next!int();
	}

	/+
	foreach(ref v; a){
		if( v > 0 ){ break; }
		if( k <= 0 ){ break; }
		v *= -1;
		--k;
	}
	+/
	bool flag = true;
	for(int i=0; 0<k; --k){
		if( a[i] >= 0 ){
			a.sort;
			for(int j=0; j<k%2; ++j){
				a[0]*=-1;
			}
			break;
		}else{
			a[i] *= -1;
			if( i+1 < n ) ++i;
		}

	}

	a.sum.writeln;
}

import std.stdio : readln;
import std.conv : to;
import std.string : split, chomp;
shared string[] input;
shared string delim = " ";
T next(T)()
in
{
	assert(hasNext());
}
out
{
	input.popFront;
}
body
{
	return input.front.to!T;
}

void next(T)(ref T v){
	v = next!T();
}

bool hasNext(){
	if(input.length > 0){
		return true;
	}

	string str = readln;
	if(str.length > 0){
		input ~= str.chomp.split(delim);
		return true;
	}else{
		return false;
	}
}

void dbg(T...)(T vs)
{
	import std.stdio : stderr;
	foreach(v; vs)
		stderr.write(v.to!string ~ " ");
	stderr.write("\n");
}

T clone(T)(T v){
	T v_;
	static if(isInputRange!(T)){
		foreach(ite; v){
			v_ ~= ite.clone;
		}
	}else{
		v_ = v;
	}

	return v_;
}

import std.stdio : write, writeln, writefln, stdin;
import std.array;
import std.range;
import std.typecons;
import std.algorithm : max, min;

int n;
int k;
int[] a;

T sum(T)(T[] l ...){
	T s;
	foreach(v; l){
		s += v;
	}
	return s;
}

void main(){
	n.next;
	k.next;
	a = a.init;
	foreach(i; n.iota){
		a ~= next!int();
	}

	a.sort;
	foreach(ref v; a){
		if( v > 0 ){ break; }
		if( k <= 0 ){ break; }
		v *= -1;
		--k;
	}
	a.sort;
	foreach(ref v; a){
		if( k <= 0 ){ break; }
		v *= -1;
		--k;
	}

	a.sum.writeln;
}

import std.stdio : readln;
import std.conv : to;
import std.string : split, chomp;
shared string[] input;
shared string delim = " ";
T next(T)()
in
{
	assert(hasNext());
}
out
{
	input.popFront;
}
body
{
	return input.front.to!T;
}

void next(T)(ref T v){
	v = next!T();
}

bool hasNext(){
	if(input.length > 0){
		return true;
	}

	string str = readln;
	if(str.length > 0){
		input ~= str.chomp.split(delim);
		return true;
	}else{
		return false;
	}
}

void dbg(T...)(T vs)
{
	import std.stdio : stderr;
	foreach(v; vs)
		stderr.write(v.to!string ~ " ");
	stderr.write("\n");
}

T clone(T)(T v){
	T v_;
	static if(isInputRange!(T)){
		foreach(ite; v){
			v_ ~= ite.clone;
		}
	}else{
		v_ = v;
	}

	return v_;
}

import std.stdio : write, writeln, writefln, stdin;
import std.array;
import std.range;
import std.typecons;
import std.algorithm : max, min;

int n;
int k;
int[] a;

T sum(T)(T[] l ...){
	T s;
	foreach(v; l){
		s += v;
	}
	return s;
}

void main(){
	n.next;
	k.next;
	a = a.init;
	foreach(i; n.iota){
		a ~= next!int();
	}

	/+
	foreach(ref v; a){
		if( v > 0 ){ break; }
		if( k <= 0 ){ break; }
		v *= -1;
		--k;
	}
	+/
	bool flag = true;
	for(int i=0; 0<k; --k){
		if( a[i] >= 0){
			flag = false;
		}

		a[i] *= -1;

		if( flag && i+1<n ){
			++i;
		}
	}

	assert( k == 0 );
	a.sum.writeln;
}

import std.stdio : readln;
import std.conv : to;
import std.string : split, chomp;
shared string[] input;
shared string delim = " ";
T next(T)()
in
{
	assert(hasNext());
}
out
{
	input.popFront;
}
body
{
	return input.front.to!T;
}

void next(T)(ref T v){
	v = next!T();
}

bool hasNext(){
	if(input.length > 0){
		return true;
	}

	string str = readln;
	if(str.length > 0){
		input ~= str.chomp.split(delim);
		return true;
	}else{
		return false;
	}
}

void dbg(T...)(T vs)
{
	import std.stdio : stderr;
	foreach(v; vs)
		stderr.write(v.to!string ~ " ");
	stderr.write("\n");
}

T clone(T)(T v){
	T v_;
	static if(isInputRange!(T)){
		foreach(ite; v){
			v_ ~= ite.clone;
		}
	}else{
		v_ = v;
	}

	return v_;
}


A string is called bracket sequence if it does not contain any characters other than "(" and ")". A bracket sequence is called regular (shortly, RBS) if it is possible to obtain correct arithmetic expression by inserting characters "+" and "1" into this sequence. For example, "", "(())" and "()()" are RBS and ")(" and "(()" are not.We can see that each opening bracket in RBS is paired with some closing bracket, and, using this fact, we can define nesting depth of the RBS as maximum number of bracket pairs, such that the $$$2$$$-nd pair lies inside the $$$1$$$-st one, the $$$3$$$-rd one — inside the $$$2$$$-nd one and so on. For example, nesting depth of "" is $$$0$$$, "()()()" is $$$1$$$ and "()((())())" is $$$3$$$.Now, you are given RBS $$$s$$$ of even length $$$n$$$. You should color each bracket of $$$s$$$ into one of two colors: red or blue. Bracket sequence $$$r$$$, consisting only of red brackets, should be RBS, and bracket sequence, consisting only of blue brackets $$$b$$$, should be RBS. Any of them can be empty. You are not allowed to reorder characters in $$$s$$$, $$$r$$$ or $$$b$$$. No brackets can be left uncolored.Among all possible variants you should choose one that minimizes maximum of $$$r$$$'s and $$$b$$$'s nesting depth. If there are multiple solutions you can print any of them.

The first line contains an even integer $$$n$$$ ($$$2 \le n \le 2 \cdot 10^5$$$) — the length of RBS $$$s$$$. The second line contains regular bracket sequence $$$s$$$ ($$$|s| = n$$$, $$$s_i \in \{$$$"(", ")"$$$\}$$$).

Print single string $$$t$$$ of length $$$n$$$ consisting of "0"-s and "1"-s. If $$$t_i$$$ is equal to 0 then character $$$s_i$$$ belongs to RBS $$$r$$$, otherwise $$$s_i$$$ belongs to $$$b$$$.

NoteIn the first example one of optimal solutions is $$$s = $$$ "$$$\color{blue}{()}$$$". $$$r$$$ is empty and $$$b = $$$ "$$$()$$$". The answer is $$$\max(0, 1) = 1$$$.In the second example it's optimal to make $$$s = $$$ "$$$\color{red}{(}\color{blue}{(}\color{red}{)}\color{blue}{)}$$$". $$$r = b = $$$ "$$$()$$$" and the answer is $$$1$$$.In the third example we can make $$$s = $$$ "$$$\color{red}{(}\color{blue}{((}\color{red}{)()}\color{blue}{)())}$$$". $$$r = $$$ "$$$()()$$$" and $$$b = $$$ "$$$(()())$$$" and the answer is $$$2$$$.

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, core.stdc.string;

void main() {
    auto N = readln.chomp.to!int;
    auto S = readln.chomp;
    auto ans = new int[](N);
    int tmp = 0;
    foreach (i; 0..N) {
        if (S[i] == '(') {
            ans[i] = tmp % 2;
            tmp += 1;
        } else {
            tmp -= 1;
            ans[i] = tmp % 2;
        }
    }
    ans.map!(to!string).join("").writeln;
}

//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.random;
void main() {
  immutable n = readln.strip.to!int;
  auto s = readln.take(n).array;
  int[] st;
  auto x = new int[n];
  auto ans = new char[n];
  foreach (i; 0 .. n) {
    if (s[i] == '(') {
      st ~= i;
      ans[i] = (st.length & 1) ? '0' : '1';
    } else {
      int j = st.back;
      st.popBack ();
      x[i] = j;
      x[j] = i;
      ans[i] = ans[j];
    }
  }
  writeln (ans);
}

import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}

	int n = read.to!int;
	string s = readln.chomp;

	int d = 0;
	int dmax = 0;
	foreach(c; s){
		if(c == '(') d += 1;
		else d -= 1;
		if(d > dmax) dmax = d;
	}

	char[] ans;
	foreach(c; s){
		if(c == '('){
			d += 1;
			if(d > dmax / 2) ans ~= "1";
			else ans ~= "0";
		}
		else{
			if(d > dmax / 2) ans ~= "1";
			else ans ~= "0";
			d -= 1;
		}
	}

	ans.writeln;
}

module _;
void main() {
	import std.stdio;
	import std.string, std.conv;
	int n = readln.strip.to!int;
	auto s = readln.strip;

	bool check(int limit, ref string co, bool doco) {
		int r = 0, b = 0;
		foreach(ch; s) {
			if (ch == '(') {
				if (r < limit) {
					r++;
					if (doco) co ~= '0';
				} else if (b < limit) {
					b++;
					if (doco) co ~='1';
				} else {
					return false;
				}
			} else {
				if (r > 0) {
					r--;
					if (doco) co ~= '0';
				} else if (b > 0) {
					b--;
					if (doco) co ~='1';
				} else {
					// impossible
					return false;
				}
			}
		}
		return true;
	}

	string ans = "";
	int l = 0, r = n;
	while (l < r-1) {
		int mid = (l+r)/2;
		if (check(mid, ans, false)) {
			r = mid;
		} else {
			l = mid;
		}
	}
	check(r, ans, true);
	writeln(ans);
}