#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define v vector
#define lp(i, s, e) for (ll i = s; i < e; ++i)
#define tpl tuple<ll, ll, ll, ll, ll, ll>
struct Seg {
Seg *left = nullptr, *right = nullptr;
int l, r, mid;
int id = -1, lazy = -1;
Seg(int l, int r) : l(l), r(r), mid((l + r) / 2) {}
void ensure() {
if (l == r)
return;
if (left == nullptr) {
left = new Seg(l, mid);
right = new Seg(mid + 1, r);
}
}
void push() {
if (lazy == -1)
return;
id = lazy;
if (l != r) {
ensure();
left->lazy = lazy;
right->lazy = lazy;
}
lazy = -1;
}
int q(int pos) {
push();
if (l == r)
return id;
ensure();
if (pos <= mid)
return left->q(pos);
return right->q(pos);
}
void update(int a, int b, int V) {
push();
if (l > b || r < a)
return;
if (l >= a && r <= b) {
lazy = V;
push();
return;
}
ensure();
left->update(a, b, V);
right->update(a, b, V);
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
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_bottom(1), B_top(1), B_left(1), B_right(1);
ll cnt = 0;
lp(i, 0, n) {
ll a, b, c, d;
cin >> a >> b >> c >> d;
ll lx = min(a, c), rx = max(a, c);
ll ly = min(b, d), ry = max(b, d);
if (lx >= dest_x)
continue;
rx = min(rx, dest_x);
++cnt;
B_left.push_back(lx);
B_right.push_back(rx);
B_bottom.push_back(ly);
B_top.push_back(ry);
y_val.push_back(ly);
y_val.push_back(ry);
y_val.push_back(ly - 1);
y_val.push_back(ry + 1);
vec.push_back({lx, ly, rx, ry, 0, cnt});
vec.push_back({rx, ry, lx, ly, 1, cnt});
}
sort(y_val.begin(), y_val.end());
y_val.erase(unique(y_val.begin(), y_val.end()), y_val.end());
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());
Seg seg(0, (int)y_val.size() - 1);
seg.update(0, (int)y_val.size() - 1, cnt + 1);
v<v<ll>> dp(cnt + 2, v<ll>(2, 0));
v<v<int>> nxt(cnt + 2, v<int>(2, cnt + 1));
v<v<int>> take(cnt + 2, v<int>(2, -1));
auto get_dist = [&](ll y, int hit, int &go) {
if (hit == cnt + 1) {
go = -1;
return abs(y - dest_y);
}
ll cost_bottom = abs(y - (B_bottom[hit] - 1)) + dp[hit][0];
ll cost_top = abs(y - (B_top[hit] + 1)) + dp[hit][1];
if (cost_bottom <= cost_top) {
go = 0;
return cost_bottom;
} else {
go = 1;
return cost_top;
}
};
ll ans = (ll)4e18;
int start_hit = cnt + 1, start_take = -1;
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
auto [cx, cy, ox, oy, type, idx] = *it;
if (type == 1) {
if (idx == 0) {
int hit = seg.q(get_y(0));
start_hit = hit;
ans = dest_x + get_dist(0, hit, start_take);
} else {
ll y_bottom = oy;
ll y_top = cy;
int hit1 = seg.q(get_y(y_bottom - 1));
nxt[idx][0] = hit1;
dp[idx][0] = get_dist(y_bottom - 1, hit1, take[idx][0]);
int hit2 = seg.q(get_y(y_top + 1));
nxt[idx][1] = hit2;
dp[idx][1] = get_dist(y_top + 1, hit2, take[idx][1]);
}
} else {
ll y_bottom = cy;
ll y_top = oy;
seg.update(get_y(y_bottom), get_y(y_top), idx);
}
}
v<pair<ll, ll>> moves;
auto add_move = [&](ll dx, ll dy) {
if (dx == 0 && dy == 0)
return;
if (!moves.empty()) {
auto &[px, py] = moves.back();
if (px == 0 && dx == 0) {
py += dy;
if (py == 0)
moves.pop_back();
return;
}
if (py == 0 && dy == 0) {
px += dx;
if (px == 0)
moves.pop_back();
return;
}
}
moves.push_back({dx, dy});
};
ll cur_x = 0, cur_y = 0;
int hit = start_hit, dir = start_take;
while (hit != cnt + 1) {
ll stop_x = B_left[hit] - 1;
add_move(stop_x - cur_x, 0);
cur_x = stop_x;
ll need_y = (dir == 0 ? B_bottom[hit] - 1 : B_top[hit] + 1);
add_move(0, need_y - cur_y);
cur_y = need_y;
ll nx = B_right[hit] + 1;
add_move(nx - cur_x, 0);
cur_x = nx;
int ndir = take[hit][dir];
int nhit = nxt[hit][dir];
hit = nhit;
dir = ndir;
}
add_move(dest_x - cur_x, 0);
cur_x = dest_x;
add_move(0, dest_y - cur_y);
cur_y = dest_y;
cout << ans << "\n";
cout << moves.size() << "\n";
for (auto [dx, dy] : moves)
cout << dx << " " << dy << "\n";
}