<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

545. Cut the rope, another rope and so on!
Time limit per test: 1 second(s)
Memory limit: 262144 kilobytes
input: standard
output: standard



A game called "Cut the rope, another rope and so on!" is very popular in Berland. People all over the country just cut ropes on their bPads and bPhones over and over again.

The game is about sequentially cutting ropes with a small ball hanging on their ends. At the beginning of the game all ropes have one end attached to the top of the screen, that is, we can assume that the ends are located on the horizontal axis Ox. The other ends of the ropes are connected together and a small ball is attached to them. The ropes never shrink or stretch. At the beginning of the game the system is in a static state — some ropes are tight, some might be loose. In this game, the ball should be considered as a material point, that is, we assume that it is infinitely small.




Let's suppose that at the beginning the ball is suspended on n ropes. A player cuts off n-1 uncut ropes, one after another. The ball may move in some way after some ropes are cut. The next cutting is made as soon as the ball becomes static after the previous cutting (the first cutting is made immediately). If the present cutting does not change the ball's position, then the next cutting is done immediately.

The physics in this game is a bit peculiar: educated people say that the motion of the ball is going in a perfectly viscous medium. This means that at any time the ball is moving so that it reduces the potential energy in the fastest way. For example, if the ball can fall straight down, it moves exactly this way. Note that the ball never swings, that is, its movement always moves it below its current position. You should assume that ropes have negligible masses compared with the mass of the ball.

Assuming that the ball always moves at the constant speed of 1 unit of length per unit of time, find the position of the ball at the given moments of time t1, t2,..., tm.

Input
The first input line contains two integers n and m (2 ≤ n ≤ 20; 1 ≤ m ≤ 1000) — the number of ropes and the number of ball position queries, correspondingly.

The second line contains n integers x1, x2,..., xn (1 ≤ xi ≤ 200) — the coordinates of the ropes' attachment points on the horizontal axis.

The third line contains n integers l1, l2,..., ln (1 ≤ li ≤ 200), li is the length of the i-th rope. It is guaranteed that values x1, x2,..., xn and l1, l2,..., ln are such that the initial configuration really exists, that is, the lower ends of all ropes can be simultaneously tied to a ball. It is guaranteed that no two ropes have equal lengths and attached to the same point at the same time.

The fourth line describes the sequence of cuts, it contains n-1 distinct integers p1, p2,..., pn-1 (1 ≤ pj ≤ n), where pj is the index of the rope that is the j-th one to be cut.

The last input line contains m real numbers t1, t2,..., tm (0 ≤ tk ≤ 1000) — the moments of time for determining the ball's position. All ti are given with no more than three digits after the decimal point. The first rope is cut at time 0, each of the other ropes is cut at the moment the ball becomes stable after the cutting of the previous rope. If the current cutting doesn't change the ball's position, then the next rope is cut immediately. All values t1, t2,..., tm are distinct and are given in the increasing order.

Output
Print m lines, the k-th line must contain the coordinates of the ball at time tk. Consider all ropes attached to the Ox axis, and the Oy axis is directed upwards. Print the numbers with at least 5 digits after the decimal point. After the ball hangs on the last rope, it doesn't move anymore.

Example(s)
sample input
sample output
3 4
1 1 3
5 10 20
1 2
2.5 10 16 20
1.0000000000 -7.5000000000
1.0000000000 -15.0000000000
2.0972097000 -19.9796138520
3.0000000000 -20.0000000000

sample input
sample output
3 7
2 22 19
12 12 10
2 1
0 0.18 0.19 4.39 6 7 9
12.0000000000 -6.6332495807
11.8993800085 -6.7824977292
11.8937244905 -6.7907448565
15.0867736994 -9.2025355158
16.6125973239 -9.7108345914
17.5939901889 -9.9006634329
19.0000000000 -10.0000000000

<|response|>
## 1. Abridged problem statement

There are `n` ropes attached to points `(xi, 0)` on the horizontal axis. Rope `i` has length `li`, and all rope ends are tied to one point-like ball.

A rope does not stretch, so while rope `i` exists, the ball must satisfy:

\[
(x-x_i)^2+y^2 \le l_i^2
\]

Initially the ball is stable. Then `n-1` ropes are cut in a given order. After each cut, the ball moves until it becomes stable again; then the next cut happens. The ball moves with speed `1` and always chooses the direction that decreases potential energy fastest, meaning it tries to move as downward as possible.

For each query time `t`, output the ball coordinates.

Constraints are small: `n ≤ 20`, `m ≤ 1000`.

---

## 2. Key observations needed to solve the problem

### Observation 1: Each rope is a disk constraint

For rope `i`, the ball must stay inside or on the disk centered at `(xi, 0)` with radius `li`.

For an active rope set `S`, all feasible positions are:

\[
\bigcap_{i \in S} D_i
\]

where `Di` is the disk of rope `i`.

---

### Observation 2: Stable position is the lowest feasible point

Gravity pulls downward, so the stable position for active rope set `S` is the point with minimum `y` inside the intersection of disks.

The lowest point must be either:

1. The bottom of one circle:

\[
(x_i, -l_i)
\]

2. An intersection point of two circles.

Since `n ≤ 20`, we can enumerate all such candidate points and keep the lowest one that lies inside every active disk.

---

### Observation 3: Motion consists only of vertical segments and circle arcs

At any moment, some ropes can be tight. A tight rope means the ball lies exactly on that circle boundary.

The ball wants to move in gravity direction:

\[
g = (0, -1)
\]

but it cannot leave any active disk.

For each tight rope `i`, define the outward normal:

\[
n_i = \frac{p - (x_i,0)}{l_i}
\]

A velocity direction `d` is feasible if:

\[
d \cdot n_i \le 0
\]

If gravity itself satisfies all constraints, the ball falls vertically.

Otherwise, the ball slides along the boundary of one tight circle. Therefore each trajectory piece is either:

- a vertical segment,
- or an arc of some circle.

---

### Observation 4: We can trace motion event by event

During vertical motion, the next event is hitting a circle boundary.

During circular arc motion, the next event is either:

- reaching an intersection with another active circle,
- or reaching the bottom point of the current circle.

Because there are at most `20` ropes, event-based simulation is easily fast enough.

---

## 3. Full solution approach

### Step 1: Compute equilibrium for an active rope set

For current active ropes `S`:

1. Add all circle bottom points `(xi, -li)` as candidates.
2. Add all pairwise circle intersection points.
3. For every candidate, check whether it lies inside every disk in `S`.
4. Choose the valid candidate with smallest `y`.

This gives the stable ball position.

---

### Step 2: Process cuts

Start with all ropes active.

Compute initial equilibrium.

For each cut:

1. Remove the cut rope from the active set.
2. Compute the new equilibrium.
3. If the new equilibrium is the same as the current position, this cut causes no movement.
4. Otherwise, trace the path from current position to the new equilibrium.
5. Store this motion phase:
   - start time,
   - start point,
   - end point,
   - list of path segments,
   - total length.

Since the ball speed is `1`, phase duration equals total path length.

---

### Step 3: Trace one motion phase

At current position:

1. Find tight ropes.
2. Compute the steepest feasible descent direction.
3. If direction is vertical:
   - fall until hitting the nearest circle boundary below,
   - or until reaching the target equilibrium.
4. If direction follows a circle:
   - move along the circle arc,
   - stop at the first intersection with another circle,
   - or at the circle bottom.
5. Repeat until the target equilibrium is reached.

---

### Step 4: Answer queries

For each query time `t`:

1. Find the motion phase containing `t`.
2. Let `s = t - phase.start_time`.
3. Walk through the stored segments until distance `s` is reached.
4. Interpolate inside that segment:
   - linearly for vertical segments,
   - by angle for circular arcs.
5. If `t` is after all phases, output the final stable position.

---

### Complexity

For one active set, equilibrium computation checks `O(n^2)` candidates, each against `O(n)` disks:

\[
O(n^3)
\]

There are only `n-1` cuts, and `n ≤ 20`, so this is very small.

The path simulation is also event-based with few events.

---

## 4. C++ implementation with detailed comments

```cpp
#include <bits/stdc++.h>
using namespace std;

using ld = long double;

const ld EPS = 1e-12L;
const ld PI = acosl(-1.0L);

struct Point {
    ld x, y;

    Point(ld _x = 0, ld _y = 0) : x(_x), y(_y) {}

    Point operator + (const Point& other) const {
        return Point(x + other.x, y + other.y);
    }

    Point operator - (const Point& other) const {
        return Point(x - other.x, y - other.y);
    }

    Point operator * (ld k) const {
        return Point(x * k, y * k);
    }

    Point operator / (ld k) const {
        return Point(x / k, y / k);
    }

    ld dot(const Point& other) const {
        return x * other.x + y * other.y;
    }

    ld norm2() const {
        return x * x + y * y;
    }

    ld norm() const {
        return sqrtl(norm2());
    }
};

int n, m;
vector<ld> xs, ls;
vector<int> cut_order;
vector<ld> queries;

/*
    Checks whether point p lies inside all disks corresponding to ropes in S.
*/
bool inside_disks(const Point& p, const vector<int>& S, ld tol = 1e-7L) {
    for (int i : S) {
        ld dx = p.x - xs[i];
        ld dy = p.y;

        if (dx * dx + dy * dy > ls[i] * ls[i] + tol) {
            return false;
        }
    }

    return true;
}

/*
    Returns intersection points of circles i and j.

    Centers are (xs[i], 0), (xs[j], 0).
    Radii are ls[i], ls[j].
*/
vector<Point> circle_intersections(int i, int j) {
    ld dx = xs[j] - xs[i];
    ld d = fabsl(dx);

    // Same center: no useful pair intersection.
    if (d < 1e-14L) {
        return {};
    }

    ld r1 = ls[i];
    ld r2 = ls[j];

    // No intersection.
    if (d > r1 + r2 + 1e-12L) {
        return {};
    }

    // One circle strictly inside another.
    if (d < fabsl(r1 - r2) - 1e-12L) {
        return {};
    }

    // Distance from center i to chord midpoint.
    ld a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);

    ld h2 = r1 * r1 - a * a;
    if (h2 < 0) {
        h2 = 0;
    }

    ld h = sqrtl(h2);

    ld sign = xs[j] > xs[i] ? 1.0L : -1.0L;
    ld mx = xs[i] + sign * a;

    return {
        Point(mx, h),
        Point(mx, -h)
    };
}

/*
    Finds the lowest point in the intersection of disks for active set S.
*/
Point equilibrium(const vector<int>& S) {
    vector<Point> candidates;

    // Bottom point of each active circle.
    for (int i : S) {
        candidates.push_back(Point(xs[i], -ls[i]));
    }

    // Pairwise circle intersections.
    for (int a = 0; a < (int)S.size(); a++) {
        for (int b = a + 1; b < (int)S.size(); b++) {
            vector<Point> inters = circle_intersections(S[a], S[b]);

            for (Point p : inters) {
                candidates.push_back(p);
            }
        }
    }

    Point best(0, 1e18L);

    for (Point p : candidates) {
        if (inside_disks(p, S) && p.y < best.y) {
            best = p;
        }
    }

    return best;
}

/*
    Returns all active ropes that are tight at point p.
*/
vector<int> tight_set(const Point& p, const vector<int>& S) {
    vector<int> tight;

    for (int i : S) {
        ld dx = p.x - xs[i];
        ld dy = p.y;
        ld d = sqrtl(dx * dx + dy * dy);

        if (fabsl(d - ls[i]) < 1e-6L) {
            tight.push_back(i);
        }
    }

    return tight;
}

struct DirectionResult {
    Point dir;       // Unit movement direction.
    int arc_circle;  // -1 means vertical/free movement, otherwise circle index.
};

/*
    Computes the steepest feasible downward direction.

    The ball wants to move in direction g = (0, -1).
    For each tight circle, movement direction d must satisfy:
        d dot normal <= 0
*/
DirectionResult descent_direction(const Point& p, const vector<int>& tight) {
    Point g(0, -1);

    if (tight.empty()) {
        return {g, -1};
    }

    vector<Point> normals;

    for (int i : tight) {
        Point r(p.x - xs[i], p.y);
        ld len = r.norm();

        if (len < 1e-14L) {
            normals.push_back(Point(0, -1));
        } else {
            normals.push_back(r / len);
        }
    }

    // Check whether gravity itself is feasible.
    bool gravity_ok = true;

    for (Point normal : normals) {
        if (g.dot(normal) > 1e-9L) {
            gravity_ok = false;
            break;
        }
    }

    if (gravity_ok) {
        int tangent_circle = -1;

        // If gravity is exactly tangent to a circle, remember it.
        for (int k = 0; k < (int)tight.size(); k++) {
            if (fabsl(g.dot(normals[k])) < 1e-9L) {
                tangent_circle = tight[k];
                break;
            }
        }

        return {g, tangent_circle};
    }

    bool found = false;
    Point best_dir(0, 1);
    int best_circle = -1;

    /*
        Try sliding along each tight circle.

        Projection of g onto tangent line of circle k:
            d = g - (g dot n_k) n_k
    */
    for (int k = 0; k < (int)tight.size(); k++) {
        Point nk = normals[k];
        ld gn = g.dot(nk);

        Point d = g - nk * gn;
        ld len = d.norm();

        if (len < 1e-14L) {
            continue;
        }

        d = d / len;

        // Must move downward.
        if (d.y >= -1e-12L) {
            continue;
        }

        // Must not violate other tight constraints.
        bool ok = true;

        for (int j = 0; j < (int)tight.size(); j++) {
            if (j == k) {
                continue;
            }

            if (d.dot(normals[j]) > 1e-9L) {
                ok = false;
                break;
            }
        }

        if (!ok) {
            continue;
        }

        // Choose the steepest downward direction.
        if (!found || d.y < best_dir.y) {
            found = true;
            best_dir = d;
            best_circle = tight[k];
        }
    }

    if (!found) {
        return {Point(0, 0), -1};
    }

    return {best_dir, best_circle};
}

struct Segment {
    bool vertical;

    // Vertical segment data.
    ld x;
    ld y0, y1;

    // Arc data.
    ld cx;
    ld r;
    ld theta0, theta1;

    ld len;
};

struct Phase {
    ld start_time;
    ld total_len;

    Point start_point;
    Point end_point;

    vector<Segment> segments;
};

/*
    Angular distance from angle "from" to angle "to",
    moving in direction s.

    s = +1 means increasing angle.
    s = -1 means decreasing angle.
*/
ld forward_angle(ld from, ld to, ld s) {
    ld two_pi = 2 * PI;

    ld delta = s * (to - from);
    delta = fmodl(delta, two_pi);

    if (delta < 0) {
        delta += two_pi;
    }

    return delta;
}

/*
    Builds the full trajectory from start to target under active set S.
*/
vector<Segment> trace_path(Point start, Point target, const vector<int>& S) {
    vector<Segment> segments;
    Point cur = start;

    for (int iter = 0; iter < 20000; iter++) {
        if ((cur - target).norm() < 1e-9L) {
            break;
        }

        vector<int> tight = tight_set(cur, S);
        DirectionResult dr = descent_direction(cur, tight);

        if (dr.dir.norm() < 1e-9L) {
            break;
        }

        if (dr.arc_circle == -1) {
            /*
                Vertical fall.

                Find the closest active circle boundary below the current point.
            */
            ld y_end = -1e18L;

            for (int i : S) {
                bool already_tight = false;

                for (int t : tight) {
                    if (t == i) {
                        already_tight = true;
                        break;
                    }
                }

                if (already_tight) {
                    continue;
                }

                ld dx = cur.x - xs[i];
                ld disc = ls[i] * ls[i] - dx * dx;

                if (disc < 0) {
                    continue;
                }

                ld y_boundary = -sqrtl(disc);

                if (y_boundary < cur.y - 1e-12L && y_boundary > y_end) {
                    y_end = y_boundary;
                }
            }

            // If no circle is hit, go directly to target y.
            if (y_end < -1e17L) {
                y_end = target.y;
            }

            // Avoid passing below the target if it is on the same vertical line.
            if (fabsl(cur.x - target.x) < 1e-9L && y_end < target.y - 1e-12L) {
                y_end = target.y;
            }

            ld len = cur.y - y_end;

            if (len < 1e-12L) {
                break;
            }

            Segment seg;
            seg.vertical = true;
            seg.x = cur.x;
            seg.y0 = cur.y;
            seg.y1 = y_end;
            seg.len = len;

            segments.push_back(seg);

            cur = Point(cur.x, y_end);
        } else {
            /*
                Move along one circle arc.
            */
            int circle = dr.arc_circle;

            ld theta0 = atan2l(cur.y, cur.x - xs[circle]);

            // Positive angular tangent.
            Point tangent(-sinl(theta0), cosl(theta0));

            // Choose angular direction that matches the descent direction.
            ld sign = tangent.dot(dr.dir) > 0 ? 1.0L : -1.0L;

            ld best_delta = 2 * PI;
            Point best_point = cur;
            bool found_event = false;

            // Event 1: intersection with another active circle.
            for (int j : S) {
                if (j == circle) {
                    continue;
                }

                vector<Point> inters = circle_intersections(circle, j);

                for (Point q : inters) {
                    ld theta_q = atan2l(q.y, q.x - xs[circle]);
                    ld delta = forward_angle(theta0, theta_q, sign);

                    if (delta < 1e-9L) {
                        continue;
                    }

                    if (delta < best_delta) {
                        best_delta = delta;
                        best_point = q;
                        found_event = true;
                    }
                }
            }

            // Event 2: bottom point of current circle.
            {
                ld theta_bottom = -PI / 2;
                ld delta = forward_angle(theta0, theta_bottom, sign);

                if (delta > 1e-9L && delta < best_delta) {
                    best_delta = delta;
                    best_point = Point(xs[circle], -ls[circle]);
                    found_event = true;
                }
            }

            if (!found_event) {
                break;
            }

            ld theta1 = theta0 + sign * best_delta;
            ld len = ls[circle] * best_delta;

            if (len < 1e-12L) {
                break;
            }

            Segment seg;
            seg.vertical = false;
            seg.cx = xs[circle];
            seg.r = ls[circle];
            seg.theta0 = theta0;
            seg.theta1 = theta1;
            seg.len = len;

            segments.push_back(seg);

            cur = best_point;
        }

        if ((cur - target).norm() < 1e-7L) {
            cur = target;
            break;
        }
    }

    return segments;
}

/*
    Returns the point after travelling distance s inside phase ph.
*/
Point interpolate(const Phase& ph, ld s) {
    if (s <= 0) {
        return ph.start_point;
    }

    if (s >= ph.total_len - 1e-12L) {
        return ph.end_point;
    }

    ld passed = 0;

    for (const Segment& seg : ph.segments) {
        if (s <= passed + seg.len + 1e-12L) {
            ld local = s - passed;
            ld ratio = local / seg.len;

            if (seg.vertical) {
                ld y = seg.y0 + (seg.y1 - seg.y0) * ratio;
                return Point(seg.x, y);
            } else {
                ld theta = seg.theta0 + (seg.theta1 - seg.theta0) * ratio;
                ld x = seg.cx + seg.r * cosl(theta);
                ld y = seg.r * sinl(theta);

                return Point(x, y);
            }
        }

        passed += seg.len;
    }

    return ph.end_point;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;

    xs.resize(n);
    ls.resize(n);

    for (int i = 0; i < n; i++) {
        cin >> xs[i];
    }

    for (int i = 0; i < n; i++) {
        cin >> ls[i];
    }

    cut_order.resize(n - 1);

    for (int i = 0; i < n - 1; i++) {
        cin >> cut_order[i];
        cut_order[i]--;
    }

    queries.resize(m);

    for (int i = 0; i < m; i++) {
        cin >> queries[i];
    }

    vector<int> active(n);
    iota(active.begin(), active.end(), 0);

    Point current = equilibrium(active);
    Point final_position = current;

    ld current_time = 0;

    vector<Phase> phases;

    /*
        Process all cuts and precompute all movement phases.
    */
    for (int cut : cut_order) {
        active.erase(find(active.begin(), active.end(), cut));

        Point next_equilibrium = equilibrium(active);

        if ((next_equilibrium - current).norm() < 1e-9L) {
            current = next_equilibrium;
            final_position = current;
            continue;
        }

        vector<Segment> segments = trace_path(current, next_equilibrium, active);

        ld total_len = 0;

        for (const Segment& seg : segments) {
            total_len += seg.len;
        }

        if (total_len < 1e-9L) {
            current = next_equilibrium;
            final_position = current;
            continue;
        }

        Phase ph;
        ph.start_time = current_time;
        ph.total_len = total_len;
        ph.start_point = current;
        ph.end_point = next_equilibrium;
        ph.segments = segments;

        phases.push_back(ph);

        current = next_equilibrium;
        final_position = current;
        current_time += total_len;
    }

    cout << fixed << setprecision(10);

    /*
        Answer queries.
    */
    for (ld t : queries) {
        Point answer = final_position;

        for (const Phase& ph : phases) {
            if (t <= ph.start_time + ph.total_len + 1e-9L) {
                ld s = t - ph.start_time;

                if (s < 0) {
                    s = 0;
                }

                if (s > ph.total_len) {
                    s = ph.total_len;
                }

                answer = interpolate(ph, s);
                break;
            }
        }

        cout << (double)answer.x << ' ' << (double)answer.y << '\n';
    }

    return 0;
}
```

---

## 5. Python implementation with detailed comments

```python
import sys
import math
from dataclasses import dataclass

EPS = 1e-12
PI = math.acos(-1.0)


@dataclass
class Point:
    x: float = 0.0
    y: float = 0.0

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    def __mul__(self, k):
        return Point(self.x * k, self.y * k)

    def __truediv__(self, k):
        return Point(self.x / k, self.y / k)

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def norm2(self):
        return self.x * self.x + self.y * self.y

    def norm(self):
        return math.sqrt(self.norm2())


@dataclass
class DirectionResult:
    dir: Point
    arc_circle: int


@dataclass
class Segment:
    vertical: bool

    # Vertical segment data.
    x: float = 0.0
    y0: float = 0.0
    y1: float = 0.0

    # Arc segment data.
    cx: float = 0.0
    r: float = 0.0
    theta0: float = 0.0
    theta1: float = 0.0

    length: float = 0.0


@dataclass
class Phase:
    start_time: float
    total_len: float
    start_point: Point
    end_point: Point
    segments: list


def inside_disks(p, active, xs, ls, tol=1e-7):
    """
    Check whether point p is inside every active disk.
    """
    for i in active:
        dx = p.x - xs[i]
        dy = p.y

        if dx * dx + dy * dy > ls[i] * ls[i] + tol:
            return False

    return True


def circle_intersections(i, j, xs, ls):
    """
    Return intersection points of circles i and j.

    Centers are (xs[i], 0), (xs[j], 0).
    Radii are ls[i], ls[j].
    """
    dx = xs[j] - xs[i]
    d = abs(dx)

    if d < 1e-14:
        return []

    r1 = ls[i]
    r2 = ls[j]

    if d > r1 + r2 + 1e-12:
        return []

    if d < abs(r1 - r2) - 1e-12:
        return []

    a = (r1 * r1 - r2 * r2 + d * d) / (2.0 * d)

    h2 = r1 * r1 - a * a

    if h2 < 0:
        h2 = 0.0

    h = math.sqrt(h2)

    sign = 1.0 if xs[j] > xs[i] else -1.0
    mx = xs[i] + sign * a

    return [
        Point(mx, h),
        Point(mx, -h)
    ]


def equilibrium(active, xs, ls):
    """
    Find the lowest feasible point in the intersection of active disks.
    """
    candidates = []

    # Bottom of each active circle.
    for i in active:
        candidates.append(Point(xs[i], -ls[i]))

    # Pairwise circle intersections.
    for a in range(len(active)):
        for b in range(a + 1, len(active)):
            candidates.extend(circle_intersections(active[a], active[b], xs, ls))

    best = Point(0.0, 1e18)

    for p in candidates:
        if inside_disks(p, active, xs, ls) and p.y < best.y:
            best = p

    return best


def tight_set(p, active, xs, ls):
    """
    Return active ropes that are tight at point p.
    """
    tight = []

    for i in active:
        dx = p.x - xs[i]
        dy = p.y
        d = math.sqrt(dx * dx + dy * dy)

        if abs(d - ls[i]) < 1e-6:
            tight.append(i)

    return tight


def descent_direction(p, tight, xs, ls):
    """
    Compute the steepest feasible downward direction.

    Gravity direction is g = (0, -1).
    For every tight rope with outward normal n,
    feasible velocity d must satisfy:
        d dot n <= 0
    """
    g = Point(0.0, -1.0)

    if not tight:
        return DirectionResult(g, -1)

    normals = []

    for i in tight:
        r = Point(p.x - xs[i], p.y)
        length = r.norm()

        if length < 1e-14:
            normals.append(Point(0.0, -1.0))
        else:
            normals.append(r / length)

    # Check whether straight downward movement is feasible.
    gravity_ok = True

    for normal in normals:
        if g.dot(normal) > 1e-9:
            gravity_ok = False
            break

    if gravity_ok:
        tangent_circle = -1

        # If gravity is tangent to a tight circle, remember it.
        for k, normal in enumerate(normals):
            if abs(g.dot(normal)) < 1e-9:
                tangent_circle = tight[k]
                break

        return DirectionResult(g, tangent_circle)

    found = False
    best_dir = Point(0.0, 1.0)
    best_circle = -1

    # Try sliding along each tight circle.
    for k, normal in enumerate(normals):
        gn = g.dot(normal)

        # Projection of gravity onto tangent line.
        d = g - normal * gn
        length = d.norm()

        if length < 1e-14:
            continue

        d = d / length

        # Direction must go downward.
        if d.y >= -1e-12:
            continue

        # Direction must not violate other tight constraints.
        ok = True

        for j, other_normal in enumerate(normals):
            if j == k:
                continue

            if d.dot(other_normal) > 1e-9:
                ok = False
                break

        if not ok:
            continue

        # Pick steepest downward direction.
        if not found or d.y < best_dir.y:
            found = True
            best_dir = d
            best_circle = tight[k]

    if not found:
        return DirectionResult(Point(0.0, 0.0), -1)

    return DirectionResult(best_dir, best_circle)


def forward_angle(frm, to, sign):
    """
    Angular distance from frm to to while moving in angular direction sign.

    sign = +1 means increasing angle.
    sign = -1 means decreasing angle.
    """
    two_pi = 2.0 * PI

    delta = sign * (to - frm)
    delta = math.fmod(delta, two_pi)

    if delta < 0:
        delta += two_pi

    return delta


def trace_path(start, target, active, xs, ls):
    """
    Build the trajectory from start to target.

    The path consists of vertical segments and circular arcs.
    """
    segments = []
    cur = start

    for _ in range(20000):
        if (cur - target).norm() < 1e-9:
            break

        tight = tight_set(cur, active, xs, ls)
        dr = descent_direction(cur, tight, xs, ls)

        if dr.dir.norm() < 1e-9:
            break

        if dr.arc_circle == -1:
            # Vertical fall.
            y_end = -1e18

            for i in active:
                if i in tight:
                    continue

                dx = cur.x - xs[i]
                disc = ls[i] * ls[i] - dx * dx

                if disc < 0:
                    continue

                y_boundary = -math.sqrt(disc)

                # We need the closest boundary below current point.
                if y_boundary < cur.y - 1e-12 and y_boundary > y_end:
                    y_end = y_boundary

            # If no circle boundary is hit, go to target.
            if y_end < -1e17:
                y_end = target.y

            # Avoid passing below target if it is on same vertical line.
            if abs(cur.x - target.x) < 1e-9 and y_end < target.y - 1e-12:
                y_end = target.y

            length = cur.y - y_end

            if length < 1e-12:
                break

            segments.append(Segment(
                vertical=True,
                x=cur.x,
                y0=cur.y,
                y1=y_end,
                length=length
            ))

            cur = Point(cur.x, y_end)

        else:
            # Circular arc movement.
            circle = dr.arc_circle

            theta0 = math.atan2(cur.y, cur.x - xs[circle])

            # Tangent direction for increasing angle.
            tangent = Point(-math.sin(theta0), math.cos(theta0))

            # Choose angular direction that matches descent direction.
            sign = 1.0 if tangent.dot(dr.dir) > 0 else -1.0

            best_delta = 2.0 * PI
            best_point = cur
            found_event = False

            # Event: intersection with another active circle.
            for j in active:
                if j == circle:
                    continue

                for q in circle_intersections(circle, j, xs, ls):
                    theta_q = math.atan2(q.y, q.x - xs[circle])
                    delta = forward_angle(theta0, theta_q, sign)

                    if delta < 1e-9:
                        continue

                    if delta < best_delta:
                        best_delta = delta
                        best_point = q
                        found_event = True

            # Event: bottom of current circle.
            theta_bottom = -PI / 2.0
            delta = forward_angle(theta0, theta_bottom, sign)

            if delta > 1e-9 and delta < best_delta:
                best_delta = delta
                best_point = Point(xs[circle], -ls[circle])
                found_event = True

            if not found_event:
                break

            theta1 = theta0 + sign * best_delta
            length = ls[circle] * best_delta

            if length < 1e-12:
                break

            segments.append(Segment(
                vertical=False,
                cx=xs[circle],
                r=ls[circle],
                theta0=theta0,
                theta1=theta1,
                length=length
            ))

            cur = best_point

        if (cur - target).norm() < 1e-7:
            cur = target
            break

    return segments


def interpolate(phase, s):
    """
    Return ball position after travelling distance s inside phase.
    """
    if s <= 0:
        return phase.start_point

    if s >= phase.total_len - 1e-12:
        return phase.end_point

    passed = 0.0

    for seg in phase.segments:
        if s <= passed + seg.length + 1e-12:
            local = s - passed
            ratio = local / seg.length

            if seg.vertical:
                y = seg.y0 + (seg.y1 - seg.y0) * ratio
                return Point(seg.x, y)
            else:
                theta = seg.theta0 + (seg.theta1 - seg.theta0) * ratio
                x = seg.cx + seg.r * math.cos(theta)
                y = seg.r * math.sin(theta)

                return Point(x, y)

        passed += seg.length

    return phase.end_point


def solve():
    data = sys.stdin.read().strip().split()

    if not data:
        return

    ptr = 0

    n = int(data[ptr])
    ptr += 1

    m = int(data[ptr])
    ptr += 1

    xs = [float(data[ptr + i]) for i in range(n)]
    ptr += n

    ls = [float(data[ptr + i]) for i in range(n)]
    ptr += n

    cut_order = [int(data[ptr + i]) - 1 for i in range(n - 1)]
    ptr += n - 1

    queries = [float(data[ptr + i]) for i in range(m)]

    active = list(range(n))

    current = equilibrium(active, xs, ls)
    final_position = current

    current_time = 0.0
    phases = []

    # Process cuts and precompute motion phases.
    for cut in cut_order:
        active.remove(cut)

        next_equilibrium = equilibrium(active, xs, ls)

        # No movement after this cut.
        if (next_equilibrium - current).norm() < 1e-9:
            current = next_equilibrium
            final_position = current
            continue

        segments = trace_path(current, next_equilibrium, active, xs, ls)
        total_len = sum(seg.length for seg in segments)

        if total_len < 1e-9:
            current = next_equilibrium
            final_position = current
            continue

        phases.append(Phase(
            start_time=current_time,
            total_len=total_len,
            start_point=current,
            end_point=next_equilibrium,
            segments=segments
        ))

        current = next_equilibrium
        final_position = current
        current_time += total_len

    output = []

    # Answer each query.
    for t in queries:
        answer = final_position

        for phase in phases:
            if t <= phase.start_time + phase.total_len + 1e-9:
                s = t - phase.start_time

                if s < 0:
                    s = 0.0

                if s > phase.total_len:
                    s = phase.total_len

                answer = interpolate(phase, s)
                break

        output.append(f"{answer.x:.10f} {answer.y:.10f}")

    sys.stdout.write("\n".join(output))


if __name__ == "__main__":
    solve()
```