Problem:
Problem F:
Canal: Water Going Up and Down
ACM国には中央を東西に流れる川がある．この川は西の隣国からACM国を通り東の隣国へと流れており，ACM国内の全長は
K
kmである．この川にいくつかの閘門を設置し，運河として利用することが計画されている．
閘門とは，異なる2つの水位間を船が移動するための仕組みである．閘門は上流側と下流側にそれぞれ水門を持ち，それらの間に閘室と呼ばれる小さな水域を持つ．この閘室に船を入れた後に注水あるいは排水を行い，閘室の水位を上下させることで船も上下させる．以下にその模式図を示す．
図 F-1: 閘門の模式図
この川の川幅はあまり広くないため，西から東へ一方通行の運河となることが決まっている．設計の担当者は，運河を効率良く運用するため，予想される船の航行スケジュールに合わせて閘門の設置場所などを最適にしたいと考えている．
あなたは設計担当者に雇われているプログラマーである．あなたの仕事は，閘門の情報と複数の船の航行スケジュールが与えられたとき，全ての船が川を通過するまでの時間をシミュレーションにより求めるプログラムを書くことである．
各閘門は以下の情報によって表される．
ACM国西端からの距離
X
(km)
水位の切り替えに必要な水の容積
L
(L)
単位時間あたりの最大注水量
F
(L/h)
単位時間あたりの最大排水量
D
(L/h)
閘門の西側の水位と東側の水位の上下関係
便宜上，シミュレーションにおいて，川はACM国外においても同様に無限に続いているものとする．
シミュレーションの開始時点において，全ての閘室の水位は東側と西側の水位のうち，低い方にある．また，航行スケジュールに含まれる船は，ACM国の西端を先頭地点として，入力で与えられる順に東から西に向かって1kmおきに並んでいるものとする． 便宜上，先頭の船の初期位置を0km地点とする．
シミュレーション開始とともに船は東に向かって航行を始める．このとき，ある船の前後1km未満に他の船が入ってはならない．
各船にはそれぞれ最大船速
V
(km/h)が設定されている．船は一瞬で任意の船速に達し，さらに一瞬で静止することすらできる．基本的に船は最大船速で航行するが，先行する船より後続の船のほうが最大船速が速く，かつ後続の船が先行する船の1km手前に追いついた場合は，後続の船は先行する船と同じ船速で航行する．船及び閘門の大きさは無視できるものとする．
船は，閘門の西側の水位と閘室の水位が等しいときのみ，その閘門に入ることができる．同様に，閘門の東側の水位と閘室の水位が等しいときのみ，その閘門から出ることができる．各閘室の水位は，中に船がいない場合は，その閘門の西側の水位と一致するまで上昇または下降する．また，船がいる場合は，その閘門の東側の水位と一致するまで変位する．閘門の丁度1km先で船が停泊している場合でも，船は閘門から出ることができる．ただし，このとき，船は先行する船が発進するまで閘門から出たところで停泊しなければならない．
船はACM国の東端を通過した後，可能な限りの速度で無限遠まで航行する．全ての船がACM国の東端を通過し終えた時点でシミュレーションは終了する．
Input
入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．
N
M
K
X
1
L
1
F
1
D
1
UD
1
X
2
L
2
F
2
D
2
UD
2
...
X
N
L
N
F
N
D
N
UD
N
V
1
V
2
...
V
M
最初の1行は3つの整数
N
,
M
,
K
からなる．
N
(1 ≤
N
≤ 100) は閘門の数，
M
(1 ≤
M
≤ 100) は船の数，
K
(2 ≤
K
≤ 1000) は川のACM国内における全長をそれぞれ表す．
続く
N
行は閘門の情報を表す． 各行は5つの整数
X
i
,
L
i
,
F
i
,
D
i
,
UD
i
からなる．
X
i
(1 ≤
X
i
≤
K
- 1) は閘門
i
のACM国西端からの位置(km)，
L
i
(1 ≤
L
i
≤ 1000) は閘門
i
の水位の切り替えに必要な水の容積(L)，
F
i
(1 ≤
F
i
≤ 1000) は閘門
i
の単位時間あたりの最大注水量(L/h)，
D
i
(1 ≤
D
i
≤ 1000) は閘門
i
の単位時間あたりの最大排水量(L/h)，
UD
i
(
UD
i
∈ {0, 1})は閘門
i
の西側の水位と東側の水位の上下関係をそれぞれ表す．
UD
i
が 0 の場合，閘門
i
は西側より東側が水位が高いことを表す．一方
UD
i
が 1 の場合，閘門
i
は西側より東側が水位が低いことを表す．
続く
M
行には，各行に
i
番目の船の最大船速(km/h)を表す整数
V
i
(1 ≤
V
i
≤ 1000) が与えられる．
閘門は
X
i
の値の小さい順で与えられる．また，同一の位置に複数の閘門が設置されることはない．
入力の終りはスペースで区切られた3個のゼロからなる．
Output
各データセットに対し，シミュレーション開始から終了までの時刻を1行で出力せよ．出力する値は10
-6
以下の誤差を含んでいても構わない．値は小数点以下何桁表示しても構わない．
Sample Input
1 1 100
50 200 20 40 0
1
2 4 100
7 4 1 4 1
19 5 1 4 0
5
3
7
9
1 2 3
1 1 1 1 0
1
3
1 2 10
5 10 1 1 1
2
3
0 0 0
Output for the Sample Input
110
46.6666666667
5
41.6666666667

Submitted solutions:

code_snippet: /*	author:  Kite_kuma
	created: 2022.03.03 02:02:13 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &number_of_ships) {
	std::cerr << "{\n";
	for(const auto &t : number_of_ships) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &number_of_ships) {
	std::cerr << "{\n";
	for(const auto &t : number_of_ships) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

struct gate {
	double x;
	double water;
	double fill;
	double reduce;
	double left_height;
	double right_height;
	gate(double x, double water, double fill, double reduce, double lh, double rh)
		: x(x), water(water), fill(fill), reduce(reduce), left_height(lh), right_height(rh) {}
};

const double eps = 1e-8;
bool eq(double a, double b) { return abs(a - b) < eps; }

double solve(int gate_number) {
	int number_of_ships;
	double goal;
	cin >> number_of_ships >> goal;

	V<gate> gates;
	rep(gate_number) {
		DBL(x, water, fill, reduce);
		bool lft;
		cin >> lft;
		double lh, rh;
		lh = rh = 0;
		if(lft)
			lh = water;
		else
			rh = water;
		gate g(x, water, fill, reduce, lh, rh);
		debug(x, water, fill, reduce, lh, rh);
		gates.push_back(g);
	}

	VEC(double, maxspeed, number_of_ships);

	V<double> place(number_of_ships);
	rep(i, number_of_ships) place[i] = -i;
	vector<double> water(gate_number, 0.);
	vector<int> gate_to_ship(gate_number, -1);
	vector<int> ship_to_gate(number_of_ships, -1);
	vector<int> gate_next(number_of_ships, 0);
	V<double> velocity(number_of_ships);

	auto preceed_time = [&](const double time_span) {
		rep(i, number_of_ships) place[i] += velocity[i] * time_span;
		rep(j, gate_number) {
			const gate &g = gates[j];
			if(gate_to_ship[j] == -1) {	 // switched to left
				if(g.left_height < g.right_height) water[j] -= time_span * g.reduce;
				// water[j] = min(g.right_height, water[j] + g.fill * time_span);
				else
					water[j] += time_span * g.fill;
				// water[j] = max(g.right_height, water[j] - g.reduce * time_span);
			} else {
				if(g.left_height < g.right_height) water[j] += time_span * g.fill;
				// water[j] = max(g.left_height, water[j] - g.reduce * time_span);
				else
					water[j] -= time_span * g.reduce;
				// water[j] = min(g.left_height, water[j] + g.fill * time_span);
				// water[j] += g.fill * time_span;
			}
			chmax(water[j], 0.);
			chmin(water[j], g.water);
		}
		rep(shipid, number_of_ships) {
			if(ship_to_gate[shipid] == -1) {
				const int nxtid = gate_next[shipid];
				if(nxtid < gate_number) {
					const gate &gt = gates[nxtid];
					debug(gt.x, place[shipid]);
					if(eq(gt.x, place[shipid])) {
						if(eq(gt.left_height, water[nxtid])) {
							ship_to_gate[shipid] = nxtid;
							gate_to_ship[nxtid] = shipid;
							velocity[shipid] = 0;
						}
					}
				}
			} else {
				const int gateid = ship_to_gate[shipid];
				assert(in_range(gateid, 0, gate_number));
				const gate &g = gates[gateid];
				if(eq(g.right_height, water[gateid])) {
					gate_next[shipid]++;
					ship_to_gate[shipid] = -1;
					gate_to_ship[gateid] = -1;
				}
			}
		}

		rep(shipid, number_of_ships) {
			double &vel = velocity[shipid];

			if(ship_to_gate[shipid] != -1)
				vel = 0;
			else {
				if(shipid) {
					double dist = place[shipid - 1] - place[shipid];
					vel = (eq(dist, 1.) ? min(maxspeed[shipid], velocity[shipid - 1]) : maxspeed[shipid]);
				} else {
					vel = maxspeed[shipid];
				}
			}

			const int nxtgateid = gate_next[shipid];
			if(nxtgateid < gate_number) {
				const auto &gt = gates[nxtgateid];
				if(eq(gt.x, place[shipid])) vel = 0;
			}
		}

		return;
	};

	preceed_time(0.);

	double time = 0;
	auto nxt_incident = [&]() {
		double ret = INF;
		// if(eps < velocity.back()) {
		// 	chmin(ret, (goal - place.back()) / velocity.back());
		// }

		if(gate_next.back() == gate_number)
			if(chmin(ret, (goal - place.back()) / velocity.back())) {
				debug(ret);
				// debug("end is coming!");
			}

		rep(shipid, number_of_ships) {
			const double &vel = velocity[shipid];
			const double &plc = place[shipid];
			if(shipid) {
				double dist = place[shipid - 1] - plc - 1.;
				assert(dist > -eps);
				double vel_diff = vel - velocity[shipid - 1];
				if(vel_diff > eps) {
					if(chmin(ret, dist / vel_diff)) {
						debug(ret);
					}
				}
			}
			if(ship_to_gate[shipid] != -1) continue;
			int nxtgateid = gate_next[shipid];
			if(nxtgateid < gate_number) {
				const double dist = gates[nxtgateid].x - place[shipid];
				if(!eq(dist, 0.))
					if(chmin(ret, dist / vel)) {
						debug(ret);
						debug(dist, vel);
						if(ret < eps) exit(0);
					}
			}
		}
		rep(gateid, gate_number) {
			double watercap, fill, reduce;
			const auto &g = gates[gateid];
			watercap = g.water;
			fill = g.fill;
			reduce = g.reduce;

			if(gate_to_ship[gateid] == -1 && !eq(g.left_height, water[gateid])) {
				double chg = g.fill;
				if(g.left_height < g.right_height) chg = g.reduce;
				double diff = abs(g.left_height - water[gateid]);
				if(chmin(ret, diff / chg)) {
					debug(ret);
				}
			}
			if(gate_to_ship[gateid] != -1 && !eq(g.right_height, water[gateid])) {
				// chmin(ret, (watercap - water[gateid]) / fill);
				double chg = g.fill;
				if(g.left_height > g.right_height) chg = g.reduce;
				double diff = abs(g.right_height - water[gateid]);
				if(chmin(ret, diff / chg)) {
					debug(ret);
				}
			}
		}
		return ret;
	};

	while(place.back() < goal - eps) {
		double timelen = nxt_incident();
		preceed_time(timelen);
		time += timelen;
		debug(place, time);
		debug(velocity);
		debug(ship_to_gate);
		debug(gate_to_ship);
		debug(gate_next);
		debug(water);

		const gate &g = gates.front();
		debug(g.x, g.water, g.left_height, g.right_height, g.reduce, g.fill);
	}

	return time;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	int n;
	// cin >> n;
	while(cin >> n && n) {
		cout << solve(n) << dl;
	}

	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3624
final_rank: 5

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;

#define EPS 0.0000001
#define NUM 105

enum Type{
	CATCH_UP,
	ARRIVE_ROOM,
	WATER_UP,
	WATER_DOWN,
	FINISH,
};

enum Water{
	West,
	East,
	Moving,
};

struct Info{
	void set(double arg_loc,double arg_down_time,double arg_up_time,bool arg_is_east_higher){
		loc = arg_loc;
		down_time = arg_down_time;
		up_time = arg_up_time;
		is_east_higher = arg_is_east_higher;
	}
	double loc,down_time,up_time,move_end_time;
	bool is_east_higher;
	int wait_ship_id;
	Water water,next_water;
};

struct Ship{
	void set(double arg_current_loc,int arg_max_speed,int arg_current_speed){
		current_loc = arg_current_loc;
		max_speed = arg_max_speed;
		current_speed = arg_current_speed;
	}
	double current_loc;
	bool is_waiting;
	int last_room,max_speed,current_speed;
};

struct Data{
	Data(){
		event_time = 0;
		ship_id = 0;
		room_id = 0;
		type = CATCH_UP;
	}
	Data(double arg_event_time,int arg_ship_id,int arg_room_id,Type arg_type){
		event_time = arg_event_time;
		ship_id = arg_ship_id;
		room_id = arg_room_id;
		type = arg_type;
	}
	bool operator<(const struct Data &arg) const{
		return event_time > arg.event_time;
	}
	double event_time;
	int ship_id,room_id;
	Type type;
};

int num_room,num_ship;
int debug_array[NUM];
double LENGTH;
Info info[NUM];
Ship ship[NUM];

void set_speed(int ship_head){

	//★前の船との距離がちょうど1kmで、1つ前の航行速度より最大速度が速いなら、1つ前のスピードに合わせる
	for(int i = ship_head+1; i < num_ship; i++){

		if(ship[i].is_waiting)continue; //閘門の中ならSKIP

		if(ship[i-1].current_loc-ship[i].current_loc > 1.0){ //距離が1より大きい

			ship[i].current_speed = ship[i].max_speed;
			continue;
		}

		//距離がちょうど1
		if(ship[i].max_speed > ship[i-1].current_speed){

			ship[i].current_speed = ship[i-1].current_speed;
		}else{

			ship[i].current_speed = ship[i].max_speed;
		}
	}
}

void calc_loc(int ship_head,double add_time){

	for(int i = ship_head; i < num_ship; i++){
		ship[i].current_loc += ship[i].current_speed*add_time;
	}
}

//ある船が、ある閘門に到着するまでの時間を求める
double calc_time(int ship_id,int room_id){

	double dist = info[room_id].loc-ship[ship_id].current_loc;
	return dist/(double)ship[ship_id].current_speed;
}

void func(){

	double X,L,F,D;
	int UD;

	double first_time = BIG_NUM;
	Type first_event = ARRIVE_ROOM;
	int first_ship,first_room;

	//閘門の情報を取得
	for(int i = 0; i < num_room; i++){

		scanf("%lf %lf %lf %lf %d",&X,&L,&F,&D,&UD);
		info[i].set(X,L/D,L/F,UD == 0);

		//シミュレーションの開始時点において、水位は低い方に合っている
		if(info[i].is_east_higher){
			info[i].water = West;
		}else{
			//★★★西側の水位に合わせる★★★
			info[i].water = Moving;
			info[i].next_water = West;
			info[i].move_end_time = info[i].up_time;
			if(first_time > info[i].up_time){
				first_time = info[i].up_time;
				first_event = WATER_UP;
				first_ship = -1;
				first_room = i;
			}
		}
		info[i].wait_ship_id = -1; //★待っている船があれば、そのidを持つ★
	}
	info[num_room].loc = LENGTH; //★時間計算簡易化のため★

	int tmp_speed;

	//船の情報を取得
	for(int i = 0; i < num_ship; i++){

		scanf("%d",&tmp_speed);
		ship[i].set(-1*i,tmp_speed,tmp_speed);
		ship[i].last_room = -1; //最後に通過した閘門のインデックス
		ship[i].is_waiting = false;
		debug_array[i] = 0;
	}

	int tmp_id,next_ship,next_room;
	double ans = BIG_NUM;
	double tmp_time;

	Type next_type;

	//★最初は1km等間隔に並んでいるため、まず船の速度を設定する★
	set_speed(0);

	/*★★船の速度が変化するイベントは、前のものが終わるまで、次のものをpushしない★★*/

	priority_queue<Data> Q;

	if(first_event == ARRIVE_ROOM){

		Q.push(Data(calc_time(0,0),0,0,ARRIVE_ROOM)); //全ての閘門の水位が西に合っているなら、先頭の船のイベントを追加
	}else{

		tmp_time = calc_time(0,0);

		if(tmp_time < first_time){

			Q.push(Data(tmp_time,0,0,ARRIVE_ROOM));
		}else{

			Q.push(Data(first_time,first_ship,first_room,first_event));
		}
	}

	Data data;
	double current_time,pre_time = 0,next_time;
	int ship_head = 0;

	while(true){

		data = Q.top();
		Q.pop();

		current_time = Q.top().event_time;
		//★★船全体を動かす★★
		if(fabs(current_time-pre_time) > EPS){
			calc_loc(0,current_time-pre_time);
		}

		switch(data.type){
		case CATCH_UP: //ある船が別の船の1km後方に到達した場合

			ship[data.ship_id].current_speed = ship[data.ship_id-1].current_speed;
			set_speed(data.ship_id); //影響を後ろに伝播させる

			break;

		case ARRIVE_ROOM: //ある船がある閘門に到達した場合

			//閘門の中ではspeed0とする
			ship[data.ship_id].current_speed = 0;
			ship[data.ship_id].is_waiting = true;
			//自分以降の船に、停止情報を伝える
			set_speed(data.ship_id);

			info[data.room_id].wait_ship_id = data.ship_id; //★とりあえず待つ★

			if(info[data.room_id].water == West){ //水位が西側に合っている場合のみ中に入る

				if(info[data.room_id].is_east_higher){

					info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
				}else{
					info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
				}
				info[data.room_id].water = Moving;
				info[data.room_id].next_water = East;
			}

			break;

		case WATER_UP:

			if(info[data.room_id].is_east_higher){ //東の方が水位が高い場合

				//★基本的に閘門の水位は西側に合わせるので、必ず船がいるはず
				tmp_id = info[data.room_id].wait_ship_id;
				ship[tmp_id].last_room = data.room_id; //通過済とする
				ship[tmp_id].is_waiting = false;
				debug_array[tmp_id]++;
				info[data.room_id].wait_ship_id = -1;

				//★閘門を通過した船の速度を設定する
				if(tmp_id == 0){

					ship[tmp_id].current_speed = ship[tmp_id].max_speed;
					set_speed(tmp_id); //影響を伝播させる

				}else{ //自分が先頭でないなら、自分の1つ前から計算すれば良い

					set_speed(tmp_id-1);
				}

				//閘門の水位が動き終わる時刻等を設定
				info[data.room_id].water = Moving;
				info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
				info[data.room_id].next_water = West;

			}else{ //西側の方が水位が高い場合(★船は中にいないが、手前で待っている場合あり★)

				info[data.room_id].water = West;
				if(info[data.room_id].wait_ship_id != -1){ //水位の変動を待っている船がいる場合

					info[data.room_id].water = Moving;
					info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
					info[data.room_id].next_water = East;
				}
			}
			break;
		case WATER_DOWN:

			if(info[data.room_id].is_east_higher){ //東の方が水位が高い場合(★船は中にいないが、手前で待っている場合あり★)

				info[data.room_id].water = West;
				if(info[data.room_id].wait_ship_id != -1){ //水位の変動を待っている船がいる場合
					info[data.room_id].water = Moving;
					info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
					info[data.room_id].next_water = East;
				}

			}else{ //西側の方が水位が高い場合

				//★基本的に閘門の水位は西側に合わせるので、必ず船がいるはず
				tmp_id = info[data.room_id].wait_ship_id;
				ship[tmp_id].last_room = data.room_id; //通過済とする
				ship[tmp_id].is_waiting = false;
				info[data.room_id].wait_ship_id = -1;
				debug_array[tmp_id]++;

				//★閘門を通過した船の速度を設定する:仮に自分が先頭でないなら、自分の1つ前から計算すれば良い★
				if(tmp_id == 0){

					ship[tmp_id].current_speed = ship[tmp_id].max_speed;
					set_speed(tmp_id); //影響を伝播させる

				}else{

					set_speed(tmp_id-1);
				}

				//閘門の水位が動き終わる時刻等を設定
				info[data.room_id].water = Moving;
				info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
				info[data.room_id].next_water = West;
			}

			break;
		case FINISH: //ある船が川を抜けた場合

			ans = current_time;

			ship_head++;
			break;
		}

		if(ship_head == num_ship)break;

		/*★★★最も早く起こる、次のイベントを計算★★★*/
		next_time = BIG_NUM;

		//船を走査
		for(int i = 0; i < num_ship; i++){

			if(fabs(ship[i].current_speed) < EPS){ //★閘門前、または前が詰まっているために待ち状態ならSKIP

				//★★★ぴったり、閘門の前で止まっている場合あり★★★
				if(fabs(ship[i].current_loc-info[ship[i].last_room+1].loc) < EPS && ship[i].is_waiting == false){

					next_time = current_time; //現在なので必ず最速
					next_ship = i;
					next_room = ship[i].last_room+1;
					next_type = ARRIVE_ROOM;
					break;
				}

			}else{

				//★1つ前の船の1km手前に追いつく時刻
				if(i != 0 && ship[i].current_speed > ship[i-1].current_speed){

					tmp_time = current_time+((ship[i-1].current_loc-ship[i].current_loc)-1.0)/(double)(ship[i].current_speed-ship[i-1].current_speed);

					if(next_time > tmp_time){

						if(fabs(next_time-tmp_time) < EPS){
							next_time = current_time;
							break;
						}else{
							next_time = tmp_time;
						}

						next_ship = i;
						next_room = -1;
						next_type = CATCH_UP;
					}
				}

				if(i < ship_head || fabs(ship[i].current_speed) < EPS)continue;

				//★閘門に到達する時刻
				if(fabs(ship[i].current_loc-info[ship[i].last_room+1].loc) < EPS){

					tmp_time = current_time;

				}else{

					tmp_time = current_time+calc_time(i,ship[i].last_room+1);
				}

				if(ship[i].last_room+1 == num_room){ //次で川を出る場合

					if(next_time > tmp_time){
						next_time = tmp_time;
						next_ship = i;
						next_room = ship[i].last_room+1;
						next_type =  FINISH;
					}

				}else{

					if(next_time > tmp_time){
						next_time = tmp_time;
						next_ship = i;
						next_room = ship[i].last_room+1;
						next_type =  ARRIVE_ROOM;
					}
				}
			}
		}

		//閘門を走査
		for(int i = 0; i < num_room; i++){

			if(info[i].water != Moving)continue;

			if(next_time > info[i].move_end_time){

				next_time = info[i].move_end_time;
				next_room = i;
				next_ship = -1;

				if(info[i].is_east_higher){

					if(info[i].next_water == West){
						next_type = WATER_DOWN;
					}else{
						next_type = WATER_UP;
					}
				}else{ //西の方が水位が高い

					if(info[i].next_water == West){
						next_type = WATER_UP;
					}else{
						next_type = WATER_DOWN;
					}
				}
			}
		}

		Q.push(Data(next_time,next_ship,next_room,next_type));

		pre_time = current_time;
	}

	printf("%.10lf\n",ans);
}

int main(){

	while(true){
		scanf("%d %d %lf",&num_room,&num_ship,&LENGTH);
		if(num_room == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 3176
final_rank: 9

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;

#define EPS 0.0000001
#define NUM 105

enum Type{
	CATCH_UP,
	ARRIVE_ROOM,
	WATER_UP,
	WATER_DOWN,
	FINISH,
};

enum Water{
	West,
	East,
	Moving,
};

struct Info{
	void set(double arg_loc,double arg_down_time,double arg_up_time,bool arg_is_east_higher){
		loc = arg_loc;
		down_time = arg_down_time;
		up_time = arg_up_time;
		is_east_higher = arg_is_east_higher;
	}
	double loc,down_time,up_time,move_end_time;
	bool is_east_higher;
	int wait_ship_id;
	Water water,next_water;
};

struct Ship{
	void set(double arg_current_loc,int arg_max_speed,int arg_current_speed){
		current_loc = arg_current_loc;
		max_speed = arg_max_speed;
		current_speed = arg_current_speed;
	}
	double current_loc;
	bool is_waiting;
	int last_room,max_speed,current_speed;
};

struct Data{
	Data(){
		event_time = 0;
		ship_id = 0;
		room_id = 0;
		type = CATCH_UP;
	}
	Data(double arg_event_time,int arg_ship_id,int arg_room_id,Type arg_type){
		event_time = arg_event_time;
		ship_id = arg_ship_id;
		room_id = arg_room_id;
		type = arg_type;
	}
	bool operator<(const struct Data &arg) const{
		return event_time > arg.event_time;
	}
	double event_time;
	int ship_id,room_id;
	Type type;
};

int num_room,num_ship;
int debug_array[NUM];
double LENGTH;
Info info[NUM];
Ship ship[NUM];

void set_speed(int ship_head){

	//★前の船との距離がちょうど1kmで、1つ前の航行速度より最大速度が速いなら、1つ前のスピードに合わせる
	for(int i = ship_head+1; i < num_ship; i++){

		if(ship[i].is_waiting)continue; //閘門の中ならSKIP

		if(ship[i-1].current_loc-ship[i].current_loc > 1.0){ //距離が1より大きい

			ship[i].current_speed = ship[i].max_speed;
			continue;
		}

		//距離がちょうど1
		if(ship[i].max_speed > ship[i-1].current_speed){

			ship[i].current_speed = ship[i-1].current_speed;
		}else{

			ship[i].current_speed = ship[i].max_speed;
		}
	}
}

void calc_loc(int ship_head,double add_time){

	for(int i = ship_head; i < num_ship; i++){
		ship[i].current_loc += ship[i].current_speed*add_time;
	}
}

//ある船が、ある閘門に到着するまでの時間を求める
double calc_time(int ship_id,int room_id){

	double dist = info[room_id].loc-ship[ship_id].current_loc;
	return dist/(double)ship[ship_id].current_speed;
}

bool STOP = false;
int num_case = 0;
void func(){

	double X,L,F,D;
	int UD;

	double first_time = BIG_NUM;
	Type first_event = ARRIVE_ROOM;
	int first_ship,first_room;

	//閘門の情報を取得
	for(int i = 0; i < num_room; i++){

		scanf("%lf %lf %lf %lf %d",&X,&L,&F,&D,&UD);
		info[i].set(X,L/D,L/F,UD == 0);

		//シミュレーションの開始時点において、水位は低い方に合っている
		if(info[i].is_east_higher){
			info[i].water = West;
		}else{
			//★★★西側の水位に合わせる★★★
			info[i].water = Moving;
			info[i].next_water = West;
			info[i].move_end_time = info[i].up_time;
			if(first_time > info[i].up_time){
				first_time = info[i].up_time;
				first_event = WATER_UP;
				first_ship = -1;
				first_room = i;
			}
		}
		info[i].wait_ship_id = -1; //★待っている船があれば、そのidを持つ★
	}
	info[num_room].loc = LENGTH; //★時間計算簡易化のため★

	int tmp_speed;

	//船の情報を取得
	for(int i = 0; i < num_ship; i++){

		scanf("%d",&tmp_speed);
		ship[i].set(-1*i,tmp_speed,tmp_speed);
		ship[i].last_room = -1; //最後に通過した閘門のインデックス
		ship[i].is_waiting = false;
		debug_array[i] = 0;
	}

	int tmp_id,next_ship,next_room;
	double ans = BIG_NUM;
	double tmp_time;

	Type next_type;

	//★最初は1km等間隔に並んでいるため、まず船の速度を設定する★
	set_speed(0);

	/*★★船の速度が変化するイベントは、前のものが終わるまで、次のものをpushしない★★*/

	priority_queue<Data> Q;

	if(first_event == ARRIVE_ROOM){

		Q.push(Data(calc_time(0,0),0,0,ARRIVE_ROOM)); //全ての閘門の水位が西に合っているなら、先頭の船のイベントを追加
	}else{

		tmp_time = calc_time(0,0);

		if(tmp_time < first_time){

			Q.push(Data(tmp_time,0,0,ARRIVE_ROOM));
		}else{

			Q.push(Data(first_time,first_ship,first_room,first_event));
		}
	}

	Data data;
	double current_time,pre_time = 0,next_time;
	int ship_head = 0;

	//int debug = 0;

	while(true){
		/*debug++;
		if(debug == 1000000){
			printf("LOOP!!\n");
			printf("case:%d\n",num_case);
			STOP = true;
			return;
		}
*/
		data = Q.top();
		Q.pop();

		current_time = Q.top().event_time;
		//★★船全体を動かす★★
		if(fabs(current_time-pre_time) > EPS){
			calc_loc(0,current_time-pre_time);
		}

		/*if(fabs(current_time-pre_time) > EPS && fabs(current_time-pre_time) < 0.001-EPS){
			printf("diff:%.10lf\n",fabs(current_time-pre_time));
			return;
		}

		printf("\ncurrent_time:%.3lf head_ship:%d\n",current_time,ship_head);*/

		/*if(fabs(current_time-BIG_NUM) < EPS){
			printf("強制終了\n");
			printf("case:%d\n",num_case);
			STOP = true;
			return;
		}*/

		switch(data.type){
		case CATCH_UP: //ある船が別の船の1km後方に到達した場合

			//printf("CATCH_UP :船%d\n",data.ship_id);

			ship[data.ship_id].current_speed = ship[data.ship_id-1].current_speed;
			set_speed(data.ship_id); //影響を後ろに伝播させる

			break;

		case ARRIVE_ROOM: //ある船がある閘門に到達した場合

			//printf("ARRIVE_ROOM 船:%d 部屋:%d\n",data.ship_id,data.room_id);

			//閘門の中ではspeed0とする
			ship[data.ship_id].current_speed = 0;
			ship[data.ship_id].is_waiting = true;
			//自分以降の船に、停止情報を伝える
			set_speed(data.ship_id);

			info[data.room_id].wait_ship_id = data.ship_id; //★とりあえず待つ★

			if(info[data.room_id].water == West){ //水位が西側に合っている場合のみ中に入る

				if(info[data.room_id].is_east_higher){

					info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
				}else{
					info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
				}
				//printf("move_end:%.2lf\n",info[data.room_id].move_end_time);
				info[data.room_id].water = Moving;
				info[data.room_id].next_water = East;
			}

			break;

		case WATER_UP:

			//printf("WATER_UP 部屋%d\n",data.room_id);

			if(info[data.room_id].is_east_higher){ //東の方が水位が高い場合

				//printf("東が高く、かつ東にいある\n");

				//★基本的に閘門の水位は西側に合わせるので、必ず船がいるはず
				tmp_id = info[data.room_id].wait_ship_id;
				//printf("船:%d\n",tmp_id);
				ship[tmp_id].last_room = data.room_id; //通過済とする
				ship[tmp_id].is_waiting = false;
				debug_array[tmp_id]++;
				info[data.room_id].wait_ship_id = -1;

				//★閘門を通過した船の速度を設定する
				if(tmp_id == 0){

					ship[tmp_id].current_speed = ship[tmp_id].max_speed;
					set_speed(tmp_id); //影響を伝播させる

				}else{ //自分が先頭でないなら、自分の1つ前から計算すれば良い

					set_speed(tmp_id-1);
				}

				//閘門の水位が動き終わる時刻等を設定
				info[data.room_id].water = Moving;
				info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
				//printf("move_end:%.3lf\n",info[data.room_id].move_end_time);
				info[data.room_id].next_water = West;

			}else{ //西側の方が水位が高い場合(★船は中にいないが、手前で待っている場合あり★)

				//printf("西が高く、かつ西にいる\n");

				info[data.room_id].water = West;
				if(info[data.room_id].wait_ship_id != -1){ //水位の変動を待っている船がいる場合
					//printf("船%dが待っている\n",info[data.room_id].wait_ship_id);
					info[data.room_id].water = Moving;
					info[data.room_id].move_end_time = current_time+info[data.room_id].down_time;
					//printf("move_end:%.2lf\n",info[data.room_id].move_end_time);
					info[data.room_id].next_water = East;
				}
			}
			break;
		case WATER_DOWN:

			//printf("WATER_DOWN 部屋%d\n",data.room_id);

			if(info[data.room_id].is_east_higher){ //東の方が水位が高い場合(★船は中にいないが、手前で待っている場合あり★)

				//printf("東が高くて、今西にいる\n");

				info[data.room_id].water = West;
				if(info[data.room_id].wait_ship_id != -1){ //水位の変動を待っている船がいる場合
					//printf("船%dが待っている\n",info[data.room_id].wait_ship_id);
					info[data.room_id].water = Moving;
					info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
					//printf("move_end:%.2lf\n",info[data.room_id].move_end_time);
					info[data.room_id].next_water = East;
				}

			}else{ //西側の方が水位が高い場合

				//printf("西が高くて、今東にいる\n");

				//★基本的に閘門の水位は西側に合わせるので、必ず船がいるはず
				tmp_id = info[data.room_id].wait_ship_id;
				//printf("船%d\n",tmp_id);
				ship[tmp_id].last_room = data.room_id; //通過済とする
				ship[tmp_id].is_waiting = false;
				info[data.room_id].wait_ship_id = -1;
				debug_array[tmp_id]++;

				//★閘門を通過した船の速度を設定する:仮に自分が先頭でないなら、自分の1つ前から計算すれば良い★
				if(tmp_id == 0){

					ship[tmp_id].current_speed = ship[tmp_id].max_speed;
					set_speed(tmp_id); //影響を伝播させる

				}else{

					set_speed(tmp_id-1);
				}

				//閘門の水位が動き終わる時刻等を設定
				info[data.room_id].water = Moving;
				info[data.room_id].move_end_time = current_time+info[data.room_id].up_time;
				//printf("move_end:%.2lf\n",info[data.room_id].move_end_time);
				info[data.room_id].next_water = West;
			}

			break;
		case FINISH: //ある船が川を抜けた場合

			//printf("FINISH\n");

			ans = current_time;

			ship_head++;
			break;
		}

		if(ship_head == num_ship)break;

		/*★★★最も早く起こる、次のイベントを計算★★★*/
		next_time = BIG_NUM;

		//船を走査
		for(int i = 0; i < num_ship; i++){

			if(fabs(ship[i].current_speed) < EPS){ //★閘門前、または前が詰まっているために待ち状態ならSKIP

				//★★★ぴったり、閘門の前で止まっている場合あり★★★
				if(fabs(ship[i].current_loc-info[ship[i].last_room+1].loc) < EPS && ship[i].is_waiting == false){

					next_time = current_time; //現在なので必ず最速
					next_ship = i;
					next_room = ship[i].last_room+1;
					next_type = ARRIVE_ROOM;
					break;
				}

				/*if(fabs(current_time-next_time) > EPS && fabs(current_time-next_time) < 0.001-EPS){
					printf("locAA\n");
					printf("diff:%.10lf\n",fabs(current_time-next_time));
							return;
						}*/

			}else{

				//★1つ前の船の1km手前に追いつく時刻
				if(i != 0 && ship[i].current_speed > ship[i-1].current_speed){

					tmp_time = current_time+((ship[i-1].current_loc-ship[i].current_loc)-1.0)/(double)(ship[i].current_speed-ship[i-1].current_speed);

					//printf("船%dが%.2lfに追いつく\n",i,tmp_time);

					if(next_time > tmp_time){

						if(fabs(next_time-tmp_time) < EPS){
							next_time = current_time;
							break;
						}else{
							next_time = tmp_time;
						}

						next_ship = i;
						next_room = -1;
						next_type = CATCH_UP;

						/*if(fabs(current_time-next_time) > EPS && fabs(current_time-next_time) < 0.001-EPS){
											printf("locBB\n");
											printf("diff:%.10lf\n",fabs(current_time-next_time));
													return;
												}*/
					}
				}

				if(i < ship_head || fabs(ship[i].current_speed) < EPS)continue;

				//★閘門に到達する時刻
				if(fabs(ship[i].current_loc-info[ship[i].last_room+1].loc) < EPS){

					tmp_time = current_time;

				}else{

					tmp_time = current_time+calc_time(i,ship[i].last_room+1);
				}
				//printf("tmp_time:%.2lf\n",tmp_time);

				if(ship[i].last_room+1 == num_room){ //次で川を出る場合

					if(next_time > tmp_time){
						next_time = tmp_time;
						next_ship = i;
						next_room = ship[i].last_room+1;
						next_type =  FINISH;
					}

				}else{

					if(next_time > tmp_time){
						next_time = tmp_time;
						next_ship = i;
						next_room = ship[i].last_room+1;
						next_type =  ARRIVE_ROOM;
					}
				}

				/*if(fabs(current_time-next_time) > EPS && fabs(current_time-next_time) < 0.001-EPS){
				printf("locCC\n");
				printf("船%d 門:%d 船スピード:%d 船loc:%.3lf 門loc:%.3lf\n",i,ship[i].last_room+1,ship[i].current_speed,ship[i].current_loc,info[ship[i].last_room+1].loc);
				printf("diff:%.10lf\n",fabs(current_time-next_time));
						return;
					}*/
			}
		}

		//閘門を走査
		for(int i = 0; i < num_room; i++){

			if(info[i].water != Moving)continue;

			if(next_time > info[i].move_end_time){

				next_time = info[i].move_end_time;
				next_room = i;
				next_ship = -1;

				//printf("閘門%d\n",i);

				if(info[i].is_east_higher){

					if(info[i].next_water == West){
						next_type = WATER_DOWN;
					}else{
						next_type = WATER_UP;
					}
				}else{ //西の方が水位が高い

					if(info[i].next_water == West){
						next_type = WATER_UP;
					}else{
						next_type = WATER_DOWN;
					}
				}
			}
		}

		Q.push(Data(next_time,next_ship,next_room,next_type));

		pre_time = current_time;
	}

	printf("%.10lf\n",ans);
	num_case++;

	/*for(int i = 0; i < num_ship; i++){
		if(debug_array[i] != 100){
			printf("船%d debug_array:%d\n",i,debug_array[i]);
		}
	}*/
}

int main(){

	while(true){
		scanf("%d %d %lf",&num_room,&num_ship,&LENGTH);
		if(num_room == 0)break;

		func();
		if(STOP)break;
	}

	return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 3148
final_rank: 10

code_snippet: #include<iostream>

using namespace std;

double in[123][2234],out[123][2234];

int main(){
  for(int N,M,K;cin>>N>>M>>K,N|M|K;){
    int O=M-1;
    double canal[2234]={};
    double rtime[2234]={},ltime[2234]={};
    for(int i=0;i<N;i++){
      int X,L,F,D,UD;
      cin>>X>>L>>F>>D>>UD;
      rtime[X+O]=UD?L*1./D:L*1./F;
      ltime[X+O]=UD?L*1./F:L*1./D;
      if(UD){
	canal[X+O]=ltime[X+O];
      }
    }
    int V[123];
    for(int i=0;i<M;i++){
      cin>>V[i];
    }
    for(int i=0;i<M;i++){
      double t=0;
      for(int j=O-i;j<2200;j++){
	in[i][j]=t;
	out[i][j]=max(t,canal[j])+rtime[j];
	canal[j]=out[i][j]+ltime[j];
	t=max(out[i][j]+1./V[i],!i?0:in[i-1][j+2]);
      }
    }
    cout<<fixed<<in[M-1][K+O]<<endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 5076
final_rank: 4

code_snippet: #include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <fstream>
#include <iomanip>
//#include <utility>
//#include <memory>
//#include <functional>
//#include <deque>
//#include <cctype>
//#include <ctime>
//#include <numeric>
//#include <list>
//#include <iomanip>

//#if __cplusplus >= 201103L
//#include <array>
//#include <tuple>
//#include <initializer_list>
//#include <forward_list>
//
//#define cauto const auto&
//#else

//#endif

using namespace std;


typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef vector<int> vint;
typedef vector<vector<int> > vvint;
typedef vector<long long> vll, vLL;
typedef vector<vector<long long> > vvll, vvLL;

#define VV(T) vector<vector< T > >

template <class T>
void initvv(vector<vector<T> > &v, int a, int b, const T &t = T()){
    v.assign(a, vector<T>(b, t));
}

template <class F, class T>
void convert(const F &f, T &t){
    stringstream ss;
    ss << f;
    ss >> t;
}

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define F first
#define S second
#define mkp make_pair
#define RALL(v) (v).rbegin(),(v).rend()
#define DEBUG
#ifdef DEBUG
#define dump(x)  cout << #x << " = " << (x) << endl;
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#else
#define dump(x) 
#define debug(x) 
#endif
#define LDcout(x,n) fixed<<setprecision(n)<<x

#define MOD 1000000007LL
#define EPS 1e-8
static const int INF=1<<24;
struct kanmon{
	double x;
	double L,F,D;
	int UD;
	double up,down;
};
void mainmain(){
	int n,m,K;

	while(cin>>n>>m>>K,n||m||K){
		vector<kanmon> v(n);
		vint pos(K+300,-1);
		rep(i,n){
			cin>>v[i].x>>v[i].L>>v[i].F>>v[i].D>>v[i].UD;
			v[i].up=v[i].L/v[i].F;
			v[i].down=v[i].L/v[i].D;
			pos[v[i].x+150]=i;
		}
		vector<double> w(m);
		rep(i,m) cin>>w[i];
		vector<VV(double)> dp;
		initvv(dp,m,K+300,vector<double>(2,0));
		rep(i,m){
			dp[i][-i+150][0]=dp[i][-i+150][1]=0;
		}
		rep(i,m){
			reep(j,-i+150+1,K+(m-1-i)+150+1){
				if(!i){
					if(pos[j]==-1){
						dp[i][j][0]=dp[i][j][1]=dp[i][j-1][1]+1.0/w[i];
					}
					else{
						int p=pos[j];
						dp[i][j][0]=dp[i][j-1][1]+1.0/w[i];
						if(v[p].UD){
							dp[i][j][0]=max(dp[i][j][0],v[p].up);
						}
						dp[i][j][1]=dp[i][j][0]+(v[p].UD==0?v[p].up:v[p].down);
					}
				}
				else{
					if(pos[j]==-1){
						dp[i][j][0]=dp[i][j][1]=max(dp[i][j-1][1]+1.0/w[i],dp[i-1][j+1][0]);
					}
					else{
						int p=pos[j];
						dp[i][j][0]=dp[i][j-1][1]+1.0/w[i];
						dp[i][j][0]=max(dp[i][j][0],max(dp[i-1][j+1][0],dp[i-1][j][1]+(v[p].UD?v[p].up:v[p].down)));
						dp[i][j][1]=max(dp[i][j][0]+(v[p].UD==0?v[p].up:v[p].down),dp[i-1][j+1][0]);
					}
				}
			}
		}
		cout<<dp[m-1][K+150][0]<<endl;
	}
}


signed main() {
	ios_base::sync_with_stdio(false);
  	cout<<fixed<<setprecision(10);
    mainmain();
}
accuracy: 1
time_ms: 30
memory_kb: 8516
final_rank: 6

code_snippet: #include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <fstream>
#include <iomanip>
//#include <utility>
//#include <memory>
//#include <functional>
//#include <deque>
//#include <cctype>
//#include <ctime>
//#include <numeric>
//#include <list>
//#include <iomanip>

//#if __cplusplus >= 201103L
//#include <array>
//#include <tuple>
//#include <initializer_list>
//#include <forward_list>
//
//#define cauto const auto&
//#else

//#endif

using namespace std;


typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef vector<int> vint;
typedef vector<vector<int> > vvint;
typedef vector<long long> vll, vLL;
typedef vector<vector<long long> > vvll, vvLL;

#define VV(T) vector<vector< T > >

template <class T>
void initvv(vector<vector<T> > &v, int a, int b, const T &t = T()){
    v.assign(a, vector<T>(b, t));
}

template <class F, class T>
void convert(const F &f, T &t){
    stringstream ss;
    ss << f;
    ss >> t;
}

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define F first
#define S second
#define mkp make_pair
#define RALL(v) (v).rbegin(),(v).rend()
#define DEBUG
#ifdef DEBUG
#define dump(x)  cout << #x << " = " << (x) << endl;
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#else
#define dump(x) 
#define debug(x) 
#endif
#define LDcout(x,n) fixed<<setprecision(n)<<x

#define MOD 1000000007LL
#define EPS 1e-8
static const int INF=1<<24;
struct kanmon{
	double x;
	double L,F,D;
	int UD;
	double up,down;
};
void mainmain(){
	int n,m,K;

	while(cin>>n>>m>>K,n||m||K){
		vector<kanmon> v(n);
		vint pos(K+300,-1);
		rep(i,n){
			cin>>v[i].x>>v[i].L>>v[i].F>>v[i].D>>v[i].UD;
			v[i].up=v[i].L/v[i].F;
			v[i].down=v[i].L/v[i].D;
			pos[v[i].x+150]=i;
		}
		vector<double> w(m);
		rep(i,m) cin>>w[i];
		vector<VV(double)> dp;
		initvv(dp,m,K+300,vector<double>(2,0));
		rep(i,m){
			dp[i][-i+150][0]=dp[i][-i+150][1]=0;
		}
		rep(i,m){
			reep(j,-i+150+1,K+(m-1-i)+150+1){
				if(!i){
					if(pos[j]==-1){
						dp[i][j][0]=dp[i][j][1]=dp[i][j-1][1]+1.0/w[i];
					}
					else{
						int p=pos[j];
						dp[i][j][0]=dp[i][j-1][1]+1.0/w[i];
						if(v[p].UD){
							dp[i][j][0]=max(dp[i][j][0],v[p].up);
						}
						dp[i][j][1]=dp[i][j][0]+(v[p].UD==0?v[p].up:v[p].down);
					}
				}
				else{
					if(pos[j]==-1){
						dp[i][j][0]=dp[i][j][1]=max(dp[i][j-1][1]+1.0/w[i],dp[i-1][j+1][0]);
					}
					else{
						int p=pos[j];
						dp[i][j][0]=dp[i][j-1][1]+1.0/w[i];
						dp[i][j][0]=max(dp[i][j][0],max(dp[i-1][j+1][0],dp[i-1][j][1]+(v[p].UD?v[p].up:v[p].down)));
						dp[i][j][1]=max(dp[i][j][0]+(v[p].UD==0?v[p].up:v[p].down),dp[i-1][j+1][0]);
					}
				}
				// cout<<i<<" "<<j-150<<" "<<dp[i][j][0]<<endl;
			}
			// cout<<endl;
		}
		cout<<dp[m-1][K+150][0]<<endl;
		// rep(i,n){
		// 	double t;
		// 	if(i){
		// 		t=max((v[i].x-v[i-1].x)/w[0],(v[i].UD==0)?0.0:v[i].up)+dp[0][i];
		// 	}
		// 	else{
		// 		t=max(v[i].x/w[0],(v[i].UD==0)?v[i].down:v[i].up);
		// 	}
		// 	dp[0][i+1]=t+(v[i].UD==0?v[i].up:v[i].down);
			// cout<<i<<" "<<dp[0][i+1]<<endl;
		// }
		// dp[0][n+1]=dp[0][n]+(K-v[n-1].x)/w[0];
		// reep(i,1,m){
		// 	rep(j,n){
		// 		double t1;
		// 		if(j){
		// 			t1=(v[j].x-v[j-1].x)/w[i];
		// 		}
		// 		else{
		// 			t1=v[j].x/w[i];
		// 		}
		// 		t1=max(t1,dp[i-1][j]);
		// 	}
		// }
	}
}


signed main() {
	ios_base::sync_with_stdio(false);
  	cout<<fixed<<setprecision(10);
    mainmain();
}
accuracy: 1
time_ms: 30
memory_kb: 8516
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,M,K;
int UD[200];
int x[200],l[200],f[200],d[200];
double X[200],L[200],F[200],D[200];
double V[200],t[200];

int id[2000];
map<int,double> s[200];

int main(){
  while(1){

    for(int i=0;i<200;i++)s[i].clear();
    for(int i=0;i<2000;i++)id[i]=-1;

    cin>>N>>M>>K;
    if(N==0&&M==0&&K==0)break;
 
    for(int i=0;i<N;i++){
      cin>>x[i]>>l[i]>>f[i]>>d[i]>>UD[i];
      X[i]=x[i],L[i]=l[i],F[i]=f[i],D[i]=d[i];
      id[x[i]]=i;
    } 

    for(int i=0;i<M;i++)cin>>V[i];
 
    for(int i=0;i<N;i++){
      t[i]=0;
      if(UD[i]==1){
        t[i]=L[i]/F[i];
        swap(F[i],D[i]);
      }
    }
 

    for(int j=1;j<=K+M-1;j++){
      s[0][j]=s[0][j-1]+1.0/V[0];
      if(id[j-1]==-1)continue;
      int k=id[j-1];

      if(s[0][j-1]<t[k]){
	s[0][j]=t[k]+L[k]/F[k]+1.0/V[0];
	t[k]=t[k]+L[k]/F[k]+L[k]/D[k];
      }else{
	s[0][j]=s[0][j-1]+L[k]/F[k]+1.0/V[0];
	t[k]=s[0][j-1]+L[k]/F[k]+L[k]/D[k];
      }
    }

    
    for(int i=1;i<M;i++){
      double v=1.0/V[i];
      for(int j=-i+1;j<=-i+K+M-1;j++){
	s[i][j]=max(s[i][j-1]+v,s[i-1][j+1]);
	if(j-1<0||id[j-1]==-1)continue;
	int k=id[j-1];
	if(s[i][j-1]<t[k]){
	  s[i][j]=max(s[i][j],t[k]+L[k]/F[k]+v);
	  t[k]=t[k]+L[k]/F[k]+L[k]/D[k];
	}else{
	  s[i][j]=max(s[i][j],s[i][j-1]+L[k]/F[k]+v);
	  t[k]=s[i][j-1]+L[k]/F[k]+L[k]/D[k];
	}
      }
    }
 
    printf("%.10f\n",s[M-1][K]);
  }
  return 0;

}
accuracy: 1
time_ms: 80
memory_kb: 8152
final_rank: 8

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
double last[1120];
int x[110];
int l[110];
int f[110];
int d[110];
int u[110];
int p[1120];
double q[110];
int v[110];
int main(){
	int a,b,c;
	while(scanf("%d%d%d",&a,&b,&c),a){
		for(int i=0;i<=c+b+2;i++)p[i]=-1;
		for(int i=0;i<a;i++){
			scanf("%d%d%d%d%d",x+i,l+i,f+i,d+i,u+i);
			if(!u[i]){
				swap(f[i],d[i]);
			}
			p[x[i]]=i;
		}
		for(int i=0;i<a;i++)q[i]=-999999999;
		for(int i=0;i<=c+b+2;i++)last[i]=-999999999;
		for(int i=0;i<a;i++){
			if(u[i]==1)q[i]=-(double)l[i]/d[i];
		}
	//	for(int i=0;i<a;i++)printf("%f\n",q[i]);
		for(int i=0;i<b;i++)scanf("%d",v+i);
		for(int i=0;i<b;i++){
		
			double now=0;
			for(int j=0;j<=c+b;j++){
				if(j==0){
					now=(double)i/v[i];
				}else now+=1.0/v[i];
				now=max(now,last[j+1]);
				
				last[j]=now;
				if(~p[j]){
					int at=p[j];
					now=max(now,q[at]+(double)l[at]/f[at]+(double)l[at]/d[at]);
					q[at]=now;
					now+=(double)l[at]/d[at];
				}
			//	printf("%d %d: %f\n",i,j,now);
			}
		}
		printf("%.12f\n",last[c]);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1084
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<b?(a=b,1):0)
#define chmin(a,b) (a>b?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

struct Koumon {
  int x,l,f,d,ud;
  Koumon() {}
  Koumon(int x, int l, int f, int d, int ud) :
    x(x),l(l),f(f),d(d),ud(ud) {}
  double otime() {
    if (ud) return double(l)/d;
    else return double(l)/f;
  }
  double itime() {
    if (ud) return double(l)/f;
    else return double(l)/d;
  }
  double ini() {
    if (ud) return double(l)/f;
    else return 0;
  }
};

double dpin[101][1500];
double dpout[101][1500];
double dpava[101][1500];

Koumon koumon[100];
int kid[1500];
int v[100];

int main() {
  int n, m, k;
  while(cin>>n>>m>>k,n||m||k) {
    memset(kid,-1,sizeof(kid));
    REP(i,n) {
      int x,l,f,d,ud;
      cin>>x>>l>>f>>d>>ud;
      x+=100;
      koumon[i]=Koumon(x,l,f,d,ud);
      kid[x] = i;
    }
    REP(i,m) cin>>v[i];
    REP(i,m+1)REP(j,k+105) {
      dpin[i][j]=dpout[i][j]=dpava[i][j]=-1e100;
    }
    REP(i,m) {
      REP(j,k+103) {
        if (kid[j] >= 0) {
          dpava[i+1][j+1] = max(koumon[kid[j]].ini(), dpout[i][j+1] + koumon[kid[j]].itime());
        }
        dpin[i+1][j+1] = max(dpout[i+1][j]+1.0/v[i], dpin[i][j+2]);
        if (i==100-j) dpin[i+1][j+1] = 0;
        if (kid[j] >= 0) chmax(dpin[i+1][j+1], dpava[i+1][j+1]);
        dpout[i+1][j+1] = dpin[i+1][j+1];
        if (kid[j] >= 0) chmax(dpout[i+1][j+1], dpin[i+1][j+1] + koumon[kid[j]].otime());
        // cout << i << " " << j << " " << dpin[i+1][j+1] << " " << dpout[i+1][j+1] << endl;
      }
    }
    printf("%.10f\n", dpout[m][k+101]);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 4752
final_rank: 3

code_snippet: #include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
using namespace std;

#define INF (1<<30)
int x[105], l[105], f[105], d[105], ud[105], v[105];

double up(int n)
{
	return 1.0*l[n]/f[n];
}

double down(int n)
{
	return 1.0*l[n]/d[n];
}

double dp[105][1250];

int main()
{
	cout << setiosflags(ios::fixed) << setprecision(10);
	
	int N,M,K;
	while(cin >> N >> M >> K, (N||M||K))
	{
		v[0]=INF;
		K+=100;

		x[N]=INF;
		
		memset(dp,0,sizeof(dp));
		
		for(int i=0; i<N; i++)
		{
			cin >> x[i] >> l[i] >> f[i] >> d[i] >> ud[i];
			x[i]+=100;
		}
		for(int i=1; i<=M; i++)
			cin >> v[i];	
		
		for(int i=0; i<=K+100; i++)
			dp[0][i]=0;
		
		for(int i=0; i<N; i++)
		{
			if(ud[i]==0) dp[0][x[i]]=-INF;
		}
			
		for(int i=1; i<=M; i++)
		{
			int g=0;
			for(int j=100-i+2; j<=K+102; j++)
			{
				double tmp = dp[i-1][j+1];
				if(x[g+1]==j+1)
				{
					if(ud[g+1]==0) tmp-=up(g+1);
					if(ud[g+1]==1) tmp-=down(g+1);
				}

				if(x[g]!=j)
				{
					dp[i][j]=max(dp[i][j-1] + 1.0/v[i], tmp);
				}
				else
				{

					if(ud[g]==0) 
					{
						dp[i][j]=max(dp[i][j-1]+1.0/v[i], max(dp[i-1][j]+down(g), tmp));
						dp[i][j]+=up(g);
					}
					if(ud[g]==1) 
					{
						dp[i][j]=max(dp[i][j-1]+1.0/v[i], max(dp[i-1][j]+  up(g), tmp));
						dp[i][j]+=down(g);
					}
					
					g++;
				}
				
			}
		}
		
		cout << dp[M][K] << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1