#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define v vector
#define lp(i, s, e) for (int i = s; i < e; ++i)
#define tpl tuple<ll, ll, ll, ll, ll, ll>
const int MAX_Y = 600005;
int seg[4 * MAX_Y];
int lazy_seg[4 * MAX_Y];
void push(int node, int l, int r) {
if (lazy_seg[node] != -1) {
seg[node] = lazy_seg[node];
if (l != r) {
lazy_seg[2 * node] = lazy_seg[node];
lazy_seg[2 * node + 1] = lazy_seg[node];
}
lazy_seg[node] = -1;
}
}
void update(int node, int l, int r, int ql, int qr, int val) {
push(node, l, r);
if (l > qr || r < ql)
return;
if (l >= ql && r <= qr) {
lazy_seg[node] = val;
push(node, l, r);
return;
}
int mid = (l + r) / 2;
update(2 * node, l, mid, ql, qr, val);
update(2 * node + 1, mid + 1, r, ql, qr, val);
}
int query(int node, int l, int r, int pos) {
push(node, l, r);
if (l == r)
return seg[node];
int mid = (l + r) / 2;
if (pos <= mid)
return query(2 * node, l, mid, pos);
return query(2 * node + 1, mid + 1, r, pos);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
memset(lazy_seg, -1, sizeof(lazy_seg));
memset(seg, -1, sizeof(seg));
ll dest_x, dest_y;
cin >> dest_x >> dest_y;
ll n;
cin >> n;
vector<tpl> vec;
v<ll> y_val;
y_val.push_back(dest_y);
y_val.push_back(0);
v<ll> B_left(n + 2), B_right(n + 2), B_bottom(n + 2), B_top(n + 2);
lp(i, 0, n) {
ll a, b, c, d;
cin >> a >> b >> c >> d;
if (a >= dest_x)
continue;
c = min(c, dest_x);
B_left[i + 1] = a;
B_right[i + 1] = c;
B_bottom[i + 1] = b;
B_top[i + 1] = d;
y_val.push_back(b);
y_val.push_back(d);
y_val.push_back(b - 1);
y_val.push_back(d + 1);
vec.push_back({a, b, c, d, 0, i + 1});
vec.push_back({c, d, a, b, 1, i + 1});
}
sort(y_val.begin(), y_val.end());
y_val.erase(unique(y_val.begin(), y_val.end()), y_val.end());
int sz = y_val.size();
auto get_y = [&](ll y) {
return lower_bound(y_val.begin(), y_val.end(), y) - y_val.begin();
};
vec.push_back({0, 0, 0, 0, 1, 0});
sort(vec.begin(), vec.end());
update(1, 0, sz - 1, 0, sz - 1, n + 1);
v<v<ll>> dp(n + 2, v<ll>(2, 0));
v<v<int>> next_hit(n + 2, v<int>(2, 0));
auto get_dist = [&](ll y, int hit, ll &cost) {
if (hit == n + 1) {
cost = abs(y - dest_y);
return;
}
ll cost_b = abs(y - (B_bottom[hit] - 1)) + dp[hit][0];
ll cost_t = abs(y - (B_top[hit] + 1)) + dp[hit][1];
cost = min(cost_b, cost_t);
};
ll ans = 1e18;
int start_hit = -1;
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
auto [cx, cy, ox, oy, type, idx] = *it;
if (type == 1) {
if (idx == 0) {
start_hit = query(1, 0, sz - 1, get_y(0));
ll cost;
get_dist(0, start_hit, cost);
ans = dest_x + cost;
} else {
int h1 = query(1, 0, sz - 1, get_y(oy - 1));
next_hit[idx][0] = h1;
get_dist(oy - 1, h1, dp[idx][0]);
int h2 = query(1, 0, sz - 1, get_y(cy + 1));
next_hit[idx][1] = h2;
get_dist(cy + 1, h2, dp[idx][1]);
}
} else {
update(1, 0, sz - 1, get_y(cy), get_y(oy), idx);
}
}
cout << ans << "\n";
ll curr_X = 0, curr_Y = 0;
int curr_hit = start_hit;
vector<pair<ll, ll>> moves;
auto add_move = [&](ll dx, ll dy) {
if (dx == 0 && dy == 0)
return;
if (!moves.empty()) {
auto &last = moves.back();
if ((last.first == 0 && dx == 0) || (last.second == 0 && dy == 0)) {
last.first += dx;
last.second += dy;
if (last.first == 0 && last.second == 0)
moves.pop_back();
return;
}
}
moves.push_back({dx, dy});
};
while (curr_hit != n + 1) {
ll nx = B_left[curr_hit];
add_move(nx - curr_X, 0);
curr_X = nx;
ll cost_b = abs(curr_Y - (B_bottom[curr_hit] - 1)) + dp[curr_hit][0];
ll cost_t = abs(curr_Y - (B_top[curr_hit] + 1)) + dp[curr_hit][1];
if (cost_b < cost_t) {
ll ny = B_bottom[curr_hit] - 1;
add_move(0, ny - curr_Y);
curr_Y = ny;
ll rx = B_right[curr_hit];
add_move(rx - curr_X, 0);
curr_X = rx;
curr_hit = next_hit[curr_hit][0];
} else {
ll ny = B_top[curr_hit] + 1;
add_move(0, ny - curr_Y);
curr_Y = ny;
ll rx = B_right[curr_hit];
add_move(rx - curr_X, 0);
curr_X = rx;
curr_hit = next_hit[curr_hit][1];
}
}
add_move(dest_x - curr_X, 0);
add_move(0, dest_y - curr_Y);
vector<pair<ll, ll>> final_moves;
for (auto m : moves) {
if (m.first != 0 || m.second != 0) {
final_moves.push_back(m);
}
}
cout << final_moves.size() << "\n";
for (auto [dx, dy] : final_moves) {
cout << dx << " " << dy << "\n";
}
}