Problem:
Development of Small Flying Robots
You are developing small flying robots in your laboratory.
The laboratory is a box-shaped building with
K
levels, each numbered 1 through
K
from bottom to top.
The floors of all levels are square-shaped with their edges precisely aligned east-west and north-south.
Each floor is divided into
R
×
R
cells.
We denote the cell on the
z
-th level in the
x
-th column from the west and the
y
-th row from the south as (
x
,
y
,
z
).
(Here,
x
and
y
are one-based.)
For each
x
,
y
, and
z
(
z
> 1),
the cell (
x
,
y
,
z
) is located immediately above the cell (
x
,
y
,
z
− 1).
There are
N
robots flying in the laboratory,
each numbered from 1 through
N
.
Initially, the
i
-th robot is located at the cell (
x
i
,
y
i
,
z
i
).
By your effort so far,
you successfully implemented the feature to move each flying robot to any place that you planned.
As the next step, you want to implement a new feature that gathers all
the robots in some single cell with the lowest energy consumption,
based on their current locations and the surrounding environment.
Floors of the level two and above have several holes.
Holes are rectangular and their edges align with edges of the
cells on the floors.
There are
M
holes in the laboratory building, each numbered 1 through
M
.
The
j
-th hole can be described by five integers
u
1
j
,
v
1
j
,
u
2
j
,
v
2
j
, and
w
j
.
The
j
-th hole extends over the cells (
x
,
y
,
w
j
)
where
u
1
j
≤
x
≤
u
2
j
and
v
1
j
≤
y
≤
v
2
j
.
Possible movements of robots and energy consumption involved are as follows.
You can move a robot from one cell to an adjacent cell, toward one of north, south, east, or west.
  The robot consumes its energy by 1 for this move.
If there is a hole to go through immediately above,
  you can move the robot upward by a single level.
  The robot consumes its energy by 100 for this move.
The robots never fall down even if there is a hole below.
Note that you can move two or more robots to the same cell.
Now, you want to gather all the flying robots at a single cell in the
K
-th level where there is no hole on the floor, with the least energy consumption.
Compute and output the minimum total energy required by the robots.
Input
The input consists of at most 32 datasets, each in the following format.
Every value in the input is an integer.
N
M
K
R
x
1
y
1
z
1
...
x
N
y
N
z
N
u
11
v
11
u
21
v
21
w
1
...
u
1
M
v
1
M
u
2
M
v
2
M
w
M
N
is the number of robots in the laboratory (1 ≤
N
≤ 100).
M
is the number of holes (1 ≤
M
≤ 50),
K
is the number of levels (2 ≤
K
≤ 10),
and
R
is the number of cells in one row and also one column on a single floor (3 ≤
R
≤ 1,000,000).
For each
i
,
integers
x
i
,
y
i
, and
z
i
represent the cell that the
i
-th robot initially located at
(1 ≤
x
i
≤
R
,
 1 ≤
y
i
≤
R
,
 1 ≤
z
i
≤
K
).
Further,
for each
j
,
integers
u
1
j
,
v
1
j
,
u
2
j
,
v
2
j
, and
w
j
describe the position and the extent of the
j
-th hole
(1 ≤
u
1
j
≤
u
2
j
≤
R
,
 1 ≤
v
1
j
≤
v
2
j
≤
R
,
 2 ≤
w
j
≤
K
).
Th
...(truncated)

Submitted solutions:

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int N) {
    int M = in(), K = in(), R = in();
    vector<tuple<int,int,int>> A(N);
    for(auto &[x, y, z] : A) x = in(), y = in(), z = in();

    vector<vector<tuple<int,int,int,int>>> B(K + 1);
    for(int _ : rep(M)) {
        int u1 = in(), v1 = in(), u2 = in(), v2 = in(), w = in();
        B[w].push_back({u1, v1, u2, v2});
    }

    vector<map<pair<int,int>, int>> C(N);
    for(int i : rep(N)) {
        map<pair<int,int>, int> &mp = C[i];
        auto [sx, sy, sz] = A[i];
        mp[{sx, sy}] = 0;

        for(int z = sz + 1; z <= K; z++) {
            map<pair<int,int>, int> nt;
            for(auto [p, d] : mp) {
                auto [x, y] = p;
                for(auto [u1, v1, u2, v2] : B[z]) {
                    int nx = [&] {
                        if(u1 <= x and x <= u2) return x;
                        return abs(u1 - x) <= abs(u2 - x) ? u1 : u2;
                    }();
                    int ny = [&] {
                        if(v1 <= y and y <= v2) return y;
                        return abs(v1 - y) <= abs(v2 - y) ? v1 : v2;
                    }();
                    int nd = d + abs(x - nx) + abs(y - ny) + 100;
                    if(nt.count({nx, ny})) chmin(nt[{nx, ny}], nd);
                    else nt[{nx, ny}] = nd;
                }
            }
            mp = move(nt);
        }
    }

    vector<int> xs, ys;
    for(auto &mp : C) for(auto [p, d] : mp) {
        auto [x, y] = p;
        xs.push_back(x);
        ys.push_back(y);
    }
    for(auto [u1, v1, u2, v2] : B[K]) {
        xs.push_back(u1 - 1);
        xs.push_back(u2 + 1);
        ys.push_back(v1 - 1);
        ys.push_back(v2 + 1);
    }
    unique(xs);
    unique(ys);

    int ans = 2e9;
    for(int x : xs) for(int y : ys) {
        if(1 <= x and x <= R and 1 <= y and y <= R) {
            bool in_hall = [&] {
                for(auto [u1, v1, u2, v2] : B[K]) {
                    if(u1 <= x and x <= u2 and v1 <= y and y <= v2) {
                        return true;
                    }
                }
                return false;
            }();
            if(not in_hall) {
                int score = 0;
                for(auto &mp : C) {
                    int Min = 2e9;
                    for(auto [p, d] : mp) {
                        auto [cx, cy] = p;
                        chmin(Min, d + abs(cx - x) + abs(cy - y));
                    }
                    score += Min;
                }
                chmin(ans, score);
            }
        }
    }
    return ans;
}

int main() {
    while(true) {
        int N = in();
        if(N == 0) return 0;
        print(solve(N));
    }
}
accuracy: 1
time_ms: 1220
memory_kb: 3944
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
bool chmax(T& p, T q) {
    if (p < q) {
        p = q; return 1;
    }
    return 0;
};
template<class T>
bool chmin(T& p, T q) {
    if (p > q) {
        p = q; return 1;
    }
    return 0;
};

bool is_contain(pair<pair<ll, ll>, pair<ll, ll>>& h, ll x, ll y) {
    if (h.first.first <= x && x<=h.second.first && h.second.second >= y && h.first.second <= y)return 1;
    return 0;
}


void solve(ll N) {
    ll M, K, R;
    cin >> M >> K >> R;
    vector<vector<pair<pair<ll, ll>, pair<ll, ll>>>> HALL(K);
    vll X(N), Y(N), Z(N);
    rep(i, N) {
        cin >> X[i] >> Y[i] >> Z[i];
        Z[i]--;
    }
    rep(i, M) {
        ll x, y, u, v, w;
        cin >> x >> y >> u >> v >> w;
        HALL[w - 2].push_back({ {x,y},{u,v} });
    }
    //最上階のhogehoge
    vector<map<pair<ll, ll>, ll>> D(N);
    rep(i, N) {
        map<pair<ll, ll>, ll> dist;
        dist[{X[i], Y[i]}] = 0;
        for (ll z = Z[i]; z < K - 1; z++) {
            map<pair<ll, ll>, ll> ndist;
            for (auto xyd : dist) {
                ll x = xyd.first.first;
                ll y = xyd.first.second;
                ll d = xyd.second;

                for (auto h : HALL[z]) {
                    ll nx = x, ny = y;
                    ll nd = d+100;
                    if (is_contain(h, x, y)) {

                    }
                    else if (h.first.first <= x && x <= h.second.first) {
                        if (h.first.second > y) {
                            ny = h.first.second;
                        }
                        else {
                            ny = h.second.second;
                        }
                    }
                    else if (h.first.second <= y && y <= h.second.second) {
                        if (h.first.first > x) {
                            nx = h.first.first;
                        }
                        else {
                            nx = h.second.first;
                        }
                    }
                    else {
                        if (h.first.first > x) {
                            nx = h.first.first;
                        }
                        else {
                            nx = h.second.first;
                        }
                        if (h.first.second > y) {
                            ny = h.first.second;
                        }
                        else {
                            ny = h.second.second;
                        }
                    }
                    nd += abs(nx - x) + abs(ny - y);

                    if (!ndist.count({ nx,ny }))ndist[{nx, ny}] = nd+1;
                    chmin(ndist[{nx, ny}], nd);
                }
            }
            swap(dist, ndist);
        }
        // cout<<i<<endl;
        // for(auto dd:dist){
        //     cout<<dd.first.first<<" "<<dd.first.second<<" "<<dd.second<<endl;
        // }
        // cout<<"===================\n";
        D[i] = dist;
    }
    //ここまでで話は2次元に落ちた

    set<ll> BX,BY;
    for(auto H:HALL[K-2]){
        BX.insert(H.first.first-1);
        BX.insert(H.second.first+1);
        BY.insert(H.first.second-1);
        BY.insert(H.second.second+1);
    }
    rep(i,N)for(auto xy:D[i]){
        BX.insert(xy.first.first);
        BY.insert(xy.first.second);
    }

    ll an=1e18;
    for(auto x:BX)for(auto y:BY){
        if(x<1||y<1||x>R||y>R)continue;
        bool OK=1;
        for(auto h:HALL[K-2])if(is_contain(h,x,y))OK=0;
        if(!OK)continue;

        ll res=0;
        rep(i,N){
            ll fes=1e18;
            for(auto uvw:D[i]){
                ll u=uvw.first.first;
                ll v=uvw.first.second;
                ll w=uvw.second;
                chmin(fes,abs(u-x)+abs(v-y)+w);
            }
            res+=fes;
        }
        chmin(an,res);
    }
    
    cout<<an<<endl;
    

    

    // cout << "MADA" << endl;
}

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


    ll N;
    while (cin >> N) {
        if (N == 0)return 0;
        solve(N);
    }

}
accuracy: 1
time_ms: 1270
memory_kb: 3864
final_rank: 5

code_snippet: //#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 2;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

int sum[305][305];
int dist[305][305];
bool isemp[305][305];

int n;
void solve() {
	int m, k, r; cin >> m >> k >> r;
	vector<int> x(n), y(n), z(n);
	rep(i, n)cin >> x[i] >> y[i] >> z[i];
	vector<int> lx(m), ly(m), rx(m), ry(m);
	vector<int> w(m);
	rep(i, m) {
		cin >> lx[i] >> ly[i] >> rx[i] >> ry[i] >> w[i];
	}
	vector<int> vx, vy;
	rep(i, n) {
		vx.push_back(x[i]);
		vy.push_back(y[i]);
	}
	rep(i, m) {
		vx.push_back(lx[i]);
		vy.push_back(ly[i]);
		vx.push_back(rx[i]);
		vy.push_back(ry[i]);
		if (w[i] == k) {
			if (lx[i] > 1)vx.push_back(lx[i] - 1);
			if (rx[i] + 1 <= r)vx.push_back(rx[i] + 1);
			if (ly[i] > 1)vy.push_back(ly[i] - 1);
			if (ry[i] + 1 <= r)vy.push_back(ry[i] + 1);
		}
	}
	sort(all(vx));
	vx.erase(unique(all(vx)), vx.end());
	sort(all(vy));
	vy.erase(unique(all(vy)), vy.end());
	rep(i, vx.size())rep(j, vy.size()) {
		isemp[i][j] = false;
		sum[i][j] = 0;
	}
	rep(i, m)if(w[i]==k) {
		int idxl = lower_bound(all(vx), lx[i]) - vx.begin();
		int idxr = lower_bound(all(vx), rx[i]) - vx.begin();
		int idyl = lower_bound(all(vy), ly[i]) - vy.begin();
		int idyr = lower_bound(all(vy), ry[i]) - vy.begin();
		Rep1(x, idxl, idxr)Rep1(y, idyl, idyr) {
			isemp[x][y] = true;
		}
	}
	auto isin = [&](int x, int y) {
		if (x < 0 || x >= vx.size() || y<0 || y >= vy.size())return false;
		return true;
	};
	vector<vector<int>> holes(k + 1);
	rep(i, m) {
		holes[w[i]].push_back(i);
	}
	auto inseg = [&](int x, int l, int r) {
		return min(r, max(l, x));
	};
	int ad = 0;
	rep(id, n) {
		ad += 100 * (k - z[id]);
		map<P, int> mp;
		mp[{x[id], y[id]}] = 0;
		int cur = z[id];
		while (cur < k) {
			map<P, int> nex;
			for (auto p : mp) {
				int cx = p.first.first;
				int cy = p.first.second;
				int cval = p.second;
				for (int h : holes[cur + 1]) {
					int nx, ny;
					bool inx = false, iny = false;
					if (lx[h] <= cx && cx <= rx[h])inx = true;
					if (ly[h] <= cy && cy <= ry[h])iny = true;
					if (inx && iny) {
						nx = cx, ny = cy;
					}
					else if (inx) {
						nx = cx, ny = inseg(cy, ly[h], ry[h]);
					}
					else if (iny) {
						nx = inseg(cx, lx[h], rx[h]), ny = cy;
					}
					else {
						nx = inseg(cx, lx[h], rx[h]), ny = inseg(cy, ly[h], ry[h]);
					}
					int nval = cval + abs(nx - cx) + abs(ny - cy);
					P np = { nx,ny };
					if (nex.find(np) == nex.end()) {
						nex[np] = nval;
					}
					else if (nex[np] > nval)nex[np] = nval;
				}
			}
			cur++;
			swap(mp, nex);
		}
		rep(i, vx.size())rep(j, vy.size()) {
			dist[i][j] = mod;
		}
		using speP = pair<int, P>;
		priority_queue<speP, vector<speP>, greater<speP>> q;
		for (auto p : mp) {
			int cx = p.first.first;
			int cy = p.first.second;
			int cval = p.second;
			cx = lower_bound(all(vx), cx) - vx.begin();
			cy = lower_bound(all(vy), cy) - vy.begin();
			dist[cx][cy] = cval;
			q.push({ cval,{cx,cy} });
		}
		while (!q.empty()) {
			speP p = q.top(); q.pop();
			int cx = p.second.first;
			int cy = p.second.second;
			int cval = p.first;
			rep(d, 4) {
				int nx = cx + dx[d];
				int ny = cy + dy[d];
				if (isin(nx, ny)) {
					int nval = cval + abs(vx[nx] - vx[cx]) + abs(vy[ny] - vy[cy]);
					if (nval < dist[nx][ny]) {
						dist[nx][ny] = nval;
						q.push({ nval,{nx,ny} });
					}
				}
			}
		}
		rep(i, vx.size())rep(j, vy.size()) {
			sum[i][j] += dist[i][j];
		}
	}
	int ans = -1;
	rep(i, vx.size())rep(j, vy.size())if (!isemp[i][j]) {
		if (ans < 0 || sum[i][j] < ans)ans = sum[i][j];
	}
	ans += ad;
	//cout << "ans is ";
	cout << ans << "\n";
}



signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(8);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)
	while (cin >> n, n)
		solve();
	return 0;
}
accuracy: 1
time_ms: 3530
memory_kb: 4036
final_rank: 7

code_snippet: //copied from http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4036948#1
// my submission is http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=5050345#1


#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1607"

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

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename V>
V compress(V v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}
template<typename T>
map<T, int> dict(const vector<T> &v){
  map<T, int> res;
  for(int i=0;i<(int)v.size();i++)
    res[v[i]]=i;
  return res;
}
map<char, int> dict(const string &v){
  return dict(vector<char>(v.begin(),v.end()));
}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed ABC036_C(){
  int n;
  cin>>n;
  vector<int> a(n);
  for(int i=0;i<n;i++) cin>>a[i];
  auto v=compress(a);
  auto m=dict(v);
  for(int i=0;i<n;i++) cout<<m[a[i]]<<endl;
  return 0;
}
/*
  verified on 2018/08/26
  https://abc036.contest.atcoder.jp/tasks/abc036_c
*/

signed main(){
  ABC036_C();
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;
template <typename T>
using gtree = tree<T,null_type,less<T>,rb_tree_tag,
                   tree_order_statistics_node_update>;
// usage:
// find_by_order(int k):
// return the iterator of k-th smallest element (0-indexed)
// order_of_key(T key):  return the index of key in tree
//END CUT HERE
#ifndef call_from_test
signed ARC028_B(){
  using ll = long long;
  int n,k;
  cin>>n>>k;
  vector<int> xs(n);
  for(int i=0;i<n;i++) cin>>xs[i];
  map<int, int> mp;
  for(int i=0;i<n;i++) mp[xs[i]]=i+1;
  gtree<ll> G;
  for(int i=0;i<k-1;i++) G.insert(xs[i]);
  for(int i=k-1;i<n;i++){
    G.insert(xs[i]);
    auto key=*G.find_by_order(k-1);
    cout<<mp[key]<<endl;
  }
  return 0;
}

/*
  verified on 2019/12/09
  https://atcoder.jp/contests/arc028/tasks/arc028_2
*/

signed ARC033_C(){
  int q;
  cin>>q;
  gtree<int> G;
  while(q--){
    int t,x;
    cin>>t>>x;
    if(t==1) G.insert(x);
    if(t==2){
      int k=*G.find_by_order(x-1);
      G.erase(k);
      cout<<k<<endl;
    }
  }
  return 0;
}

/*
  verified on 2019/12/09
  https://atcoder.jp/contests/arc033/tasks/arc033_3
*/

signed main(){
  //ARC028_B();
  //ARC033_C();
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
#endif
//BEGIN CUT HERE
// prohibited to push an element less than popped one
// Key: int or long long
template<typename K,typename V>
struct RadixHeap{
  static constexpr int bit = sizeof(K) * 8;
  array<vector< pair<K, V> >, bit> vs;

  int size;
  K last;
  RadixHeap():size(0),last(0){}

  bool empty() const{return size==0;}

  inline int getbit(int a){
    return a?bit-__builtin_clz(a):0;
  }

  inline int getbit(long long a){
    return a?bit-__builtin_clzll(a):0;
  }

  void emplace(K key,V val){
    size++;
    vs[getbit(key^last)].emplace_back(key,val);
  }

  pair<K, V> pop(){
    if(vs[0].empty()){
      int idx=1;
      while(vs[idx].empty()) idx++;
      last=min_element(vs[idx].begin(),vs[idx].end())->first;
      for(auto &p:vs[idx]) vs[getbit(p.first^last)].emplace_back(p);
      vs[idx].clear();
    }
    --size;
    auto res=vs[0].back();
    vs[0].pop_back();
    return res;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

const int BS = 8, BS2 = BS * 2;
const int msk = (1<<BS)-1;
const int MAX = 12 * (1<<BS) * (1<<BS);
int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

signed main(){
  int n;
  while(cin>>n,n){
    int m,k,r;
    cin>>m>>k>>r;
    vector<int> x(n),y(n),z(n);
    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];

    vector<int> vx(x),vy(y);
    for(int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }

    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](int cy,int cx,int f){return (f<<BS2)|(cy<<BS)|cx;};

    memset(hole,0,sizeof(hole));
    for(int p=0;p<m;p++)
      for(int i=my[v1[p]];i<=my[v2[p]];i++)
        for(int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;

    int sy=vy.size(),sx=vx.size();

    auto dijkstra=
      [&](int a)->void{
        vector<int> wy,wx;
        for(int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        int ty=zy.size(),tx=zx.size();

        vector<pair<int, int> > vs;
        {
          for(int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap<int, int> q;
          {
            int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.emplace(dist[v],v);
          }

          while(!q.empty()){
            auto p=q.pop();
            int v=p.second;
            if(dist[v]<p.first) continue;

            int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }

            auto push=
              [&](int ni,int nj,int nf){
                int u=idx(ni,nj,nf);
                int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);

                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;
                  q.emplace(dist[u],u);
                }
              };

            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }

            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {
          for(int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap<int, int> q;
          for(auto p:vs){
            int v=p.first,d=p.second;
            add[v]=d;
            q.emplace(add[v],v);
          }

          while(!q.empty()){
            auto p=q.pop();
            int v=p.second;
            if(add[v]<p.first) continue;

            int i=v>>BS,j=v&msk;
            auto push=
              [&](int ni,int nj){
                int u=(ni<<BS)|nj;
                int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;
                  q.emplace(add[u],u);
                }
              };

            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };

    memset(dp,0,sizeof(dp));
    for(int p=0;p<n;p++){
      dijkstra(p);
      for(int i=0;i<sy;i++)
        for(int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }

    long long ans=1e18;
    for(int i=0;i<sy;i++)
      for(int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 6900
memory_kb: 8424
final_rank: 12

code_snippet: //Let's join Kaede Takagaki Fan Club !!
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
//#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define all(x) x.begin(),x.end()
template<class T>
void dmp(T a){
	rep(i,a.size()) cout << a[i] << " ";
	cout << endl;
}
template<class T>
bool chmax(T&a, T b){
	if(a < b){
		a = b;
		return 1;
	}
	return 0;
}
template<class T>
bool chmin(T&a, T b){
	if(a > b){
		a = b;
		return 1;
	}
	return 0;
}
template<class T>
void g(T &a){
	cin >> a;
}
template<class T>
void o(const T &a,bool space=false){
	cout << a << (space?' ':'\n');
}
//ios::sync_with_stdio(false);
const ll mod = 1000000007;//998244353
template<class T>
void add(T&a,T b){
	a+=b;
	if(a >= mod) a-=mod;
}

int n;
int m, k, r;
int x[105], y[105], z[105];
vector<P2>hole[16];
vector<P1>dp[105][16];
void solve(){
	ll ans = 0;
	cin >> m >> k >> r;
	repn(i, n){
		cin >> x[i] >> y[i] >> z[i];
		ans += 100LL * (k-z[i]);
	}
	repn(i, k){
		hole[i].clear();
		repn(j, n) dp[j][i].clear();
	}
	set<int>S;
	repn(i, m){
		int a1, b1, a2, b2, w; cin >> a1 >> b1 >> a2 >> b2 >> w;
		hole[w].pb(mp( mp(a1, a2), mp(b1, b2) ));
		S.insert(a1); S.insert(a2);
	}
	repn(i, n){
		dp[i][z[i]].pb(mp(0, mp(x[i], y[i])));
		for(int j=z[i]+1;j<=k;j++){
			map<P, int>M;
			for(const auto at:dp[i][j-1]){
				for(const auto zz:hole[j]){
					int val = at.fi;
					P za = at.sc;
					if(zz.fi.fi > za.fi){
						val += zz.fi.fi-za.fi; za.fi = zz.fi.fi;
					}
					if(zz.fi.sc < za.fi){
						val += za.fi-zz.fi.sc; za.fi = zz.fi.sc;
					}
					if(zz.sc.fi > za.sc){
						val += zz.sc.fi-za.sc; za.sc = zz.sc.fi;
					}
					if(zz.sc.sc < za.sc){
						val += za.sc-zz.sc.sc; za.sc = zz.sc.sc;
					}
					if(M.find(za) == M.end()) M[za] = val;
					else chmin(M[za], val);
				}
			}
			for(const auto at:M){
				dp[i][j].pb(mp(at.sc, at.fi));
			}
		}
	}
	vector<int>zx, zy;
	repn(i, n){
		for(const auto at:dp[i][k]){
			zx.pb(at.sc.fi);
			zy.pb(at.sc.sc);
		}
	}
	for(const auto at:hole[k]){
		zx.pb(at.fi.fi-1); zx.pb(at.fi.fi);
		zx.pb(at.fi.sc); zx.pb(at.fi.sc+1);
		
		zy.pb(at.sc.fi-1); zy.pb(at.sc.fi);
		zy.pb(at.sc.sc); zy.pb(at.sc.sc+1);
	}
	SORT(zx); SORT(zy);
	ERASE(zx); ERASE(zy);
	ll mn = 1e18;
	rep(i, zx.size())rep(j, zy.size()){
		int X = zx[i], Y = zy[j], bad = 0;
		for(const auto at:hole[k]){
			if(at.fi.fi <= X && X <= at.fi.sc && at.sc.fi <= Y && Y <= at.sc.sc){
				bad = 1; break;
			}
		}
		if(bad) continue;
		ll sum = 0;
		repn(i, n){
			ll add = 1e18;
			for(const auto at:dp[i][k]){
				chmin(add, 1LL*abs(X-at.sc.fi) + abs(Y-at.sc.sc) + at.fi);
			}
			sum += add;
			if(sum >= mn) break;
		}
		chmin(mn, sum);
	}
	cout << mn + ans << '\n';
}
int main(){
	while(1){
		cin >> n;
		if(n == 0) return 0;
		solve();
	}
}
accuracy: 1
time_ms: 440
memory_kb: 4092
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=int64_t;
template<class T,class U> inline bool chmin(T&x,U y){if(x>y){x=y;return true;}return false;}
template<class T,class U> inline bool chmax(T&x,U y){if(x<y){x=y;return true;}return false;}

int n;
void solve(){
    int m,k,r;
    cin>>m>>k>>r;
    vector<int> xs, ys;
    vector<int> x(n),y(n),z(n);
    struct hole{
        int u,v,U,V;
    };
    vector<vector<hole>> H(k);
    ll ans{};
    for(int i{};i<(n);++i){
        cin>>x[i]>>y[i]>>z[i];
        ans+=(k-z[i])*100;
        --x[i];--y[i];--z[i];
        xs.push_back(x[i]);
        ys.push_back(y[i]);
    }
    for(int i{},u,v,U,V,w;i<m;++i){
        cin>>u>>v>>U>>V>>w;
        H[--w].push_back(hole{--u,--v,--U,--V});
        xs.push_back(u);
        xs.push_back(U);
        ys.push_back(v);
        ys.push_back(V);
        if(w==k-1){
            if(u) xs.push_back(u-1);
            if(U+1<r) xs.push_back(U+1);
            if(v) ys.push_back(v-1);
            if(V+1<r) ys.push_back(V+1);
        }
    }
    struct kou{
        int x,y;
        ll d;
    };
    vector<vector<kou>> e(n);
    for(int i{};i<k;++i){
        for(int j{};j<n;++j){
            if(!e[j].empty()){
                vector<kou> ne;
                for(auto[p,q,d]:e[j]){
                    for(auto[u,v,U,V]:H[i]){
                        int X=clamp(p, u, U);
                        int Y=clamp(q, v, V);
                        //cerr<<p<<" "<<q<<" "<<d<<" "<<X<<" "<<Y<<'\n';
                        ne.push_back(kou{X, Y, d+abs(X-p)+abs(Y-q)});
                    }
                }
                e[j].clear();
                int N=ne.size();
                vector<bool> need(N,true);
                for(int I{};I<N;++I) if(need[I]){
                    for(int J{};J<(I);++J) if(need[J]){
                        if(ne[I].d+abs(ne[I].x-ne[J].x)+abs(ne[I].y-ne[J].y)<=ne[J].d){
                            need[J]=false;
                        }
                        else if(ne[J].d+abs(ne[I].x-ne[J].x)+abs(ne[I].y-ne[J].y)<=ne[I].d){
                            need[I]=false;
                        }
                    }
                }
                for(int I{};I<N;++I) if(need[I]){
                    e[j].push_back(ne[I]);
                }
            }
            if(i==z[j]){
                e[j].push_back(kou{x[j],y[j],0});
            }
        }
        /*for(auto&E:e){
            for(auto[x,y,d]:E){
                cerr<<x<<" "<<y<<" "<<d<<'\n';
            }
            cerr<<'\n';
        }*/
    }
    sort(xs.begin(),xs.end());
    sort(ys.begin(),ys.end());
    auto it=unique(xs.begin(),xs.end());
    xs.erase(it,xs.end());
    auto it2=unique(ys.begin(),ys.end());
    ys.erase(it2,ys.end());
    unordered_map<int,int> ix,iy;
    int XS=xs.size(), YS=ys.size();
    for(int i{};i<XS;++i){
        ix[xs[i]]=i;
    }
    for(int i{};i<YS;++i){
        iy[ys[i]]=i;
    }
    /*for(auto&i:xs) cerr<<i+1<<" ";
    cerr<<'\n';
    for(auto&i:ys) cerr<<i+1<<" ";
    cerr<<'\n'<<'\n';////////////////////*/
    auto D=vector(n, vector(XS,vector(YS, LLONG_MAX/2)));
    for(int p{};p<(n);++p){
        for(auto[X,Y,d]:e[p]){
            D[p][ix[X]][iy[Y]]=d;
        }
        for(int i{};i<(XS);++i){
            for(int j{};j<(YS);++j){
                if(i) chmin(D[p][i][j], D[p][i-1][j]+xs[i]-xs[i-1]);
                if(j) chmin(D[p][i][j], D[p][i][j-1]+ys[j]-ys[j-1]);
            }
        }
        for(int i{XS};i--;){
            for(int j{};j<(YS);++j){
                if(i+1<XS) chmin(D[p][i][j], D[p][i+1][j]+xs[i+1]-xs[i]);
                if(j) chmin(D[p][i][j], D[p][i][j-1]+ys[j]-ys[j-1]);
            }
        }
        for(int i{};i<(XS);++i){
            for(int j{YS};j--;){
                if(i) chmin(D[p][i][j], D[p][i-1][j]+xs[i]-xs[i-1]);
                if(j+1<YS) chmin(D[p][i][j], D[p][i][j+1]+ys[j+1]-ys[j]);
            }
        }
        for(int i{XS};i--;){
            for(int j{YS};j--;){
                if(i+1<XS) chmin(D[p][i][j], D[p][i+1][j]+xs[i+1]-xs[i]);
                if(j+1<YS) chmin(D[p][i][j], D[p][i][j+1]+ys[j+1]-ys[j]);
            }
        }
        /*for(auto&i:D[p]){
            for(auto&j:i){
                cerr<<j<<" ";
            }
            cerr<<'\n';
        }
        cerr<<'\n';///////////*/
    }
    ll ANS=LLONG_MAX;
    for(int i{};i<(XS);++i){
        for(int j{};j<(YS);++j){
            bool f=false;
            for(auto[u,v,U,V]:H[k-1]){
                if(u<=xs[i] and xs[i]<=U and v<=ys[j] and ys[j]<=V){
                    f=true;
                    break;
                }
            }
            if(f) continue;
            ll tmp{};
            for(int p{};p<n;++p){
                tmp+=D[p][i][j];
            }
            if(chmin(ANS, tmp)){
                //cerr<<xs[i]+1<<" "<<ys[j]+1<<" "<<ANS<<'\n';
            };
        }
    }
    cout<<ans+ANS<<endl;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    while(cin>>n, n) solve();
}
accuracy: 1
time_ms: 530
memory_kb: 42284
final_rank: 6

code_snippet: #pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define N 200100
#define MOD 1000000007 //998244353
#define ll long long
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep2(i, a, b) for(int i = a; i <= b; ++i)
#define rep3(i, a, b) for(int i = a; i >= b; --i)
#define eb emplace_back
#define pb push_back
#define all(c) (c).begin(), (c).end()
#define vi vector<int>
#define pii pair<int,int>
#define pll pair<ll,ll>
int d[310][310];
int d2[310][310];
bool w[310][310];
int ans[310][310];
int dx[310];
int dy[310];


int main() {
	int n;
	int m, k, r;
	int x, y, z;
	int ax[100];
	int ay[100];
	int az[100];
	int x1[50];
	int x2[50];
	int y1[50];
	int y2[50];
	int zz[50];
	vector<int>fx;
	vector<int>fy;
	vector<int>xx;
	vector<int>yy;
	vector<int>ox;
	vector<int>oy;
	int fians;
	map<int, int>rx;
	map<int, int>ry;
	int sx, sy, osx, osy, itrx, itry;
	int cx1, cx2, cy1, cy2;
	priority_queue<pair<int, pii> > pq;
	pair<int, pii> paa;

	while (true) {
		cin >> n;
		if (n == 0)break;
		rep(i, 310) {
			rep(j, 310)ans[i][j] = 0;
		}
		cin >> m >> k >> r;
		fx.clear();
		fy.clear();
		rep(i, n) {
			cin >> ax[i] >> ay[i] >> az[i];
			fx.pb(ax[i]);
			fy.pb(ay[i]);
		}
		rep(i, m) {
			cin >> x1[i] >> y1[i] >> x2[i] >> y2[i] >> zz[i];
			fx.pb(x1[i]);
			fx.pb(x2[i]);
			if (x1[i] > 1)fx.pb(x1[i] - 1);
			if (x2[i] < r)fx.pb(x2[i] + 1);
			fy.pb(y1[i]);
			fy.pb(y2[i]);
			if (y1[i] > 1)fy.pb(y1[i] - 1);
			if (y2[i] < r)fy.pb(y2[i] + 1);
		}
		sort(fx.begin(), fx.end());
		fx.erase(unique(fx.begin(), fx.end()), fx.end());
		sort(fy.begin(), fy.end());
		fy.erase(unique(fy.begin(), fy.end()), fy.end());
		rep(nn, n) {
			xx.clear();
			yy.clear();
			xx.pb(ax[nn]);
			yy.pb(ay[nn]);
			sx = 1;
			sy = 1;
			d2[0][0] = 0;
			rep2(i, az[nn], k) {
				ox = xx;
				oy = yy;
				rep(j, m) {
					if (zz[j] == i+1) {
						xx.pb(x1[j]);
						xx.pb(x2[j]);
						yy.pb(y1[j]);
						yy.pb(y2[j]);
					}
				}
				sort(xx.begin(), xx.end());
				xx.erase(unique(xx.begin(), xx.end()), xx.end());
				sort(yy.begin(), yy.end());
				yy.erase(unique(yy.begin(), yy.end()), yy.end());
				if (i == k) {
					xx = fx;
					yy = fy;
				}
				osx = sx;
				osy = sy;
				sx = xx.size();
				sy = yy.size();
				rep(j, sx)rx[xx[j]] = j;
				rep(j, sy)ry[yy[j]] = j;
				rep(j, sx-1) {
					dx[j] = xx[j + 1] - xx[j];
				}
				rep(j, sy - 1) {
					dy[j] = yy[j + 1] - yy[j];
				}
				rep(ii, sx) {
					rep(jj, sy) {
						w[ii][jj] = false;
						d[ii][jj] = MOD;
					}
				}
				rep(j, m) {
					if (zz[j] == i) {
						cx1 = rx[x1[j]];
						cx2 = rx[x2[j]];
						cy1 = ry[y1[j]];
						cy2 = ry[y2[j]];
						rep2(ii, cx1, cx2) {
							rep2(jj, cy1, cy2)w[ii][jj] = true;
						}
					}
				}
				while (!pq.empty())pq.pop();
				itrx = 0;
				rep(ii, sx) {
					if (ox[itrx] == xx[ii]) {
						itry = 0;
						rep(jj, sy) {
							if (oy[itry] == yy[jj]) {
								if (i == az[nn]) {
									d[ii][jj] = 0;
									pq.push({ -d[ii][jj],{ii,jj} });
								}
                              else if (w[ii][jj]) {
									d[ii][jj] = d2[itrx][itry] + 100;
									pq.push({ -d[ii][jj],{ii,jj} });
								}
								itry++;
							}
							if (itry >= osy)break;
						}
						itrx++;
					}
					if (itrx >= osx)break;
				}
				
				while (!pq.empty()) {
					while (!pq.empty()) {
						paa = pq.top();
						z = -(paa.first);
						x = paa.second.first;
						y = paa.second.second;
						if (d[x][y] == z)break;
						pq.pop();
					}
					if (pq.empty())break;
					if (x > 0) {
						if (d[x - 1][y] > z + dx[x - 1]) {
							d[x - 1][y] = z + dx[x - 1];
							pq.push({ -d[x - 1][y],{x - 1,y} });
						}
					}
					if (x < (sx - 1)) {
						if (d[x + 1][y] > z + dx[x]) {
							d[x + 1][y] = z + dx[x];
							pq.push({ -d[x + 1][y],{x + 1,y} });
						}
					}
					if (y > 0) {
						if (d[x][y-1] > z + dy[y - 1]) {
							d[x][y - 1] = z + dy[y - 1];
							pq.push({ -d[x][y - 1],{x,y - 1} });
						}
					}
					if (y < (sy - 1)) {
						if (d[x][y + 1] > z + dy[y]) {
							d[x][y + 1] = z + dy[y];
							pq.push({ -d[x][y + 1],{x,y + 1} });
						}
					}
					pq.pop();
				}
				rep(ii, sx) {
					rep(jj, sy){
d2[ii][jj] = d[ii][jj];
                      //cout<<d[ii][jj]<<" ";
                    }
                  //cout<<endl;
				}

			}//階
			rep(ii, sx) {
				rep(jj, sy) {
					ans[ii][jj] += d2[ii][jj];
				}
			}

		}//ロボット
		fians = MOD * 2;
		rep(ii, sx) {
			rep(jj, sy) {
				if(!w[ii][jj])fians = min(fians, ans[ii][jj]);
			}
		}
		cout << fians << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 7270
memory_kb: 4864
final_rank: 13

code_snippet: #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1607"

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

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
#endif
//BEGIN CUT HERE
template<typename V>
V compress(V v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}
template<typename T>
map<T, int> dict(const vector<T> &v){
  map<T, int> res;
  for(int i=0;i<(int)v.size();i++)
    res[v[i]]=i;
  return res;
}
map<char, int> dict(const string &v){
  return dict(vector<char>(v.begin(),v.end()));
}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed ABC036_C(){
  int n;
  cin>>n;
  vector<int> a(n);
  for(int i=0;i<n;i++) cin>>a[i];
  auto v=compress(a);
  auto m=dict(v);
  for(int i=0;i<n;i++) cout<<m[a[i]]<<endl;
  return 0;
}
/*
  verified on 2018/08/26
  https://abc036.contest.atcoder.jp/tasks/abc036_c
*/

signed main(){
  ABC036_C();
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;
template <typename T>
using gtree = tree<T,null_type,less<T>,rb_tree_tag,
                   tree_order_statistics_node_update>;
// usage:
// find_by_order(int k):
// return the iterator of k-th smallest element (0-indexed)
// order_of_key(T key):  return the index of key in tree
//END CUT HERE
#ifndef call_from_test
signed ARC028_B(){
  using ll = long long;
  int n,k;
  cin>>n>>k;
  vector<int> xs(n);
  for(int i=0;i<n;i++) cin>>xs[i];
  map<int, int> mp;
  for(int i=0;i<n;i++) mp[xs[i]]=i+1;
  gtree<ll> G;
  for(int i=0;i<k-1;i++) G.insert(xs[i]);
  for(int i=k-1;i<n;i++){
    G.insert(xs[i]);
    auto key=*G.find_by_order(k-1);
    cout<<mp[key]<<endl;
  }
  return 0;
}

/*
  verified on 2019/12/09
  https://atcoder.jp/contests/arc028/tasks/arc028_2
*/

signed ARC033_C(){
  int q;
  cin>>q;
  gtree<int> G;
  while(q--){
    int t,x;
    cin>>t>>x;
    if(t==1) G.insert(x);
    if(t==2){
      int k=*G.find_by_order(x-1);
      G.erase(k);
      cout<<k<<endl;
    }
  }
  return 0;
}

/*
  verified on 2019/12/09
  https://atcoder.jp/contests/arc033/tasks/arc033_3
*/

signed main(){
  //ARC028_B();
  //ARC033_C();
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
#endif
//BEGIN CUT HERE
// prohibited to push an element less than popped one
// Key: int or long long
template<typename K,typename V>
struct RadixHeap{
  static constexpr int bit = sizeof(K) * 8;
  array<vector< pair<K, V> >, bit> vs;

  int size;
  K last;
  RadixHeap():size(0),last(0){}

  bool empty() const{return size==0;}

  inline int getbit(int a){
    return a?bit-__builtin_clz(a):0;
  }

  inline int getbit(long long a){
    return a?bit-__builtin_clzll(a):0;
  }

  void emplace(K key,V val){
    size++;
    vs[getbit(key^last)].emplace_back(key,val);
  }

  pair<K, V> pop(){
    if(vs[0].empty()){
      int idx=1;
      while(vs[idx].empty()) idx++;
      last=min_element(vs[idx].begin(),vs[idx].end())->first;
      for(auto &p:vs[idx]) vs[getbit(p.first^last)].emplace_back(p);
      vs[idx].clear();
    }
    --size;
    auto res=vs[0].back();
    vs[0].pop_back();
    return res;
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

const int BS = 8, BS2 = BS * 2;
const int msk = (1<<BS)-1;
const int MAX = 12 * (1<<BS) * (1<<BS);
int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

signed main(){
  int n;
  while(cin>>n,n){
    int m,k,r;
    cin>>m>>k>>r;
    vector<int> x(n),y(n),z(n);
    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];

    vector<int> vx(x),vy(y);
    for(int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }

    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](int cy,int cx,int f){return (f<<BS2)|(cy<<BS)|cx;};

    memset(hole,0,sizeof(hole));
    for(int p=0;p<m;p++)
      for(int i=my[v1[p]];i<=my[v2[p]];i++)
        for(int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;

    int sy=vy.size(),sx=vx.size();

    auto dijkstra=
      [&](int a)->void{
        vector<int> wy,wx;
        for(int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        int ty=zy.size(),tx=zx.size();

        vector<pair<int, int> > vs;
        {
          for(int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap<int, int> q;
          {
            int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.emplace(dist[v],v);
          }

          while(!q.empty()){
            auto p=q.pop();
            int v=p.second;
            if(dist[v]<p.first) continue;

            int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }

            auto push=
              [&](int ni,int nj,int nf){
                int u=idx(ni,nj,nf);
                int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);

                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;
                  q.emplace(dist[u],u);
                }
              };

            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }

            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {
          for(int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap<int, int> q;
          for(auto p:vs){
            int v=p.first,d=p.second;
            add[v]=d;
            q.emplace(add[v],v);
          }

          while(!q.empty()){
            auto p=q.pop();
            int v=p.second;
            if(add[v]<p.first) continue;

            int i=v>>BS,j=v&msk;
            auto push=
              [&](int ni,int nj){
                int u=(ni<<BS)|nj;
                int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;
                  q.emplace(add[u],u);
                }
              };

            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };

    memset(dp,0,sizeof(dp));
    for(int p=0;p<n;p++){
      dijkstra(p);
      for(int i=0;i<sy;i++)
        for(int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }

    long long ans=1e18;
    for(int i=0;i<sy;i++)
      for(int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7280
memory_kb: 7976
final_rank: 14

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 ADD 100

struct LOC{
	LOC(){
		x = y = 0;
	}
	LOC(int arg_x,int arg_y){
		x = arg_x;
		y = arg_y;
	}
	void set(int arg_x,int arg_y){
		x = arg_x;
		y = arg_y;
	}
	bool operator<(const struct LOC &arg) const{
		if(x != arg.x){

			return x < arg.x;
		}else{

			return y < arg.y;
		}
	}
	bool operator==(const struct LOC &arg) const{
		return x == arg.x && y == arg.y;
	}

	int x,y;
};


struct Info{

	LOC loc;
	int floor;
};

struct Data{
	int x_1,y_1,x_2,y_2;
};

struct State{
	State(LOC arg_loc,int arg_sum_cost,int arg_hole_index){
		loc.set(arg_loc.x,arg_loc.y);
		sum_cost = arg_sum_cost;
		hole_index = arg_hole_index;
	}
	LOC loc;
	int sum_cost,hole_index;
};

int num_robot,num_hole,K,R;
Info info[105];
Data data[55];
vector<int> HOLE[10];
vector<State> V[105],dp[2];


int calc_dist(LOC a, LOC b){

	return abs(a.x-b.x)+abs(a.y-b.y);
}

LOC calc_near_loc(LOC loc,Data data){

	LOC ret;

	if(loc.y < data.y_1){

		if(loc.x < data.x_1){

			ret.set(data.x_1,data.y_1);

		}else if(loc.x > data.x_2){

			ret.set(data.x_2,data.y_1);

		}else{

			ret.set(loc.x,data.y_1);
		}


	}else if(loc.y > data.y_2){

		if(loc.x < data.x_1){

			ret.set(data.x_1,data.y_2);

		}else if(loc.x > data.x_2){

			ret.set(data.x_2,data.y_2);

		}else{

			ret.set(loc.x,data.y_2);
		}

	}else{

		if(loc.x < data.x_1){

			ret.set(data.x_1,loc.y);

		}else if(loc.x > data.x_2){

			ret.set(data.x_2,loc.y);

		}else{

			ret.set(loc.x,loc.y);
		}
	}

	return ret;
}


void func(){

	for(int i = 0; i < num_robot; i++){

		V[i].clear();
	}

	scanf("%d %d %d",&num_hole,&K,&R);

	for(int i = 0; i < K; i++){

		HOLE[i].clear();
	}

	for(int i = 0; i < num_robot; i++){

		scanf("%d %d %d",&info[i].loc.x,&info[i].loc.y,&info[i].floor);
		info[i].floor--;
	}

	int floor;

	for(int i = 0; i < num_hole; i++){

		scanf("%d %d %d %d %d",&data[i].x_1,&data[i].y_1,&data[i].x_2,&data[i].y_2,&floor);
		floor--;
		HOLE[floor].push_back(i);
	}

	LOC tmp,next_loc;
	int index,next_cost,data_index;
	int CURRENT = 0,NEXT = 1;
	bool FLG;

	for(int loop = 0; loop < num_robot; loop++){

		dp[CURRENT].clear();
		dp[NEXT].clear();

		tmp.set(info[loop].loc.x,info[loop].loc.y);

		index = -1;

		for(int k = 0; k < HOLE[info[loop].floor].size(); k++){
			data_index = HOLE[info[loop].floor][k];

			if(data[data_index].x_1 <= tmp.x && data[data_index].x_2 >= tmp.x &&
					data[data_index].y_1 <= tmp.y && data[data_index].y_2 >= tmp.y){
				index = data_index;
				break;
			}
		}
		dp[CURRENT].push_back(State(tmp,0,index));

		for(int next_floor = info[loop].floor+1; next_floor <= K-1; next_floor++){
			for(int i = 0; i < dp[CURRENT].size(); i++){

				tmp = dp[CURRENT][i].loc;

				for(int k = 0; k < HOLE[next_floor].size(); k++){
					next_loc = calc_near_loc(tmp,data[HOLE[next_floor][k]]);

					FLG = false;
					for(int a = 0; a < dp[NEXT].size(); a++){
						if(dp[NEXT][a].loc.x == next_loc.x && dp[NEXT][a].loc.y == next_loc.y){
							FLG = true;
							index = a;
							break;
						}
					}

					next_cost = dp[CURRENT][i].sum_cost+calc_dist(tmp,next_loc)+ADD;

					if(!FLG){ //初登場

						dp[NEXT].push_back(State(next_loc,next_cost,HOLE[next_floor][k]));

					}else{

						if(dp[NEXT][index].sum_cost > next_cost){
							dp[NEXT][index].sum_cost = next_cost;
						}
					}
				}
			}

			dp[CURRENT].clear();

			for(int a = 0; a < dp[NEXT].size(); a++){
				FLG = true;
				for(int b = 0; b < dp[NEXT].size(); b++){
					if(a == b)continue;
					 if(dp[NEXT][b].sum_cost+calc_dist(dp[NEXT][a].loc,dp[NEXT][b].loc) <= dp[NEXT][a].sum_cost){
						FLG = false;
						break;
					}
				}
				if(FLG){
					dp[CURRENT].push_back(dp[NEXT][a]);
				}
			}

			dp[NEXT].clear();
		}

		for(int k = 0; k < dp[CURRENT].size(); k++){

			V[loop].push_back(dp[CURRENT][k]);
		}
	}

	vector<int> X,Y;
	for(int i = 0; i < num_robot; i++){

		X.push_back(info[i].loc.x);
		Y.push_back(info[i].loc.y);
	}

	for(int i = 0; i < num_hole; i++){

		X.push_back(data[i].x_1);
		X.push_back(data[i].x_1-1);
		X.push_back(data[i].x_2);
		X.push_back(data[i].x_2+1);
		Y.push_back(data[i].y_1);
		Y.push_back(data[i].y_1-1);
		Y.push_back(data[i].y_2);
		Y.push_back(data[i].y_2+1);
	}

	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());

	sort(Y.begin(),Y.end());
	Y.erase(unique(Y.begin(),Y.end()),Y.end());

	vector<LOC> CANDIDATE;

	for(int i = 0; i < X.size(); i++){
		for(int k = 0; k < Y.size(); k++){
			CANDIDATE.push_back(LOC(X[i],Y[k]));
		}
	}

	vector<LOC> WORK = CANDIDATE;
	CANDIDATE.clear();

	for(int i = 0; i < WORK.size(); i++){
		FLG = true;
		for(int a = 0; a < HOLE[K-1].size(); a++){
			index = HOLE[K-1][a];
			if(data[index].x_1 <= WORK[i].x && data[index].x_2 >= WORK[i].x &&
					data[index].y_1 <= WORK[i].y && data[index].y_2 >= WORK[i].y){
				FLG = false;
				break;
			}
		}
		if(FLG){
			CANDIDATE.push_back(WORK[i]);
		}
	}

	int ans = BIG_NUM;
	int minimum,tmp_sum,tmp_cost;

	for(int i = 0; i < CANDIDATE.size(); i++){
		tmp_sum = 0;
		for(int a = 0; a < num_robot; a++){
			minimum = BIG_NUM;
			for(int k = 0; k < V[a].size(); k++){
				tmp_cost = V[a][k].sum_cost+calc_dist(V[a][k].loc,CANDIDATE[i]);
				minimum = min(minimum,tmp_cost);
			}
			tmp_sum += minimum;
		}
		ans = min(ans,tmp_sum);
	}

	printf("%d\n",ans);
}

int main(){

	while(true){

		scanf("%d",&num_robot);
		if(num_robot == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 790
memory_kb: 4808
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = signed;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template<typename T,typename U> 
using gmap = cc_hash_table<T, U, hash<T> >;

//INSERT ABOVE HERE
template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
gmap<T, Int> dict(const vector<T> &v){
  gmap<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}

template< typename T >
struct RadixHeap
{
  vector< pair< Int, T > > v[33];
  Int size, last;

  RadixHeap() : size(0), last(0) {}

  bool empty() const { return size == 0; }

  inline Int getbit(Int a)
  {
    return a ? 32 - __builtin_clz(a) : 0;
  }

  void push(Int key, const T &value)
  {
    ++size;
    v[getbit(key ^ last)].emplace_back(key, value);
  }

  pair<Int, T > pop()
  {
    if(v[0].empty()) {
      Int idx = 1;
      while(v[idx].empty()) ++idx;
      last = min_element(begin(v[idx]), end(v[idx]))->first;
      for(auto &p : v[idx]) v[getbit(p.first ^ last)].emplace_back(p);
      v[idx].clear();
    }
    --size;
    auto ret = v[0].back();
    v[0].pop_back();
    return ret;
  }
};

const Int BS = 8, BS2 = BS * 2;
const Int msk = (1<<BS)-1;
const Int MAX = 12 * (1<<BS) * (1<<BS);
Int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

signed main(){
  Int n;
  while(cin>>n,n){
    Int m,k,r;
    cin>>m>>k>>r;
    vector<Int> x(n),y(n),z(n);
    for(Int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<Int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(Int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];
    
    vector<Int> vx(x),vy(y);
    for(Int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }
    
    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](Int cy,Int cx,Int f){return (f<<BS2)|(cy<<BS)|cx;};
  
    memset(hole,0,sizeof(hole));    
    for(Int p=0;p<m;p++)
      for(Int i=my[v1[p]];i<=my[v2[p]];i++)
        for(Int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;
    
    Int sy=vy.size(),sx=vx.size();
    
    auto dijkstra=
      [&](Int a)->void{                
        vector<Int> wy,wx;
        for(Int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;  
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);        
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        Int ty=zy.size(),tx=zx.size();
           
        vector<pair<Int, Int> > vs;
        {
          for(Int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap<Int> q;
          {
            Int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.push(dist[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(dist[v]<p.first) continue;
          
            Int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            Int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }
          
            auto push=
              [&](Int ni,Int nj,Int nf){
                Int u=idx(ni,nj,nf);
                Int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);
              
                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;             
                  q.push(dist[u],u);
                }
              };
          
            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }
            
            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {          
          for(Int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap<Int> q;          
          for(auto p:vs){
            Int v=p.first,d=p.second;
            add[v]=d;
            q.push(add[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(add[v]<p.first) continue;
          
            Int i=v>>BS,j=v&msk;            
            auto push=
              [&](Int ni,Int nj){
                Int u=(ni<<BS)|nj;
                Int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);              
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;             
                  q.push(add[u],u);
                }
              };
            
            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };
    
    memset(dp,0,sizeof(dp));          
    for(Int p=0;p<n;p++){
      dijkstra(p);               
      for(Int i=0;i<sy;i++)
        for(Int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }
        
    long long ans=1e18;
    for(Int i=0;i<sy;i++)
      for(Int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(Int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;          
  }
  return 0;
}
accuracy: 1
time_ms: 5810
memory_kb: 8008
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = signed;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template<typename T,typename U> 
using gmap = cc_hash_table<T, U, hash<T> >;

//INSERT ABOVE HERE
template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
gmap<T, Int> dict(const vector<T> &v){
  gmap<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}

pair< Int, Int > v[33][1<<18];
Int cur[33];

struct RadixHeap
{
  Int size, last;
  RadixHeap() : size(0), last(0) {
    for(Int i=0;i<33;i++) cur[i]=0;
  }

  bool empty() const { return size == 0; }

  inline Int getbit(Int a) {
    return a ? 32 - __builtin_clz(a) : 0;
  }

  void push(Int key, const Int &value) {
    ++size;
    Int uku=getbit(key^last);
    v[uku][cur[uku]++]=make_pair(key,value);
  }

  pair<Int, Int> pop() {
    if(!cur[0]) {      
      Int idx = 1;
      while(!cur[idx]) ++idx;
      last=min_element(v[idx],v[idx]+cur[idx])->first;
      for(Int i=0;i<cur[idx];i++){
        auto &p=v[idx][i];
        Int uku=getbit(p.first^last);
        v[uku][cur[uku]++]=p;
      }
      cur[idx]=0;
    }
    --size;
    auto ret = v[0][--cur[0]];
    return ret;
  }
};

const Int BS = 8, BS2 = BS * 2;
const Int msk = (1<<BS)-1;
const Int MAX = 12 * (1<<BS) * (1<<BS);
Int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

signed main(){
  Int n;
  while(cin>>n,n){
    Int m,k,r;
    cin>>m>>k>>r;
    vector<Int> x(n),y(n),z(n);
    for(Int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<Int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(Int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];
    
    vector<Int> vx(x),vy(y);
    for(Int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }
    
    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](Int cy,Int cx,Int f){return (f<<BS2)|(cy<<BS)|cx;};
  
    memset(hole,0,sizeof(hole));    
    for(Int p=0;p<m;p++)
      for(Int i=my[v1[p]];i<=my[v2[p]];i++)
        for(Int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;
    
    Int sy=vy.size(),sx=vx.size();
    
    auto dijkstra=
      [&](Int a)->void{                
        vector<Int> wy,wx;
        for(Int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;  
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);        
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        Int ty=zy.size(),tx=zx.size();
           
        vector<pair<Int, Int> > vs;
        {
          for(Int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap q;
          {
            Int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.push(dist[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(dist[v]<p.first) continue;
          
            Int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            Int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }
          
            auto push=
              [&](Int ni,Int nj,Int nf){
                Int u=idx(ni,nj,nf);
                Int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);
              
                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;             
                  q.push(dist[u],u);
                }
              };
          
            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }
            
            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {          
          for(Int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap q;          
          for(auto p:vs){
            Int v=p.first,d=p.second;
            add[v]=d;
            q.push(add[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(add[v]<p.first) continue;
          
            Int i=v>>BS,j=v&msk;            
            auto push=
              [&](Int ni,Int nj){
                Int u=(ni<<BS)|nj;
                Int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);              
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;             
                  q.push(add[u],u);
                }
              };
            
            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };
    
    memset(dp,0,sizeof(dp));          
    for(Int p=0;p<n;p++){
      dijkstra(p);               
      for(Int i=0;i<sy;i++)
        for(Int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }
        
    long long ans=1e18;
    for(Int i=0;i<sy;i++)
      for(Int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(Int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;          
  }
  return 0;
}
accuracy: 1
time_ms: 5950
memory_kb: 8208
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = signed;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
unordered_map<T, Int> dict(const vector<T> &v){
  unordered_map<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}

pair< Int, Int > v[33][1<<18];
Int cur[33];

struct RadixHeap
{
  Int size, last;
  RadixHeap() : size(0), last(0) {
    for(Int i=0;i<33;i++) cur[i]=0;
  }

  bool empty() const { return size == 0; }

  inline Int getbit(Int a) {
    return a ? 32 - __builtin_clz(a) : 0;
  }

  void push(Int key, const Int &value) {
    ++size;
    Int uku=getbit(key^last);
    v[uku][cur[uku]++]=make_pair(key,value);
  }

  pair<Int, Int> pop() {
    if(!cur[0]) {      
      Int idx = 1;
      while(!cur[idx]) ++idx;
      last=min_element(v[idx],v[idx]+cur[idx])->first;
      for(Int i=0;i<cur[idx];i++){
        auto &p=v[idx][i];
        Int uku=getbit(p.first^last);
        v[uku][cur[uku]++]=p;
      }
      cur[idx]=0;
    }
    --size;
    auto ret = v[0][--cur[0]];
    return ret;
  }
};

const Int BS = 8, BS2 = BS * 2;
const Int msk = (1<<BS)-1;
const Int MAX = 12 * (1<<BS) * (1<<BS);
Int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

//INSERT ABOVE HERE
signed main(){
  Int n;
  while(cin>>n,n){
    Int m,k,r;
    cin>>m>>k>>r;
    vector<Int> x(n),y(n),z(n);
    for(Int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<Int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(Int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];
    
    vector<Int> vx(x),vy(y);
    for(Int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }
    
    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](Int cy,Int cx,Int f){return (f<<BS2)|(cy<<BS)|cx;};
  
    memset(hole,0,sizeof(hole));    
    for(Int p=0;p<m;p++)
      for(Int i=my[v1[p]];i<=my[v2[p]];i++)
        for(Int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;
    
    Int sy=vy.size(),sx=vx.size();
    
    auto dijkstra=
      [&](Int a)->void{                
        vector<Int> wy,wx;
        for(Int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;  
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);        
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        Int ty=zy.size(),tx=zx.size();
           
        vector<pair<Int, Int> > vs;
        {
          for(Int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap q;
          {
            Int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.push(dist[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(dist[v]<p.first) continue;
          
            Int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            Int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }
          
            auto push=
              [&](Int ni,Int nj,Int nf){
                Int u=idx(ni,nj,nf);
                Int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);
              
                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;             
                  q.push(dist[u],u);
                }
              };
          
            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }
            
            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {          
          for(Int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap q;          
          for(auto p:vs){
            Int v=p.first,d=p.second;
            add[v]=d;
            q.push(add[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(add[v]<p.first) continue;
          
            Int i=v>>BS,j=v&msk;            
            auto push=
              [&](Int ni,Int nj){
                Int u=(ni<<BS)|nj;
                Int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);              
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;             
                  q.push(add[u],u);
                }
              };
            
            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };
    
    memset(dp,0,sizeof(dp));          
    for(Int p=0;p<n;p++){
      dijkstra(p);               
      for(Int i=0;i<sy;i++)
        for(Int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }
        
    long long ans=1e18;
    for(Int i=0;i<sy;i++)
      for(Int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(Int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;          
  }
  return 0;
}
accuracy: 1
time_ms: 6610
memory_kb: 8224
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = signed;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
map<T, Int> dict(const vector<T> &v){
  map<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}

pair< Int, Int > v[33][1<<18];
Int cur[33];

struct RadixHeap
{
  Int size, last;
  RadixHeap() : size(0), last(0) {
    for(Int i=0;i<33;i++) cur[i]=0;
  }

  bool empty() const { return size == 0; }

  inline Int getbit(Int a) {
    return a ? 32 - __builtin_clz(a) : 0;
  }

  void push(Int key, const Int &value) {
    ++size;
    Int uku=getbit(key^last);
    v[uku][cur[uku]++]=make_pair(key,value);
  }

  pair<Int, Int> pop() {
    if(!cur[0]) {      
      Int idx = 1;
      while(!cur[idx]) ++idx;
      last=min_element(v[idx],v[idx]+cur[idx])->first;
      for(Int i=0;i<cur[idx];i++){
        auto &p=v[idx][i];
        Int uku=getbit(p.first^last);
        v[uku][cur[uku]++]=p;
      }
      cur[idx]=0;
    }
    --size;
    auto ret = v[0][--cur[0]];
    return ret;
  }
};

const Int BS = 8, BS2 = BS * 2;
const Int msk = (1<<BS)-1;
const Int MAX = 12 * (1<<BS) * (1<<BS);
Int dist[MAX];
bool hole[MAX];
long long add[(1<<BS) * (1<<BS)];
long long dp[(1<<BS)][(1<<BS)];

//INSERT ABOVE HERE
signed main(){
  Int n;
  while(cin>>n,n){
    Int m,k,r;
    cin>>m>>k>>r;
    vector<Int> x(n),y(n),z(n);
    for(Int i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i];
    vector<Int> u1(m),v1(m),u2(m),v2(m),w(m);
    for(Int i=0;i<m;i++) cin>>u1[i]>>v1[i]>>u2[i]>>v2[i]>>w[i];
    
    vector<Int> vx(x),vy(y);
    for(Int p=0;p<m;p++){
      vx.emplace_back(u1[p]);
      vx.emplace_back(u2[p]);
      vy.emplace_back(v1[p]);
      vy.emplace_back(v2[p]);
      if(w[p]!=k) continue;
      if(u1[p]-1>=1) vx.emplace_back(u1[p]-1);
      if(u2[p]+1<=r) vx.emplace_back(u2[p]+1);
      if(v1[p]-1>=1) vy.emplace_back(v1[p]-1);
      if(v2[p]+1<=r) vy.emplace_back(v2[p]+1);
    }
    
    vx=compress(vx);
    vy=compress(vy);
    auto mx=dict(vx);
    auto my=dict(vy);

    // kokokara y yuusen
    auto idx=[&](Int cy,Int cx,Int f){return (f<<BS2)|(cy<<BS)|cx;};
  
    memset(hole,0,sizeof(hole));    
    for(Int p=0;p<m;p++)
      for(Int i=my[v1[p]];i<=my[v2[p]];i++)
        for(Int j=mx[u1[p]];j<=mx[u2[p]];j++)
          hole[idx(i,j,w[p])]=1;
    
    Int sy=vy.size(),sx=vx.size();
    
    auto dijkstra=
      [&](Int a)->void{                
        vector<Int> wy,wx;
        for(Int p=0;p<m;p++){
          if(w[p]<=z[a]) continue;  
          wy.emplace_back(v1[p]);
          wy.emplace_back(v2[p]);        
          wx.emplace_back(u1[p]);
          wx.emplace_back(u2[p]);
        }
        wy.emplace_back(y[a]);
        wx.emplace_back(x[a]);
        wy=compress(wy);
        wx=compress(wx);
        auto zy=dict(wy);
        auto zx=dict(wx);
        Int ty=zy.size(),tx=zx.size();
           
        vector<pair<Int, Int> > vs;
        {
          for(Int i=0;i<MAX;i++) dist[i]=INT_MAX;
          RadixHeap q;
          {
            Int v=idx(zy[y[a]],zx[x[a]],z[a]);
            dist[v]=0;
            q.push(dist[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(dist[v]<p.first) continue;
          
            Int f=v>>BS2,i=(v>>BS)&msk,j=v&msk;
            Int ai=my[wy[i]],aj=mx[wx[j]];
            if(f==k){
              vs.emplace_back((ai<<BS)|aj,dist[v]);
              continue;
            }
          
            auto push=
              [&](Int ni,Int nj,Int nf){
                Int u=idx(ni,nj,nf);
                Int c=abs(wy[ni]-wy[i])+abs(wx[nj]-wx[j]);
              
                if(dist[u]>dist[v]+c){
                  dist[u]=dist[v]+c;             
                  q.push(dist[u],u);
                }
              };
          
            if(hole[idx(ai,aj,f+1)]){
              push(i,j,f+1);
              continue;
            }
            
            if(i+1<ty) push(i+1,j,f);
            if(i-1>=0) push(i-1,j,f);
            if(j+1<tx) push(i,j+1,f);
            if(j-1>=0) push(i,j-1,f);
          }
        }
        {          
          for(Int i=0;i<(sy<<BS);i++) add[i]=INT_MAX;
          RadixHeap q;          
          for(auto p:vs){
            Int v=p.first,d=p.second;
            add[v]=d;
            q.push(add[v],v);
          }
          
          while(!q.empty()){
            auto p=q.pop();
            Int v=p.second;
            if(add[v]<p.first) continue;
          
            Int i=v>>BS,j=v&msk;            
            auto push=
              [&](Int ni,Int nj){
                Int u=(ni<<BS)|nj;
                Int c=abs(vy[ni]-vy[i])+abs(vx[nj]-vx[j]);              
                if(add[u]>add[v]+c){
                  add[u]=add[v]+c;             
                  q.push(add[u],u);
                }
              };
            
            if(i+1<sy) push(i+1,j);
            if(i-1>=0) push(i-1,j);
            if(j+1<sx) push(i,j+1);
            if(j-1>=0) push(i,j-1);
          }
        }
      };
    
    memset(dp,0,sizeof(dp));          
    for(Int p=0;p<n;p++){
      dijkstra(p);               
      for(Int i=0;i<sy;i++)
        for(Int j=0;j<sx;j++)
          dp[i][j]+=add[(i<<BS)|j];
    }
        
    long long ans=1e18;
    for(Int i=0;i<sy;i++)
      for(Int j=0;j<sx;j++)
        if(!hole[idx(i,j,k)]) chmin(ans,dp[i][j]);

    for(Int p=0;p<n;p++) ans+=(k-z[p])*100;
    cout<<ans<<endl;          
  }
  return 0;
}
accuracy: 1
time_ms: 7880
memory_kb: 8192
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF = INT_MAX;

template <class T>
pair<vector<T>, map<T, int> > compress(vector<T>& a) {
	vector<T> v;
	for(int i = 0; i < a.size(); i++) v.push_back(a[i]);
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	map<T, int> m;
	for(int i = 0; i < v.size(); i++) m[v[i]] = i;
	return { v, m };
}

struct edge {
	int x, y, z;
	int cost;
};

struct S {
	int x, y, z;
	int cost;

	bool operator <(const S& x) const{
		return cost > x.cost;
	}
};

using P = pair<int, int>;
vector<edge> G[300][300][11];
int dist[300][300][11];
int sum[300][300];

int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };

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

	int N, M, K, R;
	vector<int> X(100), Y(100), Z(100), xl(50), xr(50), yt(50), yb(50), h(50);
	while(cin >> N, N) {
		cin >> M >> K >> R;

		vector<int> xs, ys;
		for(int i = 0; i < N; i++) {
			cin >> X[i] >> Y[i] >> Z[i];
			xs.push_back(X[i]);
			ys.push_back(Y[i]);
		}
		for(int i = 0; i < M; i++) {
			cin >> xl[i] >> yt[i] >> xr[i] >> yb[i] >> h[i];
			xs.push_back(xl[i]);
			xs.push_back(xr[i]);
			ys.push_back(yt[i]);
			ys.push_back(yb[i]);
			if(h[i] == K) {
				if(xl[i] - 1 >= 1) xs.push_back(xl[i] - 1);
				if(xr[i] + 1 <= R) xs.push_back(xr[i] + 1);
				if(yt[i] - 1 >= 1) ys.push_back(yt[i] - 1);
				if(yb[i] + 1 <= R) ys.push_back(yb[i] + 1);
			}
		}

		auto zipX = compress(xs);
		auto zipY = compress(ys);

		int XN = zipX.first.size();
		int YN = zipY.first.size();

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					G[i][j][k].clear();
				}
			}
		}

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					int cx = zipX.first[i];
					int cy = zipY.first[j];
					if(k == K) {
						for(int l = 0; l < 4; l++) {
							if(i + dx[l] < 0 || XN <= i + dx[l]) continue;
							if(j + dy[l] < 0 || YN <= j + dy[l]) continue;
							int nx = zipX.first[i + dx[l]];
							int ny = zipY.first[j + dy[l]];
							int cost = abs(cx - nx) + abs(cy - ny);
							G[i][j][k].push_back({ i + dx[l], j + dy[l], k, cost });
						}
					}
					else {
						for(int m = 0; m < M; m++) {
							if(k + 1 != h[m]) continue;
							int cost = INF;
							int ii = 0, jj = 0;
							int li = zipX.second[xl[m]];
							int ri = zipX.second[xr[m]];
							int tj = zipY.second[yt[m]];
							int bj = zipY.second[yb[m]];
							if(li <= i && i <= ri && tj <= j && j <= bj) {
								if(cost > 100) {
									cost = 100;
									ii = i, jj = j;
								}
							}
							else if(li <= i && i <= ri) {
								if(cost > 100 + abs(cy - yt[m])){
									cost = 100 + abs(cy - yt[m]);
									ii = i, jj = tj;
								}
								if(cost > 100 + abs(cy - yb[m])) {
									cost = 100 + abs(cy - yb[m]);
									ii = i, jj = bj;
								}
							}
							else if(tj <= j && j <= bj) {
								if(cost > 100 + abs(cx - xl[m])){
									cost = 100 + abs(cx - xl[m]);
									ii = li, jj = j;
								}
								if(cost > 100 + abs(cx - xr[m])) {
									cost = 100 + abs(cx - xr[m]);
									ii = ri, jj = j;
								}
							}
							else {
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yt[m]);
									ii = li, jj = tj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yt[m]);
									ii = ri, jj = tj;
								}
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yb[m]);
									ii = li, jj = bj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yb[m]);
									ii = ri, jj = bj;
								}
							}
							G[i][j][k].push_back({ ii, jj, k + 1, cost });
						}
					}
				}
			}
		}

		vector<P> goal;
		for(int i = 0; i < XN; i++) {
			for(int j = 0; j < YN; j++) {
				int cx = zipX.first[i];
				int cy = zipY.first[j];
				bool ok = true;
				for(int m = 0; m < M; m++) {
					if(K == h[m] && xl[m] <= cx && cx <= xr[m] && yt[m] <= cy && cy <= yb[m]) {
						ok = false;
						break;
					}
				}
				if(ok) goal.push_back({ i, j });
			}
		}

		memset(sum, 0, sizeof sum);
		for(int n = 0; n < N; n++) {
			fill((int*)begin(dist), (int*)end(dist), INF);
			dist[zipX.second[X[n]]][zipY.second[Y[n]]][Z[n]] = 0;
			priority_queue<S> q;
			q.push({ zipX.second[X[n]],zipY.second[Y[n]], Z[n], 0 });
			while(q.size()) {
				S s = q.top();
				q.pop();
				if(dist[s.x][s.y][s.z] < s.cost) continue;
				for(auto& e : G[s.x][s.y][s.z]) {
					int ncost = s.cost + e.cost;
					if(dist[e.x][e.y][e.z] > ncost){
						dist[e.x][e.y][e.z] = ncost;
						q.push({ e.x, e.y, e.z, ncost });
					}
				}
			}
			for(auto& g : goal) {
				sum[g.first][g.second] += dist[g.first][g.second][K];
			}
		}
		int ans = INF;
		for(auto& g : goal) {
			ans = min(ans, sum[g.first][g.second]);
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 7980
memory_kb: 157944
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
//typedef long long int;
const int INF = INT_MAX;

template <class T>
pair<vector<T>, map<T, int> > compress(vector<T>& a) {
	vector<T> v;
	for(int i = 0; i < a.size(); i++) v.push_back(a[i]);
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	map<T, int> m;
	for(int i = 0; i < v.size(); i++) m[v[i]] = i;
	return { v, m };
}

struct edge {
	int x, y, z;
	int cost;
};

struct S {
	int x, y, z;
	int cost;

	bool operator <(const S& x) const{
		return cost > x.cost;
	}
};

using P = pair<int, int>;
vector<edge> G[300][300][11];
int dist[300][300][11];
int sum[300][300];

int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };

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

	int N, M, K, R;
	vector<int> X(100), Y(100), Z(100), xl(50), xr(50), yt(50), yb(50), h(50);
	while(cin >> N, N) {
		cin >> M >> K >> R;

		vector<int> xs, ys;
		for(int i = 0; i < N; i++) {
			cin >> X[i] >> Y[i] >> Z[i];
			xs.push_back(X[i]);
			ys.push_back(Y[i]);
		}
		for(int i = 0; i < M; i++) {
			cin >> xl[i] >> yt[i] >> xr[i] >> yb[i] >> h[i];
			xs.push_back(xl[i]);
			xs.push_back(xr[i]);
			ys.push_back(yt[i]);
			ys.push_back(yb[i]);
			if(h[i] == K) {
				if(xl[i] - 1 >= 1) xs.push_back(xl[i] - 1);
				if(xr[i] + 1 <= R) xs.push_back(xr[i] + 1);
				if(yt[i] - 1 >= 1) ys.push_back(yt[i] - 1);
				if(yb[i] + 1 <= R) ys.push_back(yb[i] + 1);
			}
		}

		auto zipX = compress(xs);
		auto zipY = compress(ys);

		int XN = zipX.first.size();
		int YN = zipY.first.size();

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					G[i][j][k].clear();
				}
			}
		}

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					int cx = zipX.first[i];
					int cy = zipY.first[j];
					if(k == K) {
						for(int l = 0; l < 4; l++) {
							if(i + dx[l] < 0 || XN <= i + dx[l]) continue;
							if(j + dy[l] < 0 || YN <= j + dy[l]) continue;
							int nx = zipX.first[i + dx[l]];
							int ny = zipY.first[j + dy[l]];
							int cost = abs(cx - nx) + abs(cy - ny);
							G[i][j][k].push_back({ i + dx[l], j + dy[l], k, cost });
						}
					}
					else {

						for(int m = 0; m < M; m++) {
							if(k + 1 != h[m]) continue;
							int cost = INF;
							int ii = 0, jj = 0;
							int li = zipX.second[xl[m]];
							int ri = zipX.second[xr[m]];
							int tj = zipY.second[yt[m]];
							int bj = zipY.second[yb[m]];
							if(li <= i && i <= ri && tj <= j && j <= bj) {
								if(cost > 100) {
									cost = 100;
									ii = i, jj = j;
								}
							}
							else if(li <= i && i <= ri) {
								if(cost > 100 + abs(cy - yt[m])){
									cost = 100 + abs(cy - yt[m]);
									ii = i, jj = tj;
								}
								if(cost > 100 + abs(cy - yb[m])) {
									cost = 100 + abs(cy - yb[m]);
									ii = i, jj = bj;
								}
							}
							else if(tj <= j && j <= bj) {
								if(cost > 100 + abs(cx - xl[m])){
									cost = 100 + abs(cx - xl[m]);
									ii = li, jj = j;
								}
								if(cost > 100 + abs(cx - xr[m])) {
									cost = 100 + abs(cx - xr[m]);
									ii = ri, jj = j;
								}
							}
							else {
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yt[m]);
									ii = li, jj = tj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yt[m]);
									ii = ri, jj = tj;
								}
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yb[m]);
									ii = li, jj = bj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yb[m]);
									ii = ri, jj = bj;
								}
							}
							G[i][j][k].push_back({ ii, jj, k + 1, cost });
						}
					}
				}
			}
		}

		vector<P> goal;
		for(int i = 0; i < XN; i++) {
			for(int j = 0; j < YN; j++) {
				int cx = zipX.first[i];
				int cy = zipY.first[j];
				bool ok = true;
				for(int m = 0; m < M; m++) {
					if(K == h[m] && xl[m] <= cx && cx <= xr[m] && yt[m] <= cy && cy <= yb[m]) {
						ok = false;
						break;
					}
				}
				if(ok) goal.push_back({ i, j });
			}
		}

		memset(sum, 0, sizeof sum);
		for(int n = 0; n < N; n++) {
			for(int k = 1; k <= K; k++) {
				for(int i = 0; i < XN; i++) {
					for(int j = 0; j < YN; j++) {
						dist[i][j][k] = INF;
					}
				}
			}
			dist[zipX.second[X[n]]][zipY.second[Y[n]]][Z[n]] = 0;
			priority_queue<S> q;
			q.push({ zipX.second[X[n]],zipY.second[Y[n]], Z[n], 0 });
			while(q.size()) {
				S s = q.top();
				q.pop();
				if(dist[s.x][s.y][s.z] < s.cost) continue;
				//cout << s.cost << endl;
				for(auto& e : G[s.x][s.y][s.z]) {
					int ncost = s.cost + e.cost;
					if(dist[e.x][e.y][e.z] > ncost){
						dist[e.x][e.y][e.z] = ncost;
						q.push({ e.x, e.y, e.z, ncost });
					}
				}
			}
			for(auto& g : goal) {
				sum[g.first][g.second] += dist[g.first][g.second][K];
			}
		}
		int ans = INF;
		for(auto& g : goal) {
			ans = min(ans, sum[g.first][g.second]);
		}
		cout << ans << endl;
	}

}
accuracy: 1
time_ms: 7230
memory_kb: 156840
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }

typedef pair<int, int> point;
#define X first
#define Y second

struct state {
	point pos;
	int cost;

	state(int x, int y, int cost_):pos(x, y), cost(cost_) {}

	bool operator<(const state &s) const {
		return cost < s.cost;
	}
};

inline bool in_range(int l, int r, int x) {
	return l <= x && x <= r;
}

inline int calc_best(int l, int r, int x) {
	return x < l ? l : r < x ? r : x;
}

inline int dist(const point &a, const point &b) {
	return abs(a.X - b.X) + abs(a.Y - b.Y);
}

void reduce(vector<state> &states) {
	sort(begin(states), end(states));

	const int n = states.size();
	vector<bool> ok(n, true);
	int last = 0;

	for(int i = 0; i < n; ++i) {
		if(ok[i]) {
			for(int j = i + 1; j < n; ++j) {
				if(ok[j] && states[j].cost - states[i].cost >= dist(states[i].pos, states[j].pos)) {
					ok[j] = false;
				}
			}
			states[last++] = states[i];
		}
	}

	states.erase(begin(states) + last, end(states));
}

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

	for(int n; cin >> n && n;) {
		int m, k, r;
		cin >> m >> k >> r;

		vector<int> cx, cy;
		vector<int> rx(n), ry(n), rz(n);

		for(int i = 0; i < n; ++i) {
			cin >> rx[i] >> ry[i] >> rz[i];
			cx.emplace_back(rx[i]);
			cy.emplace_back(ry[i]);
			--rz[i];
		}

		vector<vector<pair<point, point>>> holes(k);
		for(int i = 0; i < m; ++i) {
			int x1, y1, x2, y2, w;
			cin >> x1 >> y1 >> x2 >> y2 >> w;
			holes[w - 1].emplace_back(point(x1, y1), point(x2, y2));

			if(w == k) {
				if(x1 > 1) cx.emplace_back(x1 - 1);
				if(x2 < r) cx.emplace_back(x2 + 1);
				if(y1 > 1) cy.emplace_back(y1 - 1);
				if(y2 < r) cy.emplace_back(y2 + 1);
			}

			cx.emplace_back(x1);
			cx.emplace_back(x2);
			cy.emplace_back(y1);
			cy.emplace_back(y2);
		}

		vector<state> candidate;
		candidate.reserve(cx.size() * cy.size());
		sort(begin(cx), end(cx));
		sort(begin(cy), end(cy));
		cx.erase(unique(begin(cx), end(cx)), end(cx));
		cy.erase(unique(begin(cy), end(cy)), end(cy));

		for(const auto &x : cx) {
			for(const auto &y : cy) {
				for(const auto &hole : holes.back()) {
					if(in_range(hole.first.X, hole.second.X, x) && in_range(hole.first.Y, hole.second.Y, y)) {
						goto next_candidate;
					}
				}
				candidate.emplace_back(x, y, 0);
			next_candidate:;
			}
		}

		int ans = 0;
		for(int r_idx = 0; r_idx < n; ++r_idx) {
			ans += (k - (rz[r_idx] + 1)) * 100;

			vector<state> dp(1, state(rx[r_idx], ry[r_idx], 0));

			for(int i = rz[r_idx] + 1; i < k; ++i) {
				vector<state> next_dp;

				for(const auto &s : dp) {
					for(const auto &hole : holes[i]) {
						const int x = calc_best(hole.first.X, hole.second.X, s.pos.X);
						const int y = calc_best(hole.first.Y, hole.second.Y, s.pos.Y);
						next_dp.emplace_back(x, y, s.cost + dist(s.pos, make_pair(x, y)));
					}
				}

				dp = move(next_dp);
				reduce(dp);
			}

			for(auto &c : candidate) {
				int min_cost = INT_MAX;

				for(const auto &e : dp) {
					chmin(min_cost, e.cost + dist(c.pos, e.pos));
				}
				c.cost += min_cost;
			}
		}

		ans += min_element(begin(candidate), end(candidate))->cost;
		cout << ans << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 420
memory_kb: 3692
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <cstdlib>
#include <queue>
#include <utility>
using namespace std;

typedef long long LL;

const LL INF = 1LL << 50;

struct hole;

vector<int> xs, ys;
vector<vector<hole>> vhls;
int szx, szy;

inline int encode(int x, int y){
	return x * szy + y;
}
inline void decode(int e, int &x, int &y){
	x = e / szy;
	y = e % szy;
}

struct robot{
	int x, y, z;
	robot(int x_, int y_, int z_)
	: x(x_), y(y_), z(z_) {
		xs.push_back(x);
		ys.push_back(y);
	}
};

struct hole{
	int xl, yl, xr, yr;

	hole(int u1, int v1, int u2, int v2, int s)
	: xl(u1), yl(v1), xr(u2), yr(v2)
	{
		xs.push_back(u1);
		xs.push_back(u2);
		ys.push_back(v1);
		ys.push_back(v2);

		if(s >= 0){
			if(u1 > 1){ xs.push_back(u1 - 1); }
			if(u2 < s){ xs.push_back(u2 + 1); }

			if(v1 > 1){ ys.push_back(v1 - 1); }
			if(v2 < s){ ys.push_back(v2 + 1); }
		}
	}

	bool in(int x, int y) const{
		return xl <= x && x <= xr && yl <= y && y <= yr;
	}

	void nearest(int x, int y, int &nx, int &ny) const{
		if(x < xl){ nx = xl; }
		else if(x > xr){ nx = xr; }
		else{ nx = x; }

		if(y < yl){ ny = yl; }
		else if(y > yr){ ny = yr; }
		else{ ny = y; }
	}
};

struct cmpfst{
	template <class T, class U>
	bool operator() (const pair<T,U> &p, const pair<T,U> &q) const{
		return p.first < q.first;
	}
};

void compress(const vector<int> &v, int &t){
	t = lower_bound(v.begin(), v.end(), t) - v.begin();
}

vector<LL> calc(const robot &rb){
	unordered_map<int,LL> mp1, mp2;
	mp1.emplace(encode(rb.x, rb.y), 0);

	int hg = vhls.size() - 1;
	for(int z = rb.z + 1; z <= hg; ++z){
		for(auto p : mp1){
			int x, y, nx, ny;
			decode(p.first, x, y);
			for(const auto &h : vhls[z]){
				h.nearest(x, y, nx, ny);
				LL &t = mp2.emplace(encode(nx, ny), INF).first->second;
				t = min(t, p.second + abs(xs[x] - xs[nx]) + abs(ys[y] - ys[ny]) + 100);
			}
		}
		mp1.swap(mp2);
		mp2.clear();
	}

	typedef pair<LL,int> pli;

	vector<LL> ret(szx * szy, INF);
	priority_queue<pli,vector<pli>,cmpfst> pq;
	for(auto p : mp1){
		ret[p.first] = p.second;
		pq.emplace(-p.second, p.first);
	}

	int dd[5] = {0, -1, 0, 1, 0};

	while(!pq.empty()){
		auto p = pq.top();
		pq.pop();
		if(ret[p.second] != -p.first){ continue; }
		int x, y;
		decode(p.second, x, y);
		for(int i = 0; i < 4; ++i){
			int nx = x + dd[i];
			int ny = y + dd[i + 1];
			if(nx < 0 || nx >= szx || ny < 0 || ny >= szy){ continue; }
			int e = encode(nx, ny);
			LL c = -p.first + abs(xs[x] - xs[nx]) + abs(ys[y] - ys[ny]);
			if(ret[e] > c){
				ret[e] = c;
				pq.emplace(-c, e);
			}
		}
	}

	return ret;
}

int main(){
	ios::sync_with_stdio(false);

	int n, m, k, s;

	vector<robot> rbs;
	rbs.reserve(100);

	while(cin >> n >> m >> k >> s){
		xs = ys = {1, s};

		rbs.clear();
		vhls.clear();
		vhls.resize(k + 1);

		for(int i = 0; i < n; ++i){
			int x, y, z;
			cin >> x >> y >> z;
			rbs.emplace_back(x, y, z);
		}
		for(int i = 0; i < m; ++i){
			int u1, v1, u2, v2, w;
			cin >> u1 >> v1 >> u2 >> v2 >> w;
			vhls[w].emplace_back(u1, v1, u2, v2, w == k ? s : -1);
		}

		sort(xs.begin(), xs.end());
		xs.erase(unique(xs.begin(), xs.end()), xs.end());
		sort(ys.begin(), ys.end());
		ys.erase(unique(ys.begin(), ys.end()), ys.end());
		szx = xs.size();
		szy = ys.size();

		for(auto &r : rbs){
			compress(xs, r.x);
			compress(ys, r.y);
		}
		for(auto &hls : vhls){
			for(auto &h : hls){
				compress(xs, h.xl);
				compress(xs, h.xr);
				compress(ys, h.yl);
				compress(ys, h.yr);
			}
		}

		vector<vector<LL>> tms;
		for(int i = 0; i < n; ++i){
			tms.emplace_back(calc(rbs[i]));
		}

		LL ans = INF;
		for(int x = 0; x < szx; ++x){
			for(int y = 0; y < szy; ++y){
				bool ok = true;
				for(const auto &h : vhls.back()){
					if(h.in(x, y)){
						ok = false;
						break;
					}
				}
				if(ok){
					int e = encode(x, y);
					LL sum = 0;
					for(int i = 0; i < n; ++i){
						sum += tms[i][e];
					}
					ans = min(ans, sum);
				}
			}
		}
		if(ans == INF){ ans = -1; }
		cout << ans << '\n';
	}
}
accuracy: 1
time_ms: 3850
memory_kb: 41736
final_rank: 8