#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <random>
#include <algorithm>
#include <optional>
#include <chrono>
#include <set>
#include <iomanip>
using namespace std;

int64_t max_value = 1000000000ll * 1000000000ll;

struct TimeLogger {
    chrono::steady_clock::time_point tp;
    TimeLogger(string str) : message(move(str)) {
        tp = chrono::steady_clock::now();
    }
    ~TimeLogger() {
        auto cur = chrono::steady_clock::now();
        auto dur = cur - tp;
        auto millis = chrono::duration_cast<chrono::milliseconds>(dur);
        cout << message << ": " << millis.count() << endl;
    }
    string message;
};

struct Point {
    int64_t x, y, i;
};
std::ostream& operator<<(std::ostream& ostr, const Point& pt) {
    return ostr << "{" << pt.x << ", " << pt.y << "; " << pt.i << "}";
}

int64_t dist2(const Point& a, const Point& b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

int64_t manhattan(const Point& a, const Point& b) {
    return abs(a.x - b.x) + abs(a.y - b.y);
}

uint64_t get_hash(pair<int64_t, int64_t> p) {
    return 1ll * p.first * max_value + p.second;
}

struct TwoClosestPoints {
    std::unordered_map<uint64_t, vector<int64_t>> umap;
    vector<Point> values;
    int64_t cell_size_sqr = max_value;

    pair<int64_t, int64_t> get_cur_index(const Point& point) {
        auto cur_size = max(cell_size_sqr, 1ll);
        return { point.x / sqrt(cur_size), point.y / sqrt(cur_size) };
    }

    void rebuild(int64_t new_cell_size_sqr) {
        cell_size_sqr = new_cell_size_sqr;
        umap.clear();
        for (int64_t i = 0; i < values.size(); ++i) {
            umap[get_hash(get_cur_index(values[i]))].push_back(i);
        }
    }

    optional<Point> get_closest_for_point(const Point& point) {
        optional<Point> result;
        int64_t max_dist2 = cell_size_sqr;
        auto index = get_cur_index(point);
        for (int64_t dx = -1; dx <= 1; ++dx) {
            for (int64_t dy = -1; dy <= 1; ++dy) {
                pair<int64_t, int64_t> cindex{ index.first + dx, index.second + dy };
                auto iter = umap.find(get_hash(cindex));
                if (iter == umap.end()) continue;
                for (auto i : iter->second) {
                    int64_t cur = dist2(values[i], point);
                    if (max_dist2 > cur) {
                        max_dist2 = cur;
                        result = values[i];
                    }
                }
            }
        }
        return result;
    }

    void add_point(const Point& point) {
        umap[get_hash(get_cur_index(point))].push_back(values.size());
        values.push_back(point);
    }
};

pair<Point, Point> solve_fast(const vector<Point>& vn_, const vector<Point>& vm_) {
    mt19937 rng(0);
    auto vn = vn_;
    auto vm = vm_;
    shuffle(vn.begin(), vn.end(), rng);
    shuffle(vm.begin(), vm.end(), rng);

    TwoClosestPoints set1;
    TwoClosestPoints set2;

    int64_t min_dist = max_value;
    optional<Point> result1;
    optional<Point> result2;

    for (int64_t i = 0; i < max(vn.size(), vm.size()); ++i) {
        bool changed = false;
        if (i < vn.size()) {
            set1.add_point(vn[i]);
            auto closest = set2.get_closest_for_point(vn[i]);
            if (closest.has_value() && dist2(vn[i], closest.value()) < min_dist) {
                min_dist = dist2(vn[i], closest.value());
                result1 = vn[i];
                result2 = closest;
                changed = true;
            }
        }
        if (i < vm.size()) {
            set2.add_point(vm[i]);
            auto closest = set1.get_closest_for_point(vm[i]);
            if (closest.has_value() && dist2(vm[i], closest.value()) < min_dist) {
                min_dist = dist2(vm[i], closest.value());
                result1 = closest;
                result2 = vm[i];
                changed = true;
            }
        }
        if (changed) {
            set1.rebuild(min_dist);
            set2.rebuild(min_dist);
        }
    }
    return pair{ result1.value(), result2.value() };
}


pair<Point, Point> solve_slow(vector<Point> vn, vector<Point> vm) {
    Point result1 = vn[0];
    Point result2 = vm[0];
    for (int64_t i = 0; i < vn.size(); ++i) {
        for (int64_t j = 0; j < vm.size(); ++j) {
            if (dist2(vn[i], vm[j]) < dist2(result1, result2)) {
                result1 = vn[i];
                result2 = vm[j];
            }
        }
    }
    return pair{ result1, result2 };
}

pair<Point, Point> solve_random(vector<Point> vn, vector<Point> vm) {
    int64_t max_iter_count = 10000000;
    if (vn.size() * vm.size() < max_iter_count) {
        return solve_slow(vn, vm);
    }
    std::optional<pair<Point, Point>> result;
    mt19937 rng(12345);
    std::uniform_int_distribution<int64_t> uid1(0, vn.size() - 1);
    std::uniform_int_distribution<int64_t> uid2(0, vm.size() - 1);
    for (int64_t i = 0; i < max_iter_count; ++i) {
        int64_t i1 = uid1(rng);
        int64_t i2 = uid2(rng);
        const Point& p1 = vn[i1];
        const Point& p2 = vm[i2];
        if (!result.has_value() || dist2(p1, p2) < dist2(result->first, result->second)) {
            result = pair<Point, Point>{ p1, p2 };
        }
    }
    return result.value();
}

pair<Point, Point> solve_random_2(vector<Point> vn, vector<Point> vm) {
    mt19937 rng(12345);
    std::uniform_int_distribution<int64_t> uid1(0, vn.size() - 1);
    std::uniform_int_distribution<int64_t> uid2(0, vm.size() - 1);
    std::optional<pair<Point, Point>> result;
    for (int64_t i = 0; i < 1000; ++i) {
        int64_t i1 = uid1(rng);
        int64_t i2 = uid2(rng);
        const Point& p1 = vn[i1];
        const Point& p2 = vm[i2];
        set<int64_t> s1, s2;
        s1.insert(i1);
        s2.insert(i2);
        while (true) {
            auto iter_new_i2 = std::min_element(vm.begin(), vm.end(),
                [&](const Point& p1, const Point& p2) {
                    return dist2(vn[i1], p1) < dist2(vn[i1], p2);
                });
            auto iter_new_i1 = std::min_element(vn.begin(), vn.end(),
                [&](const Point& p1, const Point& p2) {
                    return dist2(*iter_new_i2, p1) < dist2(*iter_new_i2, p2);
                });
            int64_t new_i1 = iter_new_i1 - vn.begin();
            int64_t new_i2 = iter_new_i2 - vm.begin();
            if (dist2(vn[new_i1], vm[new_i2]) < dist2(vn[i1], vm[i2])) {
                swap(new_i1, i1);
                swap(new_i2, i2);
                if (!result.has_value() ||
                    dist2(vn[i1], vm[i2]) < dist2(result->first, result->second)) {
                    result = pair<Point, Point>{ vn[i1], vm[i2] };
                }
            }
            else {
                break;
            }
        }
    }
    return result.value();
}

pair<Point, Point> solve_slow_manhattan(vector<Point> vn, vector<Point> vm) {
    Point result1 = vn[0];
    Point result2 = vm[0];
    for (int64_t i = 0; i < vn.size(); ++i) {
        for (int64_t j = 0; j < vm.size(); ++j) {
            if (manhattan(vn[i], vm[j]) < manhattan(result1, result2)) {
                result1 = vn[i];
                result2 = vm[j];
            }
        }
    }
    return pair{ result1, result2 };
}

pair<vector<Point>, vector<Point>> input_from_console() {
    int64_t n, m;
    vector<Point> vn;
    vector<Point> vm;
    cin >> n;
    cin >> m;
    for (int i = 0; i < n; ++i) {
        vn.emplace_back();
        vn.back().i = i;
        cin >> vn.back().x >> vn.back().y;
    }
    for (int i = 0; i < m; ++i) {
        vm.emplace_back();
        vm.back().i = i;
        cin >> vm.back().x >> vm.back().y;
    }
    return { vn, vm };
}

void output_to_console(vector<Point> vn, vector<Point> vm) {
    cout << vn.size() << " " << vm.size() << endl;
    for (const auto& pt : vn) {
        cout << pt.x << " " << pt.y << endl;
    }
    for (const auto& pt : vm) {
        cout << pt.x << " " << pt.y << endl;
    }
}

pair<vector<Point>, vector<Point>> generate_input(mt19937_64& rng) {
    int64_t max_size_n = 100000;
    int64_t max_size_m = 100000;
    int64_t max_coord = 100000000;
    vector<Point> vn, vm;
    uniform_int_distribution<int64_t> uid_coord(-max_coord, max_coord);
    vn.resize(max_size_n);
    vm.resize(max_size_m);
    // vn.resize(uid(rng));
    // vm.resize(uid(rng));
    for (int64_t i = 0; i < vn.size(); ++i) {
        vn[i].i = i;
        vn[i].x = uid_coord(rng);
        vn[i].y = uid_coord(rng);
    }
    for (int64_t i = 0; i < vm.size(); ++i) {
        vm[i].i = i;
        vm[i].x = uid_coord(rng);
        vm[i].y = uid_coord(rng);
    }
    return { vn, vm };
}

bool inside_borders(const Point& p) {
    return -10000 <= p.x && p.x <= 10000 &&
        -10000 <= p.y && p.y <= 10000;
}

pair<vector<Point>, vector<Point>> generate_antimanhattan_input(mt19937_64& rng) {
    int64_t iter_num = 30000;
    int64_t max_coord = 100000000;
    int64_t step = 800000;
    vector<Point> vn, vm;
    for (int64_t i = 0; i < 2; ++i) {
        int64_t cnt = 0;
        int64_t val = 0;
        for (int64_t x_coord = -max_coord + step/2; x_coord + step/2 <= max_coord; x_coord += step) {
            for (int64_t y_coord = -max_coord + step/2; y_coord + step/2 <= max_coord; y_coord += step) {
                ++val;
                if ((val + i) % 2 == 0) continue;
                if (cnt > iter_num) break;
                vn.push_back(Point{ x_coord, y_coord, 0 });
                int64_t dst = rng() % 100000 + 1;
                bool pos_x = rng() % 2;
                bool pos_y = rng() % 2;
                bool x_or_y = rng() % 2;
                Point p_one{ dst, dst, 0 };
                Point p_two{ dst * 2, dst * 2, 0 };
                if (!pos_x) p_one.x *= -1;
                if (!pos_y) p_one.y *= -1;
                if (pos_x) p_two.x *= -1;
                if (pos_y) p_two.y *= -1;
                if (x_or_y) p_two.x = 0;
                if (!x_or_y) p_two.y = 0;
                p_one.x += x_coord;
                p_one.y += y_coord;
                p_two.x += x_coord;
                p_two.y += y_coord;
                vm.push_back(p_one);
                vm.push_back(p_two);
                ++cnt;
            }
        }
        swap(vn, vm);
    }
    shuffle(vn.begin(), vn.end(), rng);
    shuffle(vm.begin(), vm.end(), rng);
    return { vn, vm };
}

pair<vector<Point>, vector<Point>> generate_antimanhattan_input_2(mt19937_64& rng) {
    int64_t iter_num = 24000;
    int64_t max_coord = 100000000;
    int64_t step = 800000;
    vector<Point> vn, vm;
    for (int64_t i = 0; i < 2; ++i) {
        int64_t cnt = 0;
        int64_t val = 0;
        for (int64_t x_coord = -max_coord + step/2; x_coord + step/2 <= max_coord; x_coord += step) {
            for (int64_t y_coord = -max_coord + step/2; y_coord + step/2 <= max_coord; y_coord += step) {
                ++val;
                if ((val + i) % 2 == 0) continue;
                if (cnt > iter_num) break;
                vn.push_back(Point{ x_coord, y_coord, 0 });
                int64_t dst = rng() % 100000 + 2;
                bool pos_x = rng() % 2;
                bool pos_y = rng() % 2;
                bool x_or_y = rng() % 2;
                Point p_one{ dst, dst, 0 };
                Point p_two{ dst * 2, dst * 2, 0 };
                if (!pos_x) p_one.x *= -1;
                if (!pos_y) p_one.y *= -1;
                if (pos_x) p_two.x *= -1;
                if (pos_y) p_two.y *= -1;
                if (x_or_y) p_two.x = 0;
                if (!x_or_y) p_two.y = 0;
                auto p_three = p_one;
                p_three.x *= -1;
                p_three.y *= -1;
                p_one.x += x_coord;
                p_one.y += y_coord;
                p_two.x += x_coord;
                p_two.y += y_coord;
                p_three.x += x_coord;
                p_three.y += y_coord;
                vm.push_back(p_one);
                vm.push_back(p_two);
                vm.push_back(p_three);
                ++cnt;
            }
        }
        swap(vn, vm);
    }
    shuffle(vn.begin(), vn.end(), rng);
    shuffle(vm.begin(), vm.end(), rng);
    return { vn, vm };
}


int main() {
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cin.tie(nullptr);

    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    if (true) {

        auto p = input_from_console();
        
        string s = "slow";


        pair<Point, Point> result;
        if (s == "fast") {
            result = solve_fast(p.first, p.second);
        }
        if (s == "slow") {
            result = solve_slow(p.first, p.second);
        }
        if (s == "slow_manhattan") {
            result = solve_slow(p.first, p.second);
        }
        if (s == "random1") {
            result = solve_random(p.first, p.second);
        }
        if (s == "random2") {
            result = solve_random_2(p.first, p.second);
        }

        cout << dist2(result.first, result.second) << endl;

    }
    else {
        mt19937_64 rng(time(0));
        auto p = generate_antimanhattan_input_2(rng);
        output_to_console(p.first, p.second);
    }

}

