//Misha and Forest.cpp
#include <bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI 3.1415926535897932626
#define EXIT exit(0);
#define PAUSE system("pause");
#define DEBUG puts("Here is a BUG");
#define SYNC_CLOSE ios::sync_with_stdio(false);
#define CLEAR(name, init) memset(name, init, sizeof(name))
const double eps = 1e-8;
const int MAXN = (int)1e9 + 5;
using namespace std;

struct Node {
    int v;
    pair<int, int> p;
    Node() { }
    Node(int v, pair<int, int> p): v(v), p(p) { }
    bool operator < (const Node& rhs) const {
        return p.first < rhs.p.first || (p.first == rhs.p.first && p.second < rhs.p.second);
    }
};
int de[1<<17], ss[1<<17];

int main(int argc, char const *argv[]) {
#ifndef ONLINE_JUDGE
    freopen("D:\\Documents\\Disk_Synchronous\\Programs\\Acm\\input.txt", "r", stdin);
#endif
    int n; cin >> n;
    std::vector<Node> v;
    CLEAR(de, 0); CLEAR(ss, 0);
    for(int i = 0; i < n; i++) {
        int d, s;
        cin >> d >> s;
        v.push_back(Node(i, {d, s}));
    }
    sort(v.begin(), v.end());
    std::vector<pair<int, int> > res;
    for(auto i : v) {
        int d = i.p.first; d += de[i.v];
        int s = i.p.second; s ^= ss[i.v];
        // cout << i.v << ' ' << d << ' ' << s << endl;
        if (d == 0) continue;
        if (d == 1) {
            res.emplace_back(i.v, s);
            de[s]--; //cout << de[s] << endl;
            ss[s] ^= i.v;
        }
    }
    cout << res.size() << endl;
    for(auto i : res) {
        cout << i.first << ' ' << i.second << endl;
    }
    return 0;
}


//Misha and Forest.cpp
#include <bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI 3.1415926535897932626
#define EXIT exit(0);
#define PAUSE system("pause");
#define DEBUG puts("Here is a BUG");
#define SYNC_CLOSE ios::sync_with_stdio(false);
#define CLEAR(name, init) memset(name, init, sizeof(name))
const double eps = 1e-8;
const int MAXN = (int)1e9 + 5;
using namespace std;

struct Node {
    int vertice, d, s;
    Node() { }
    Node(int vertice, int d, int s): vertice(vertice), d(d), s(s) { }
};
int de[1<<17], verticeis[1<<17];

int main(int argc, char const *argvertice[]) {
#ifndef ONLINE_JUDGE
    freopen("D:\\Documents\\Disk_Synchronous\\Programs\\Acm\\input.txt", "r", stdin);
#endif
    SYNC_CLOSE;
    int n; cin >> n;
    queue<int> q;
    std::vector<pair<int, int> > vertice;
    for(int i = 0; i < n; i++) {
        int d, s;
        cin >> d >> s;
        vertice.emplace_back(d, s);
        if (d == 1) q.push(i);
    }
    std::vector<pair<int, int> > res;
    while(!q.empty()) {
        int u = q.front(); q.pop();
        if (vertice[u].first == 0) continue;
        int v = vertice[u].second;
        res.emplace_back(u, v);
        vertice[v].first--; vertice[v].second ^= u;
        if (vertice[v].first == 1) q.push(v);
    }
    cout << res.size() << endl;
    for(auto i : res) {
        cout << i.first << ' ' << i.second << endl;
    }
    return 0;
}


//Misha and Forest.cpp
#include <bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI 3.1415926535897932626
#define EXIT exit(0);
#define PAUSE system("pause");
#define DEBUG puts("Here is a BUG");
#define SYNC_CLOSE ios::sync_with_stdio(false);
#define CLEAR(name, init) memset(name, init, sizeof(name))
const double eps = 1e-8;
const int MAXN = (int)1e9 + 5;
using namespace std;

struct Node {
    int v, d, s;
    Node() { }
    Node(int v, int d, int s): v(v), d(d), s(s) { }
};
int de[1<<17], vis[1<<17];

int main(int argc, char const *argv[]) {
#ifndef ONLINE_JUDGE
    freopen("D:\\Documents\\Disk_Synchronous\\Programs\\Acm\\input.txt", "r", stdin);
#endif
    int n; cin >> n;
    std::vector<pair<int, int> > v;
    queue<int> q;
    CLEAR(vis, 0);
    for(int i = 0; i < n; i++) {
        int d, s;
        cin >> d >> s;
        v.emplace_back(d, s);
        if (d == 1) q.push(i);
    }
    std::vector<pair<int, int> > res;
    while(!q.empty()) {
        int n = q.front(); q.pop();
        if (v[n].first == 0) continue;
        res.emplace_back(n, v[n].second);
        v[v[n].second].first--; v[v[n].second].second ^= n;
        if (v[v[n].second].first == 1/* && !vis[v[n].second]*/) {
            vis[v[n].second] = 1;
            q.push(v[n].second);
        }
    }
    cout << res.size() << endl;
    for(auto i : res) {
        cout << i.first << ' ' << i.second << endl;
    }
    return 0;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int maxn = (1 << 16);

int deg[maxn], s[maxn], n;
queue <int> q;
vector <pair<int, int> > edges;

int main() {
	#ifndef ONLINE_JUDGE
	freopen("501c.in", "r", stdin);
	freopen("501c.out", "w", stdout);
	#endif

	cin >> n;
	for(int i = 0 ; i < n ; ++ i) {
		cin >> deg[i] >> s[i];
		if(deg[i] == 1)
			q.push(i);
	}

	while(!q.empty()) {
		int node = q.front();
		q.pop();

		if(deg[node] == 0)
			continue;

		edges.push_back(make_pair(node, s[node]));
		-- deg[s[node]];
		s[s[node]] ^= node;

		if(deg[s[node]] == 1)
			q.push(s[node]);
	}

	cout << edges.size() << '\n';
	for(vector <pair<int, int> > :: iterator it = edges.begin() ; it != edges.end() ; ++ it)
		cout << it->first << ' ' << it->second << '\n';
}


#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int maxn = (1 << 26);

int deg[maxn], s[maxn], n;
queue <int> q;
vector <pair<int, int> > edges;

int main() {
	#ifndef ONLINE_JUDGE
	freopen("501c.in", "r", stdin);
	freopen("501c.out", "w", stdout);
	#endif

	cin >> n;
	for(int i = 1 ; i <= n ; ++ i) {
		cin >> deg[i] >> s[i];
		if(deg[i] == 1)
			q.push(i);
	}

	while(!q.empty()) {
		int node = q.front();
		q.pop();

		if(deg[node] == 0)
			continue;

		edges.push_back(make_pair(node, s[node]));
		-- deg[s[node]];
		s[s[node]] ^= node;

		if(deg[s[node]] == 1)
			q.push(s[node]);
	}

	cout << edges.size() << '\n';
	for(vector <pair<int, int> > :: iterator it = edges.begin() ; it != edges.end() ; ++ it)
		cout << it->first << ' ' << it->second << '\n';
}


#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int maxn = (1 << 16);

int deg[maxn], s[maxn], n;
queue <int> q;
vector <pair<int, int> > edges;

int main() {
	#ifndef ONLINE_JUDGE
	freopen("501c.in", "r", stdin);
	freopen("501c.out", "w", stdout);
	#endif

	cin >> n;
	for(int i = 1 ; i <= n ; ++ i) {
		cin >> deg[i] >> s[i];
		if(deg[i] == 1)
			q.push(i);
	}

	while(!q.empty()) {
		int node = q.front();
		q.pop();

		if(deg[node] == 0)
			continue;

		edges.push_back(make_pair(node, s[node]));
		-- deg[s[node]];
		s[s[node]] ^= node;

		if(deg[s[node]] == 1)
			q.push(s[node]);
	}

	cout << edges.size() << '\n';
	for(vector <pair<int, int> > :: iterator it = edges.begin() ; it != edges.end() ; ++ it)
		cout << it->first << ' ' << it->second << '\n';
}


#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>

using namespace std;

map<string, int> idx;
map<int, string> aux, last;

int main() {
	#ifndef ONLINE_JUDGE
	freopen("501b.in", "r", stdin);
	freopen("501b.out", "w", stdout);
	#endif
	int n;
	cin >> n;
	int users = 0;
	for(int i = 1 ; i <= n ; ++ i) {
		string a, b;
		cin >> a >> b;
		if(!idx[a]) {
			idx[a] = ++ users;
			aux[users] = a;
		}
		last[idx[a]] = b;
		idx[b] = idx[a];
	}
	cout << users << '\n';
	for(int i = 1 ; i <= users ; ++ i) {
		cout << aux[i] << ' ' << last[i] << '\n';
	}

}


#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<iterator>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstring>
#include<string>
#include<set>

using namespace std;

#define M 120
#define maxn 100010
#define mod 1000000007
#define pi acos(-1.0)
#define eps 1e-6
#define inf 0x3f3f3f3f
#define lc n<<1
#define rc n<<1|1
typedef long long ll;

int d[maxn], s[maxn];
pair<int, int>p[maxn];
queue<int>q;

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> d[i] >> s[i];
        if (d[i] == 1)
            q.push(i);
    }

    int cnt = 0;
    while (q.size())
    {
        int t = q.front();
        q.pop();
        if (t == 0)
            continue;
        p[cnt++] = make_pair(t, s[t]);
        d[s[t]]--;
        s[s[t]] ^= t;
        if (d[s[t]] == 1)
            q.push(s[t]);
    }

    cout << cnt << endl;
    for (int i = 0; i < cnt; i++)
    {
        cout << p[i].first << " " << p[i].second << endl;
    }
    return 0;
}


#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<iterator>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstring>
#include<string>
#include<set>

using namespace std;

#define M 120
#define maxn 100010
#define mod 1000000007
#define pi acos(-1.0)
#define eps 1e-6
#define inf 0x3f3f3f3f
#define lc n<<1
#define rc n<<1|1
typedef long long ll;

int d[maxn], s[maxn],vis[maxn];
pair<int, int>p[maxn];
queue<int>q;

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> d[i] >> s[i];
		if (d[i] == 1)
		{
			q.push(i);
			vis[i] = 1;
		}
	}

	int cnt = 0;
	while (q.size())
	{
		int t = q.front();
		q.pop();
		if (d[t] != 0)
		{
			p[cnt++] = make_pair(t, s[t]);
			d[s[t]]--;
			s[s[t]] ^= t;
		}
		if (d[s[t]] == 1 && vis[s[t]] == 0)
		{
			vis[s[t]] = 1;
			q.push(s[t]);
		}
	}

	cout << cnt << endl;
	for (int i = 0; i < cnt; i++)
	{
		cout << p[i].first << " " << p[i].second << endl;
	}
	return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;
    cin >> n;
    vector<Input> input(n);
    {
        int c = 0;
        for (auto& i : input)
        {
            cin >> i.q >> i.sum;
            i.o = c++;
        }
    }
    vector<Input> result;
    vector<int> remap(n);
    for (int i = 0; i < n; ++i) remap[i] = i;
    result.reserve(n);

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        if (in.q == 0) continue;

        input[remap[in.sum]].q--;
        input[remap[in.sum]].sum ^= i;
        result.push_back({in.o, in.sum, 0});
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <cassert>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;

    cin >> n;
    vector<int> remap(n);
    vector<Input> result;
    result.reserve(n);
    vector<Input> input(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
    }
    for (int i = 0; i < n; ++i)
        remap[i] = i;

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        assert(in.q == 0 || in.q == 1);
        if (in.q <= 0) continue;
        result.push_back(in);

        int ri = remap[in.sum];
        input[ri].sum ^= in.o;
        if (--input[ri].q == 1 && swapPos < ri)
        {
            remap[input[ri].o] = swapPos;
            remap[input[swapPos].o] = ri;
            swap(input[ri], input[swapPos++]);
        }
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <cassert>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;
    vector<Input> input(n);
    vector<Input> result;
    vector<int> remap(n);

    cin >> n;
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
    }
    result.reserve(n);
    for (int i = 0; i < n; ++i)
        remap[i] = i;

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        if (in.q <= 0) continue;

        int ri = remap[in.sum];
        input[ri].q--;
        input[ri].sum ^= in.o;
        result.push_back({in.o, in.sum, 0});
        if (input[ri].q == 1 && swapPos < ri)
        {
            remap[input[ri].o] = swapPos;
            remap[input[swapPos].o] = ri;
            swap(input[ri], input[swapPos++]);
        }
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <cassert>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;

    cin >> n;
    vector<int> remap(n);
    vector<Input> result;
    result.reserve(n);
    vector<Input> input(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
    }
    for (int i = 0; i < n; ++i)
        remap[i] = i;

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        assert(in.q == 0 || in.q == 1);
        if (in.q <= 0) continue;
        result.push_back({in.o, in.sum, 0});

        int ri = remap[in.sum];
        input[ri].sum ^= in.o;
        if (--input[ri].q == 1 && swapPos < ri)
        {
            remap[input[ri].o] = swapPos;
            remap[input[swapPos].o] = ri;
            swap(input[ri], input[swapPos++]);
        }
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;
    cin >> n;
    vector<Input> input(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
    }
    vector<int> remap(n);
    for (int i = 0; i < n; ++i) remap[i] = i;
    vector<Input> result;
    result.reserve(n);

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        if (in.q <= 0) continue;

        input[remap[in.sum]].q--;
        input[remap[in.sum]].sum ^= in.o;
        result.push_back({in.o, in.sum, 0});
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <cassert>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;

    cin >> n;
    vector<int> remap(n);
    vector<Input> result;
    result.reserve(n);
    vector<Input> input(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
    }
    for (int i = 0; i < n; ++i)
        remap[i] = i;

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1 && swapPos < i)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        if (in.q <= 0) continue;

        int ri = remap[in.sum];
        input[ri].q--;
        input[ri].sum ^= in.o;
        result.push_back({in.o, in.sum, 0});
        if (input[ri].q == 1 && swapPos < ri)
        {
            remap[input[ri].o] = swapPos;
            remap[input[swapPos].o] = ri;
            swap(input[ri], input[swapPos++]);
        }
    }

    cout << result.size() << '\n';
    for (auto a : result) cout << a.q << ' ' << a.sum << '\n';

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <cassert>
using namespace std;

struct Input
{
    int q, sum, o;
};

int main()
{
    int n;
    cin >> n;

    vector<int> remap(n);
    vector<Input> result;
    result.reserve(n);
    vector<Input> input(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> input[i].q >> input[i].sum;
        input[i].o = i;
        remap[i] = i;
    }

    int swapPos = 0;
    for (int i = 0; i < input.size(); ++i)
    {
        if (input[i].q == 1)
        {
            remap[input[i].o] = swapPos;
            remap[input[swapPos].o] = i;
            swap(input[i], input[swapPos++]);
        }
    }

    for (int i = 0; i < n; ++i)
    {
        auto in = input[i];
        assert(in.q == 0 || in.q == 1);
        if (in.q <= 0) continue;
        result.push_back({in.o, in.sum, 0});

        int ri = remap[in.sum];
        input[ri].sum ^= in.o;
        if (--input[ri].q == 1)
        {
            remap[input[ri].o] = swapPos;
            remap[input[swapPos].o] = ri;
            swap(input[ri], input[swapPos++]);
        }
    }

    cout << result.size() << '\n';
    for (const auto& a : result) cout << a.q << ' ' << a.sum << '\n';

}


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

    int main() {
        /*
         * Proof:-
         *
         *  First, any acyclic graph can be represented as a tree if all its nodes are connected,
         * or several separated tree if not.
         *
         *  The nodes in a tree can be classified into levels, where the last level are the leafs.
         *
         *  These leaves of course have one edge each;
         * which mean that each leaf is connected only to one node.
         *
         *  What I'm doing here is that I get the leaves,
         * of course the XOR sum will be the number of the single node they are connected to,
         * I subtract one from the degree of that single node and make its XOR sum xored with the number of the leaf node:
         * (If x^y=z , then y=x^z)
         *
         * By that I keep deleting the leaves, and push back the edges in the vector.
         *
         * Order of that code is only O(N).
         *
         * That needs another proof.
         *
         *  Well, it's very simple, each node will be a leaf only once, so I'll enter that while loop only n times
         *(for the whole iterations of the for loop of course).
         *
         *
         */
        int n;
        cin >> n;
        vector<pair<int, int> > vec(n), ans;
        for (int i = 0; i < n; ++i)
            cin >> vec[i].first >> vec[i].second;
        for (int i = 0; i < n; ++i) {
            int tmp = i;
            while (vec[tmp].first == 1) {
                ans.push_back(make_pair(tmp, vec[tmp].second));
                vec[tmp].first--;
                vec[vec[tmp].second].first--;
                vec[vec[tmp].second].second ^= tmp;
                tmp = vec[tmp].second;
            }
        }
        cout << ans.size() << endl;
        for (int i = 0; i < ans.size(); ++i)
            cout << ans[i].first << ' ' << ans[i].second << endl;

    }


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

    int main() {
        // I'll try to write the proof in another submission, I just want now to get sure that that is right :D
        int n;
        cin >> n;
        vector<pair<int, int> > vec(n), ans;
        for (int i = 0; i < n; ++i)
            cin >> vec[i].first >> vec[i].second;
        for (int i = 0; i < n; ++i) {
            int tmp = i;
            while (vec[tmp].first == 1) {
                ans.push_back(make_pair(tmp, vec[tmp].second));
                vec[tmp].first--;
                vec[vec[tmp].second].first--;
                vec[vec[tmp].second].second ^= tmp;
                tmp = vec[tmp].second;
            }
        }
        cout << ans.size() << endl;
        for (int i = 0; i < ans.size(); ++i)
            cout << ans[i].first << ' ' << ans[i].second << endl;
    }


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
vector<pii>sol;
int n,N,i;
struct asd
{
    int d,v;
}a[65540];
int main()
{
    cin>>n;
    N=n;
    for(i=0;i<n;i++)
    {
        cin>>a[i].d>>a[i].v;
        if(a[i].d==0)
            N--;
    }
    while(N)
    {
        for(i=0;i<n;i++)
            if(a[i].d==1)
                break;
        if(i==n)
            break;
        N--;
        sol.pb(mp(i,a[i].v));
        a[i].d=0;
        a[a[i].v].d--;
        a[a[i].v].v^=i;
        if(a[a[i].v].d==0)N--;
    }
    cout<<sol.size()<<'\n';
    for(auto it:sol)
        cout<<it.first<<' '<<it.second<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        for(auto it : w)
        {
            e.clear();
            N--;
            x=it;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        e.clear();
        for(auto it : w)
        {
            x=it;
            if(a[x].d==0)continue;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
vector<pii>sol;
vector<int>w,e;
int n, N, i;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        for(auto it : w)
        {
            e.clear();
            N--;
            sol.pb(mp(it, a[it].v));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        e.clear();
        for(auto it : w)
        {
            if(x==0)continue;
            x=it;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        e.clear();
        for(auto it : w)
        {
            x=it;
            if(x==0)continue;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb insert
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
int n,N,i;
struct asd
{
    int d,v;
}a[65540];
int main()
{
    cin>>n;
    N=n;
    for(i=0;i<n;i++)
    {
        cin>>a[i].d>>a[i].v;
        if(a[i].d==0)
            N--;
    }
    while(N)
    {
        for(i=0;i<n;i++)
            if(a[i].d==1)
                break;
        if(i==n)
            break;
        N--;
        sol.pb(mp(i,a[i].v));
        a[i].d=0;
        a[a[i].v].d--;
        a[a[i].v].v^=i;
        if(a[a[i].v].d==0)N--;
    }
    cout<<sol.size()<<'\n';
    for(auto it:sol)
        cout<<it.first<<' '<<it.second<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
vector<pii>sol;
int n,N,i;
struct asd
{
    int d,v;
}a[65540];
int main()
{
    cin>>n;
    N=n;
    for(i=0;i<n;i++)
    {
        cin>>a[i].d>>a[i].v;
        if(a[i].d==0)
            N--;
    }
    while(N)
    {
        for(i=0;i<n;i++)
            if(a[i].d==1)
        {
            N--;
        sol.pb(mp(i,a[i].v));
        a[i].d=0;
        a[a[i].v].d--;
        a[a[i].v].v^=i;
        if(a[a[i].v].d==0)N--;
        }
    }
    cout<<sol.size()<<'\n';
    for(auto it:sol)
        cout<<it.first<<' '<<it.second<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        e.clear();
        for(auto it : w)
        {
            x=it;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
vector<int>w,e;
int n, N, i,x,y;
struct asd
{
    int d, v;
} a[65540];
int main()
{
    cin >> n;
    N = n;
    for(i = 0; i < n; i++)
    {
        cin >> a[i].d >> a[i].v;
        if(a[i].d == 1)
            w.pb(i);
    }
    while(w.size())
    {
        e.clear();
        for(auto it : w)
        {
            x=it;
            if(d[x]==0)continue;
            y=a[it].v;
            if(x>y)
                swap(x,y);
            sol.insert(mp(x,y));
            a[it].d = 0;
            a[a[it].v].d--;
            a[a[it].v].v ^= it;
            if(a[a[it].v].d == 0)N--;
            if(a[a[it].v].d == 1)e.pb(a[it].v);
        }
        w = e;
    }
    cout << sol.size() << '\n';
    for(auto it : sol)
        cout << it.first << ' ' << it.second << '\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb emplace_back
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
vector<pii>sol;
vector<int>w;
int n,N,i;
struct asd
{
    int d,v;
}a[65540];
int main()
{
    cin>>n;
    N=n;
    for(i=0;i<n;i++)
    {
        cin>>a[i].d>>a[i].v;
        if(a[i].d==0)
            N--;
        if(a[i].d==1)
            w.pb(i);
    }
    for(auto it :w)
    {
        N--;
        sol.pb(mp(it,a[it].v));
        a[it].d=0;
        a[a[it].v].d--;
        a[a[it].v].v^=it;
        if(a[a[it].v].d==0)N--;
        if(a[a[it].v].d==1)w.pb(a[it].v);
    }
    cout<<sol.size()<<'\n';
    for(auto it:sol)
        cout<<it.first<<' '<<it.second<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb insert
#define mp make_pair
#define ll long long
#define oo 1<<18;
using namespace std;
set<pii>sol;
int n,N,i;
struct asd
{
    int d,v;
}a[65540];
int main()
{
    cin>>n;
    N=n;
    for(i=0;i<n;i++)
    {
        cin>>a[i].d>>a[i].v;
        if(a[i].d==0)
            N--;
    }
    while(N)
    {
        for(i=0;i<n;i++)
            if(a[i].d==1)
                break;
        N--;
        sol.pb(mp(i,a[i].v));
        a[i].d=0;
        a[a[i].v].d--;
        a[a[i].v].v^=i;
        if(a[a[i].v].d==0)N--;
    }
    cout<<sol.size()<<'\n';
    for(auto it:sol)
        cout<<it.first<<' '<<it.second<<'\n';
    return 0;
}


#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <limits.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>
using namespace std;
const int num = 2<<16 + 5;
int n,m,total = 0;
int deg[num],s[num];
bool used[num];
stack<int > st;
struct line{
    int w,v;
};
stack<line > edges;
void read(){
    cin>>n;
    memset(used,false,num*sizeof(bool));
    for(int i = 0 ; i < n ; i++){
        scanf("%d %d",&deg[i],&s[i]);
        if(deg[i] == 1) st.push(i);
    }
}

void solve(){
    while(!st.empty()){
        int top = st.top();
        st.pop();
        used[top] = true;
        int ver = s[top];
        if(used[ver])   continue;
        s[ver] ^= top;
        struct line new_edge = {top,ver};
        edges.push(new_edge);
        total++;
        deg[ver]--;
        if(deg[ver] == 1) st.push(ver);
    }
    cout<<total<<endl;
    struct line tmp;
    while(!edges.empty()){
        tmp = edges.top();
        edges.pop();
        printf("%d %d\n",tmp.w,tmp.v);
    }
}

int main(){
    read();
    solve();
    return 0;
}


#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <limits.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>
using namespace std;
const int num = 2<<16 + 5;
int n,m,total = 0;
int deg[num],s[num];
stack<int > st;
struct line{
    int w,v;
};
stack<line > edges;
void read(){
    cin>>n;
    for(int i = 0 ; i < n ; i++){
        scanf("%d %d",&deg[i],&s[i]);
        if(deg[i] == 1) st.push(i);
    }
}

void solve(){
    while(!st.empty()){
        int top = st.top();
        st.pop();
        if(deg[top] !=1 )
            continue;
        int ver = s[top];
        s[ver] ^= top;
        struct line new_edge = {top,ver};
        edges.push(new_edge);
        total++;
        deg[ver]--;
        if(deg[ver] == 1) st.push(ver);
    }
    cout<<total<<endl;
    struct line tmp;
    while(!edges.empty()){
        tmp = edges.top();
        edges.pop();
        printf("%d %d\n",tmp.w,tmp.v);
    }
}

int main(){
    read();
    solve();
    return 0;
}


#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <limits.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>
using namespace std;
const int num = 2<<16 + 5;
int n,m,total = 0;
int deg[num],s[num];
bool used[num];
stack<int > st;
struct line{
    int w,v;
};
stack<line > edges;
void read(){
    cin>>n;
    memset(used,false,num*sizeof(bool));
    for(int i = 0 ; i < n ; i++){
        scanf("%d %d",&deg[i],&s[i]);
        if(deg[i] == 1) st.push(i);
    }
}

void solve(){
    while(!st.empty()){
        int top = st.top();
        st.pop();
        used[top] = true;
        int ver = s[top];
        s[ver] ^= top;
        if(used[ver])   continue;
        struct line new_edge = {top,ver};
        edges.push(new_edge);
        total++;
        deg[ver]--;
        if(deg[ver] == 1) st.push(ver);
    }
    cout<<total<<endl;
    struct line tmp;
    while(!edges.empty()){
        tmp = edges.top();
        edges.pop();
        printf("%d %d\n",tmp.w,tmp.v);
    }
}

int main(){
    read();
    solve();
    return 0;
}


// (|-__-|)

#include<bits/stdc++.h>

using namespace std;
#define mp make_pair
#define X first
#define Y second
typedef long long int ll;

const int maxn = (1 << 16) + 10;
queue <int> g;
vector <pair <int, int> > ans;
int x[maxn], deg[maxn];
int n;

int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>deg[i]>>x[i];
        if(deg[i] == 1)
            g.push(i);
    }
    while(!g.empty())
    {
        int v = g.front(), u = x[v];
        g.pop();
        if(!deg[v])
            continue;
        ans.push_back(mp(u, v));
        deg[u]--, x[u] ^= v;
        if(deg[u] == 1)
            g.push(u);
    }
    cout<<ans.size()<<endl;
    for(auto &e : ans)
        cout<<e.X<<" "<<e.Y<<endl;

    return 0;
}


// (|-__-|)

#include<bits/stdc++.h>

using namespace std;
#define mp make_pair
#define X first
#define Y second
typedef long long int ll;

const int maxn = (1 << 16) + 10;
set<pair <int, int>> g;
vector <pair <int, int> > ans;
int x[maxn], deg[maxn];
int n;

int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>deg[i]>>x[i];
        g.insert(mp(deg[i], i));
    }
    while(g.size())
    {
        auto F = g.begin();
        g.erase(F);
        int u = x[F->Y], v = F->Y;
        if(!deg[v])
            continue;
        ans.push_back(mp(u, v));
        g.erase(mp(deg[u], u));
        deg[u]--, x[u] ^= v;
        g.insert(mp(deg[u], u));
    }
    cout<<ans.size()<<endl;
    for(auto &e : ans)
        cout<<e.X<<" "<<e.Y<<endl;

    return 0;
}


// (|-__-|)

#include<bits/stdc++.h>

using namespace std;
#define mp make_pair
#define X first
#define Y second
typedef long long int ll;

const int maxn = (1 << 16) + 10;
set<pair <int, int>> g;
vector <pair <int, int> > ans;
int x[maxn], deg[maxn];
int n;

int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>deg[i]>>x[i];
        g.insert(mp(deg[i], i));
    }
    while(g.size())
    {
        auto F = g.begin();
        g.erase(F);
        int u = x[F->Y], v = F->Y;
        ans.push_back(mp(u, v));
        g.erase(mp(deg[u], u));
        deg[u]--, x[u] ^= v;
        if(deg[u])
            g.insert(mp(deg[u], u));
    }
    cout<<ans.size()<<endl;
    for(auto &e : ans)
        cout<<e.X<<" "<<e.Y<<endl;

    return 0;
}


// (|-__-|)

#include<bits/stdc++.h>

using namespace std;
#define mp make_pair
#define X first
#define Y second
typedef long long int ll;

const int maxn = (1 << 16) + 10;
queue <int> g;
vector <pair <int, int> > ans;
int x[maxn], deg[maxn];
int n;

int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>deg[i]>>x[i];
        if(deg[i] == 1)
            g.push(i);
    }
    while(!g.empty())
    {
        int v = g.front(), u = x[v];
        g.pop();
        if(u != v)
            ans.push_back(mp(u, v));
        deg[u]--, x[u] ^= v;
        if(deg[u] == 1)
            g.push(u);
    }
    cout<<ans.size()<<endl;
    for(auto &e : ans)
        cout<<e.X<<" "<<e.Y<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
int main()
{
    int n;
    cin>>n;
    pair<int,int> arr[n];
    queue<int>que;
    vector<int> adj[n];
    bool chk[n];
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        chk[i]=0;
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
            */
        if(chk[pr]==0)
        {
            arr[arr[pr].second].first--;
            if(arr[arr[pr].second].first==1)
            {
                que.push(arr[pr].second);
            }
            adj[pr].push_back(arr[pr].second);
            ct++;
            arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
            arr[pr].first--;
            chk[arr[pr].second]=1;
        }
        chk[pr]=1;
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
int main()
{
    int n;
    cin>>n;
    pair<int,int> arr[n];
    queue<int>que;
    vector<int> adj[n];
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
            */
        if(arr[arr[pr].second].first>0)
        {
            arr[arr[pr].second].first--;
            if(arr[arr[pr].second].first==1)
            {
                que.push(arr[pr].second);
            }
            adj[pr].push_back(arr[pr].second);
            ct++;
            arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
            arr[pr].first--;
        }
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
int main()
{
    int n;
    cin>>n;
    pair<int,int> arr[n];
    queue<int>que;
    vector<int> adj[n];
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
            */
        if(arr[pr].first>0)
        {
            arr[arr[pr].second].first--;
            if(arr[arr[pr].second].first==1)
            {
                que.push(arr[pr].second);
            }
            adj[pr].push_back(arr[pr].second);
            ct++;
            arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
            arr[pr].first--;
        }
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
int main()
{
    int n;
    cin>>n;
    pair<int,int> arr[n];
    queue<int>que;
    vector<int> adj[n];
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        if(arr[pr].first==0 && arr[pr].second==0)
            break;
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
            */
        arr[arr[pr].second].first--;
        if(arr[arr[pr].second].first==1)
        {
            que.push(arr[pr].second);
        }
        adj[pr].push_back(arr[pr].second);
        ct++;
        arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
        arr[pr].first--;
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
int main()
{
    int n;
    cin>>n;
    pair<int,int> arr[n];
    queue<int>que;
    vector<int> adj[n];
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        if(arr[pr].first==0 && arr[pr].second==0)
            break;
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
        */
        arr[arr[pr].second].first--;
        que.push(arr[pr].second);
        adj[pr].push_back(arr[pr].second);
        ct++;
        arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
        arr[pr].first--;
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define MAX numeric_limits<int>::max()
#define MIN numeric_limits<int>::min()
pair<int,int> arr[(1<<16)+2];
queue<int>que;
vector<int> adj[(1<<16)+2];
int main()
{
    int n;
    cin>>n;
    int i,j,deg,xsum;
    for(i=0;i<n;i++)
    {
        cin>>deg>>xsum;
        arr[i]=make_pair(deg,xsum);
        if(arr[i].first==1)
        {
            que.push(i);
        }
    }
    int pr;
    int ct=0;
    while(!que.empty())
    {
        pr=que.front();
        que.pop();
        if(arr[pr].first==0 && arr[pr].second==0)
            break;
        /*
        cout<<"front\t"<<pr<<"\n";
        for(i=0;i<n;i++)
            cout<<i<<"\t"<<arr[i].first<<"\t"<<arr[i].second<<"\n";
        */
        arr[arr[pr].second].first--;
        que.push(arr[pr].second);
        adj[pr].push_back(arr[pr].second);
        ct++;
        arr[arr[pr].second].second=pr^arr[arr[pr].second].second;
        arr[pr].first--;
    }
    cout<<ct<<"\n";
    for(i=0;i<n;i++)
    {
        for(j=0;j<adj[i].size();j++)
        {
                cout<<i<<" "<<adj[i][j]<<"\n";
        }
    }
    return 0;
}


//copied from "wjfwzzc"
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=(1<<16)+5;
int d[MAXN],s[MAXN];
vector<pair<int,int> > ans;
queue<int> q;
int main() {
    int m;
    scanf("%d",&m);
    for(int i=0; i<m; ++i) {
        scanf("%d%d",&d[i],&s[i]);
        if(d[i]==1)
            q.push(i);
    }
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        if(d[u]!=1)
            continue;
        ans.push_back(make_pair(u,s[u]));
        s[s[u]]^=u;
        d[s[u]]--;
        if(d[s[u]]==1)
            q.push(s[u]);
    }
    printf("%d\n",ans.size());
    for(int i=0; i<ans.size(); ++i)
        printf("%d %d\n",ans[i].first,ans[i].second);
}


#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

typedef long long int integer;
typedef pair<integer,integer> P;

int main() {
  integer n;
  vector<pair<P,integer>> inputs; // <degree_i, s_i>
  cin >> n;
  REP(i, n) {
    integer di, si;
    cin >> di >> si;
    inputs.push_back(make_pair(make_pair(di,si),i));
  }

  sort(inputs.begin(), inputs.end());

  vector<P> nodes;
  vector<integer> reference(n);
  REP(i, n) {
    nodes.push_back(inputs[i].first);
    reference[inputs[i].second] = i;
  }

  integer len = nodes.size();
  vector<pair<integer,integer>> edges;

  REP(i, len) {
    if (nodes[i].first == 0) continue;
    integer d = reference[nodes[i].second];
    edges.push_back(make_pair(i, d));
    nodes[d].first --;
    nodes[d].second = nodes[d].second xor i;
  }

  cout << edges.size() << endl;
  for (P edge : edges) {
    cout << edge.first << " " << edge.second << endl;
  }
}


#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

typedef long long int integer;
typedef pair<integer,integer> P;

int main() {
  integer n;
  vector<pair<P,integer>> nodes; // <degree_i, s_i>
  cin >> n;
  REP(i, n) {
    integer di, si;
    cin >> di >> si;
    nodes.push_back(make_pair(make_pair(di,si),i));
  }

  sort(nodes.begin(), nodes.end());

  vector<integer> reference(n);
  REP(i, n) {
    reference[nodes[i].second] = i;
  }

  vector<P> edges;
  REP(i, n) {
    integer& node = nodes[i].second;
    integer& degree = nodes[i].first.first;
    integer& sum = nodes[i].first.second;

    if (degree != 1) continue;
    edges.push_back(make_pair(node, sum));
    integer dest = reference[sum];
    nodes[dest].first.first--;
    nodes[dest].first.second = nodes[dest].first.second xor node;
    degree--;
    sum = 0;
  }

  cout << edges.size() << endl;
  for (P edge : edges) {
    cout << edge.first << " " << edge.second << endl;
  }
}


#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

typedef long long int integer;
typedef pair<integer,integer> P;

int main() {
  integer n;
  vector<P> nodes; // <degree_i, s_i>
  cin >> n;
  REP(i, n) {
    integer di, si;
    cin >> di >> si;
    nodes.push_back(make_pair(di,si));
  }

  queue<integer> que;
  REP(i, n) {
    if (nodes[i].first == 1) {
      que.push(i);
    }
  }

  vector<P> edges;
  while (!que.empty()) {
    integer i = que.front();
    que.pop();
    if (nodes[i].first == 0) {
      continue;
    }
    integer j = nodes[i].second;
    edges.push_back(make_pair(i, j));
    nodes[j].first--;
    nodes[j].second = nodes[j].second xor i;
    if (nodes[j].first == 1) {
      que.push(j);
    }

    nodes[i].first--;
    nodes[i].second = 0;
  }

  cout << edges.size() << endl;
  for (P edge : edges) {
    cout << edge.first << " " << edge.second << endl;
  }
}


#include<stdio.h>
#include<stdlib.h>
struct node{
	int d, x;
}m[1000000], ans[1000000];
int n, k, one[1000000], q, none[1000000];
int main(){
	scanf("%d", &n);
	int i;
	for(i = 0; i < n; i++){
		scanf("%d%d", &m[i].d, &m[i].x);
		if(m[i].d == 1) one[k++] = i;
	}
	while(k){
		int nk = 0;
		for(i = 0; i < k; i++){
			int fr = one[i], to = m[fr].x;
			if(m[fr].d != 1) continue;
			ans[q].d = fr;
			ans[q++].x = to;
		//	printf("(%d, %d)\n", fr, to);
			--m[fr].d;
			--m[to].d;
			m[to].x ^= fr;
		}
		for(i = 0; i < k; i++){
			int fr = one[i], to = m[fr].x;
			if(m[to].d == 1) none[nk++] = to;
		}
		//printf("nk = %d\n", nk);
		for(i = 0; i < nk; i++) one[i] = none[i];
		k = nk;
	}
	printf("%d\n", q);
	for(i = 0; i < q; i++) printf("%d %d\n", ans[i].d, ans[i].x);
}


#include<stdio.h>
#include<stdlib.h>

typedef struct{
  int number;
  int value;
  int xor;
} node;

//int comp(const void *p1,const void *p2);
void RouteDetect(int pos);

int count=0,*start,*goal;
node *vertex;

int main(void){
  int n,i,j;

  scanf("%d",&n);
  vertex=(node *)calloc(n,sizeof(node));
  start=(int *)calloc(n,sizeof(int));
  goal=(int *)calloc(n,sizeof(int));
  for(i=0;i<n;i++){
    vertex[i].number=i;
    scanf("%d%d",&vertex[i].value,&vertex[i].xor);
  }

  //qsort(vertex,n,sizeof(node),comp);
  /*for(i=0;i<n;i++){
    printf("%d %d %d\n",vertex[i].number,vertex[i].value,vertex[i].xor);
    }//*/
  for(i=0;i<n;i++)
    if(vertex[i].value==1) RouteDetect(i);

  printf("%d\n",count);
  for(i=0;i<count;i++) printf("%d %d\n",start[i],goal[i]);

  free(vertex);
  free(start);
  free(goal);
  return 0;
}
/*
int comp(const void *p1,const void *p2){
  const node *n1,*n2;
  n1= (const node *)p1;
  n2= (const node *)p2;
  if(n1->value == n2->value) return n1->number-n2->number;
  else return n1->value-n2->value;
  }//*/

void RouteDetect(int pos){
  int tmp;

  if(vertex[pos].value==1){
    vertex[pos].value--;
    tmp=vertex[pos].xor;
    // printf("%d ^ %d = %d\n", vertex[pos].xor,vertex[pos].number,tmp);
    vertex[tmp].value--;
    vertex[tmp].xor^=vertex[pos].number;
    start[count]=pos;
    goal[count]=tmp;
    count++;
    RouteDetect(tmp);
  }
}


#include<stdio.h>
#include<stdlib.h>

typedef struct{
  int number;
  int value;
  int xor;
} node;

//int comp(const void *p1,const void *p2);
void RouteDetect(int pos);

int count=0,*start,*goal;
node *vertex;

int main(void){
  int n,i,j;

  scanf("%d",&n);
  vertex=(node *)calloc(n,sizeof(node));
  start=(int *)calloc(n,sizeof(int));
  goal=(int *)calloc(n,sizeof(int));
  for(i=0;i<n;i++){
    vertex[i].number=i;
    scanf("%d%d",&vertex[i].value,&vertex[i].xor);
  }

  //qsort(vertex,n,sizeof(node),comp);
  /*for(i=0;i<n;i++){
    printf("%d %d %d\n",vertex[i].number,vertex[i].value,vertex[i].xor);
    }//*/
  for(i=0;i<n;i++)
    if(vertex[i].value==1) RouteDetect(i);

  printf("%d\n",count);
  for(i=0;i<count;i++) printf("%d %d\n",start[i],goal[i]);

  free(vertex);
  free(start);
  free(goal);
  return 0;
}
/*
int comp(const void *p1,const void *p2){
  const node *n1,*n2;
  n1= (const node *)p1;
  n2= (const node *)p2;
  if(n1->value == n2->value) return n1->number-n2->number;
  else return n1->value-n2->value;
  }//*/

void RouteDetect(int pos){
  int tmp;

  if(vertex[pos].value==1){
    vertex[pos].value--;
    tmp=vertex[pos].xor;
    printf("%d ^ %d = %d\n", vertex[pos].xor,vertex[pos].number,tmp);
    vertex[tmp].value--;
    vertex[tmp].xor^=vertex[pos].number;
    start[count]=pos;
    goal[count]=tmp;
    count++;
    RouteDetect(tmp);
  }
}


#include<stdio.h>
int main()
{
    int n,vertex[100000][2],ans[100000][2],cnt,i,single[100000],tot;
    scanf("%d",&n);
    cnt=0;
    for(i=0;i<n;i++)
    {
        scanf("%d %d",&vertex[i][0],&vertex[i][1]);
        if(vertex[i][0]==1)//at least one vertex will have degree 1, its a forest
        {
            single[cnt]=i;
            cnt++;
        }
    }
    tot=0;

   while(cnt>0)
    {
        if(vertex[single[cnt-1]][0]==1)
        {int index=single[cnt-1];
	 int neighbor_index=vertex[index][1];//since its the only neighbor ,degree is 1, hence XOR value = index of neighbor
        ans[tot][0]=single[cnt-1];
        ans[tot][1]=vertex[single[cnt-1]][1];
        tot++;
        cnt--;
        vertex[neighbor_index][0]--;//reduce degree of neighbor,since we have taken into account one of its neighbors
        vertex[neighbor_index][1]=vertex[neighbor_index][1]^index;//XOR prev XOR sum with this index to fetch you XOR sum due to other vertices
        if(vertex[neighbor_index][0]==1)//check if now neighbor also has degree 1
        {
            single[cnt]=neighbor_index;//single[cnt] no longer holds i but the neighbor's index,rev dirn reading
            cnt++;
        }
        }
        else
        cnt--;
    }
    printf("%d\n",tot);
    for(i=0;i<tot;i++)
    printf("%d %d\n",ans[i][0],ans[i][1]);
    return 0;
}


#include <stdio.h>
#include<stdbool.h>
#define gc() getchar()
inline int readInt()
{
    int ret=0;
    bool negg=false;
    char c;
    c=gc();
    while((c<'0' || c>'9') && c!='-')
    {
        c=gc();
    }
    if(c=='-')
    {
        negg=true;
        c=gc();
    }
    while(c>='0' && c<='9')
    {
        ret=ret*10+(c-'0');
        c=gc();
    }
    if(negg)
    {
        ret=-ret;
    }
    return ret;
}//=readInt();
int queue[1000000],top=0,bottom=0;
struct d{
    int sum,deg;
}   arr[100000];
int main(void) {
    int i,j,k,m,n,x,y,z,ans=0;
    n=readInt();
    for(i=0;i<n;++i){
        arr[i].deg=readInt();arr[i].sum=readInt();
        if(arr[i].deg==1) queue[bottom++]=i;
        ans+=arr[i].deg;
    }
    printf("%d\n",ans/2);
    while(top<bottom){
        if(arr[queue[top]].deg!=1) {top++; continue;}
        printf("%d %d\n",queue[top],arr[queue[top]].sum);
        arr[arr[queue[top]].sum].sum=arr[arr[queue[top]].sum].sum ^ queue[top];
        arr[arr[queue[top]].sum].deg--;
        if( arr[arr[queue[top]].sum].deg==1) queue[bottom++]=arr[queue[top]].sum;
        top++;
    }
    return 0;
}


#include <stdio.h>
#define gc() getchar()
inline int readInt()
{
    int ret=0;
    int negg=0;
    char c;
    c=gc();
    while((c<'0' || c>'9') && c!='-')
    {
        c=gc();
    }
    if(c=='-')
    {
        negg=1;
        c=gc();
    }
    while(c>='0' && c<='9')
    {
        ret=ret*10+(c-'0');
        c=gc();
    }
    if(negg)
    {
        ret=-ret;
    }
    return ret;
}//=readInt();
int queue[1000000],top=0,bottom=0;
struct d{
    int sum,deg;
}   arr[100000];
int main(void) {
    int i,j,k,m,n,x,y,z,ans=0;
    n=readInt();
    for(i=0;i<n;++i){
        arr[i].deg=readInt();arr[i].sum=readInt();
        if(arr[i].deg==1) queue[bottom++]=i;
        ans+=arr[i].deg;
    }
    printf("%d\n",ans/2);
    while(top<bottom){
        if(arr[queue[top]].deg!=1) {top++; continue;}
        printf("%d %d\n",queue[top],arr[queue[top]].sum);
        arr[arr[queue[top]].sum].sum=arr[arr[queue[top]].sum].sum ^ queue[top];
        arr[arr[queue[top]].sum].deg--;
        if( arr[arr[queue[top]].sum].deg==1) queue[bottom++]=arr[queue[top]].sum;
        top++;
    }
    return 0;
}


#include <stdio.h>
int queue[1000000],top=0,bottom=0;
struct d{
    int sum,deg;
}   arr[100000];
int main(void) {
    int i,j,k,m,n,x,y,z,ans=0;
    scanf("%d",&n);
    for(i=0;i<n;++i){
        scanf("%d %d",&arr[i].deg,&arr[i].sum);
        if(arr[i].deg==1) queue[bottom++]=i;
        ans+=arr[i].deg;
    }
    printf("%d\n",ans/2);
    while(top<bottom){
        if(arr[queue[top]].deg!=1) {top++; continue;}
        printf("%d %d\n",queue[top],arr[queue[top]].sum);
        arr[arr[queue[top]].sum].sum=arr[arr[queue[top]].sum].sum ^ queue[top];
        arr[arr[queue[top]].sum].deg--;
        if( arr[arr[queue[top]].sum].deg==1) queue[bottom++]=arr[queue[top]].sum;
        top++;
    }
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
typedef long long unsigned ll;
struct noeud
{
    ll d,s,edge;
};
void fusion(struct noeud tableau[],ll deb1,ll fin1,ll fin2)
        {
        struct noeud *table1;
        ll deb2=fin1+1;
        ll compt1=deb1;
        ll compt2=deb2;
        ll i;

        table1=malloc((fin1-deb1+1)*sizeof(struct noeud));

        //on recopie les éléments du début du tableau
        for(i=deb1;i<=fin1;i++)
            {
            table1[i-deb1].d=tableau[i].d;
            table1[i-deb1].s=tableau[i].s;
            table1[i-deb1].edge=tableau[i].edge;
            }

        for(i=deb1;i<=fin2;i++)
            {
            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
                {
                break; //tous les éléments ont donc été classés
                }
            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge;
                //on ajoute les éléments restants du premier tableau
                compt1++;
                }
            else if (table1[compt1-deb1].d<tableau[compt2].d)
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge; //on ajoute un élément du premier tableau
                compt1++;
                }
            else
                {
                tableau[i].d=tableau[compt2].d;
                tableau[i].s=tableau[compt2].s;
                tableau[i].edge=tableau[compt2].edge;//on ajoute un élément du second tableau
                compt2++;
                }
            }
        free(table1);
        }

void tri_fusion_bis(struct noeud tableau[],ll deb,ll fin)
        {
        if (deb!=fin)
            {
            long long unsigned milieu=(fin+deb)/2;
            tri_fusion_bis(tableau,deb,milieu);
            tri_fusion_bis(tableau,milieu+1,fin);
            fusion(tableau,deb,milieu,fin);
            }
        }

void tri_fusion(struct noeud tableau[],ll longueur)
     {
     if (longueur>0)
            {
            tri_fusion_bis(tableau,0,longueur-1);
            }
     }
int main()
{
    ll n,i;
    scanf("%llu",&n);
    struct noeud t[n];
    for(i=0;i<n;i++)
    {
        scanf("%llu%llu",&t[i].d,&t[i].s);
        t[i].edge=i;
    }
    tri_fusion(t,n);
    ll j,ans=0,L[n][2];
    for (i=0;i<n;i++)
    {
        if (t[i].d==1)
        {
            ans++;
            L[ans][0]=t[i].edge;
            L[ans][1]=t[i].s;
            for(j=0;j<n ;j++)
            {
                if (t[j].edge==t[i].s)
                {

                    t[j].s^=t[i].edge;
                    t[j].d--;
                    t[i].d--;
                    tri_fusion(t,n);

                    break;
                }

            }
        }
    }
    printf("%llu\n",ans);
    for(i=1;i<=ans;i++)
        printf("%llu %llu\n",L[i][0],L[i][1]);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
typedef long long unsigned ll;
struct noeud
{
    ll d,s;
};

int main()
{
    ll n,i,k;
    scanf("%llu",&n);
    struct noeud t[n];
    for(i=0;i<n;i++)
    {
        scanf("%llu%llu",&t[i].d,&t[i].s);

    }

    ll ans=0,L[n][2];
    for (i=0;i<n;i++)
    {
        if (t[i].d==1)
        {
        k=i;
        while (t[k].d==1)
            {ans++;
            L[ans][0]=k;
            L[ans][1]=t[k].s;
            t[t[k].s].s^=k;

                    t[t[k].s].d--;
                    t[k].d--;

              k=t[k].s;
            }

        }
    }
    printf("%llu\n",ans);
    for(i=1;i<=ans;i++)
        printf("%llu %llu\n",L[i][0],L[i][1]);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
typedef long long unsigned ll;
struct noeud
{
    ll d,s,edge;
};
void fusion(struct noeud tableau[],ll deb1,ll fin1,ll fin2)
        {
        struct noeud *table1;
        ll deb2=fin1+1;
        ll compt1=deb1;
        ll compt2=deb2;
        ll i;

        table1=malloc((fin1-deb1+1)*sizeof(struct noeud));

        //on recopie les éléments du début du tableau
        for(i=deb1;i<=fin1;i++)
            {
            table1[i-deb1].d=tableau[i].d;
            table1[i-deb1].s=tableau[i].s;
            table1[i-deb1].edge=tableau[i].edge;
            }

        for(i=deb1;i<=fin2;i++)
            {
            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
                {
                break; //tous les éléments ont donc été classés
                }
            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge;
                //on ajoute les éléments restants du premier tableau
                compt1++;
                }
            else if (table1[compt1-deb1].d<tableau[compt2].d)
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge; //on ajoute un élément du premier tableau
                compt1++;
                }
            else
                {
                tableau[i].d=tableau[compt2].d;
                tableau[i].s=tableau[compt2].s;
                tableau[i].edge=tableau[compt2].edge;//on ajoute un élément du second tableau
                compt2++;
                }
            }
        free(table1);
        }

void tri_fusion_bis(struct noeud tableau[],ll deb,ll fin)
        {
        if (deb!=fin)
            {
            long long unsigned milieu=(fin+deb)/2;
            tri_fusion_bis(tableau,deb,milieu);
            tri_fusion_bis(tableau,milieu+1,fin);
            fusion(tableau,deb,milieu,fin);
            }
        }

void tri_fusion(struct noeud tableau[],ll longueur)
     {
     if (longueur>0)
            {
            tri_fusion_bis(tableau,0,longueur-1);
            }
     }
int main()
{
    ll n,i;
    scanf("%llu",&n);
    struct noeud t[n];
    for(i=0;i<n;i++)
    {
        scanf("%llu%llu",&t[i].d,&t[i].s);
        t[i].edge=i;
    }
    tri_fusion(t,n);
    ll j,ans=0,L[n][2];
    for (i=0;i<n;i++)
    {
        if (t[i].d==1)
        {
            ans++;
            L[ans][0]=t[i].edge;
            L[ans][1]=t[i].s;
            for(j=0;j<n ;j++)
            {
                if (t[j].edge==t[i].s)
                {
                    t[j].d--;
                    t[j].s^=t[i].s;
                    break;
                }

            }
        }
    }
    printf("%llu\n",ans);
    for(i=1;i<=ans;i++)
        printf("%llu %llu\n",L[i][0],L[i][1]);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
typedef long long unsigned ll;
struct noeud
{
    ll d,s,edge;
};
void fusion(struct noeud tableau[],ll deb1,ll fin1,ll fin2)
        {
        struct noeud *table1;
        ll deb2=fin1+1;
        ll compt1=deb1;
        ll compt2=deb2;
        ll i;

        table1=malloc((fin1-deb1+1)*sizeof(struct noeud));

        //on recopie les éléments du début du tableau
        for(i=deb1;i<=fin1;i++)
            {
            table1[i-deb1].d=tableau[i].d;
            table1[i-deb1].s=tableau[i].s;
            table1[i-deb1].edge=tableau[i].edge;
            }

        for(i=deb1;i<=fin2;i++)
            {
            if (compt1==deb2) //c'est que tous les éléments du premier tableau ont été utilisés
                {
                break; //tous les éléments ont donc été classés
                }
            else if (compt2==(fin2+1)) //c'est que tous les éléments du second tableau ont été utilisés
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge;
                //on ajoute les éléments restants du premier tableau
                compt1++;
                }
            else if (table1[compt1-deb1].d<tableau[compt2].d)
                {
                tableau[i].d=table1[compt1-deb1].d;
                tableau[i].s=table1[compt1-deb1].s;
                tableau[i].edge=table1[compt1-deb1].edge; //on ajoute un élément du premier tableau
                compt1++;
                }
            else
                {
                tableau[i].d=tableau[compt2].d;
                tableau[i].s=tableau[compt2].s;
                tableau[i].edge=tableau[compt2].edge;//on ajoute un élément du second tableau
                compt2++;
                }
            }
        free(table1);
        }

void tri_fusion_bis(struct noeud tableau[],ll deb,ll fin)
        {
        if (deb!=fin)
            {
            long long unsigned milieu=(fin+deb)/2;
            tri_fusion_bis(tableau,deb,milieu);
            tri_fusion_bis(tableau,milieu+1,fin);
            fusion(tableau,deb,milieu,fin);
            }
        }

void tri_fusion(struct noeud tableau[],ll longueur)
     {
     if (longueur>0)
            {
            tri_fusion_bis(tableau,0,longueur-1);
            }
     }
int main()
{
    ll n,i,k;
    scanf("%llu",&n);
    struct noeud t[n];
    for(i=0;i<n;i++)
    {
        scanf("%llu%llu",&t[i].d,&t[i].s);
        t[i].edge=i;
    }
    tri_fusion(t,n);
    ll j,ans=0,L[n][2];
    for (i=0;i<n;i++)
    {
        if (t[i].d==1)
        {
        k=i;
        while (t[k].d==1)
            {ans++;
            L[ans][0]=t[k].edge;
            L[ans][1]=t[k].s;
            for(j=0;j<n ;j++)
            {

                if (t[j].edge==t[k].s)
                {
                    t[j].s^=t[k].edge;
                    t[j].d--;
                    t[k].d--;

                    break;
                }
              k=j;
            }
            }
        }
    }
    printf("%llu\n",ans);
    for(i=1;i<=ans;i++)
        printf("%llu %llu\n",L[i][0],L[i][1]);
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
struct vertex{
	int deg;
	int xor;
};

struct node{
	int id;
	struct node *next;
};

void pushint(int);
struct node *end;
int main(){
	struct node *head;
	struct vertex *ar;
	int n,i,edges;
	head=(struct node *)malloc(sizeof(struct node));
	head->next=NULL;
	end=head;
	scanf("%d",&n);
	ar=(struct vertex *)malloc(sizeof(struct vertex)*n);
	for(i=0,edges=0;i<n;i++){
		scanf("%d %d",&ar[i].deg,&ar[i].xor);
		if(ar[i].deg==1){
			pushint(i);
		}
		edges+=ar[i].deg;
	}
	edges>>=1;
	printf("%d\n",edges);
	while(edges>0){
		i=head->next->id;
		if(ar[i].deg==0){
		}
		else if(ar[i].deg==1){
			printf("%d %d\n",i,ar[i].xor);
			ar[ar[i].xor].deg--;
			ar[ar[i].xor].xor^=i;
			edges--;
			if(ar[ar[i].xor].deg==1){
				pushint(ar[i].xor);
			}
		}
		else{
			printf("ERROR!\nDegree is %d\n",ar[i].deg);
		}
		head=head->next;
	}
	return 0;
}

void pushint(int i){
	end->next=(struct node *)malloc(sizeof(struct node));
	end=end->next;
	end->id=i;
	end->next=NULL;
}


#include<stdio.h>
#include<stdlib.h>
int *links,*revs,*adjs,*xors,n;
void swap(int,int);
void heapify(int);
int main(){
	int i,j,edges;
	scanf("%d",&n);
	links=(int *)malloc(sizeof(int)*(n+1));
	adjs=(int *)malloc(sizeof(int)*(n+1));
	xors=(int *)malloc(sizeof(int)*(n+1));
	revs=(int *)malloc(sizeof(int)*(n+1));
	for(i=1,edges=0;i<=n;i++){
		scanf("%d %d",adjs+i,xors+i);
		links[i]=i;
		revs[i]=i;
		if(adjs[i]==0){
			i--;
			n--;
		}
		edges+=adjs[i];
	}
	for(i=n>>1;i>0;i--){
		heapify(i);
	}
	edges>>=1;
	printf("%d\n",edges);
	for(i=0;i<edges;i++){
		if(adjs[1]==0){
			swap(n,1);
			n--;
			i--;
		}
		else if(adjs[1]==1){
			printf("%d %d\n",links[1]-1,xors[1]);
			adjs[revs[xors[1]+1]]--;
			xors[revs[xors[1]+1]]^=(links[1]-1);
			swap(1,n);
			n--;
			heapify(1);
		}
		else{
			printf("ERROR!\nadjs[1]=%d\n",adjs[1]);
		}
	}
	return 0;
}

void swap(int a,int b){
	int t;
	revs[links[a]]=b;
	revs[links[b]]=a;
	t=links[a];
	links[a]=links[b];
	links[b]=t;
	t=xors[a];
	xors[a]=xors[b];
	xors[b]=t;
	t=adjs[a];
	adjs[a]=adjs[b];
	adjs[b]=t;
}

void heapify(int ind){
	if(ind<<1>n){
		return ;
	}
	else if(ind<<1>n-1){
		if(adjs[ind]>adjs[ind<<1]){
			swap(ind,ind<<1);
		}
	}
	else{
		int i;
		i=adjs[ind]<adjs[ind<<1]?ind:ind<<1;
		if(adjs[ind]>adjs[i]){
			swap(ind,i);
		}
	}
}


from heapq import *
ax,ay,bx,by,tx,ty=map(int,input().split())
n=int(input())
f,a,t,no=[0]*n,[],1<<64,(0,0)
l=[tuple(map(int,input().split())) for _ in range(n)]
for i in range(n):
  x,y=l[i]
  lt=(tx-x)*(tx-x)+(ty-y)*(ty-y)
  la=(ax-x)*(ax-x)+(ay-y)*(ay-y)+lt
  lb=(bx-x)*(bx-x)+(by-y)*(by-y)+lt
  if la<t: t=la;no=(i,1)
  if lb<t: t=lb;no=(i,2)
ans,f[no[0]],fl=t**0.5,1,0
for i in range(n):
  x,y=l[i]
  lt=(tx-x)*(tx-x)+(ty-y)*(ty-y)
  ll=(ax-x)*(ax-x)+(ay-y)*(ay-y)+lt if no[1]==2 else (bx-x)*(bx-x)+(by-y)*(by-y)+lt
  heappush(a,(lt+lt,i,0))
  heappush(a,(ll,i,1))
while n-1:
  t,i,p=heappop(a)
  if f[i] or p==fl==1: continue
  if p==1: fl=1
  ans+=t**0.5
  n-=1
print(ans)


def readlist():
    return list(map(float, input().split()))

def hypot(P):
    a = 0
    for p in P:
        a += p*p
    return a**0.5

def dist(P1, P2):
    P = [P1[i] - P2[i] for i in range(len(P1))]
    return hypot(P)

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - b_2best, sum_dists - a_2best - b_best))


def readlist():
    return list(map(float, input().split()))

def hypot(P):
    a = 0
    for p in P:
        a += p*p
    return a**0.5

def dist(P1, P2):
    P = [P1[i] - P2[i] for i in range(len(P1))]
    return hypot(P)

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - max(0, b_2best), sum_dists - max(0, a_2best) - b_best))


#import math

def readlist():
    return list(map(float, input().split()))

def dist(P1, P2):
    aa = (P1[0] - P2[0])
    bb = P1[1] - P2[1]
    return (aa*aa + bb*bb)**0.5

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - max(0, b_2best), sum_dists - max(0, a_2best) - b_best))


import math

def readlist():
    return list(map(float, input().split()))

def dist(P1, P2):
    return math.hypot(P1[0] - P2[0], P1[1] - P2[1])

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - max(0, b_2best), sum_dists - max(0, a_2best) - b_best))


def readlist():
    return list(map(float, input().split()))

def hypot(P):
    a = 0
    for p in P:
        a += p*p
    return a**0.5

def dist(P1, P2):
    P = [P1[i] - P2[i] for i in range(len(P1))]
    return hypot(P)

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - b_2best, sum_dists - a_2best - b_best))


#import math

def readlist():
    return list(map(float, input().split()))

def dist(P1, P2):
    return ((P1[0] - P2[0])*(P1[0] - P2[0]) + (P1[1] - P2[1])*(P1[1] - P2[1]))**0.5

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - max(0, b_2best), sum_dists - max(0, a_2best) - b_best))


import math

def readlist():
    return list(map(float, input().split()))

def dist(P1, P2):
    return hypot(P1[0] - P2[0], P1[1] - P2[1])

ax, ay, bx, by, tx, ty = readlist()
A = [ax, ay]
B = [bx, by]
T = [tx, ty]
n = int(input())
Bottles = []
for i in range(n):
    Bottles.append(readlist())
dists_to_T = [dist(T, btl) for btl in Bottles]
sum_dists = 2*sum(dists_to_T)
A_possible_wins = [dist(btl, T) - dist(A, btl) for btl in Bottles]
B_possible_wins = [dist(btl, T) - dist(B, btl) for btl in Bottles]
a_best = max(A_possible_wins)
b_best = max(B_possible_wins)
if a_best < 0 or b_best < 0 or len(Bottles) == 1:
    print(sum_dists - max(a_best, b_best))
else:
    a_pos = A_possible_wins.index(a_best)
    b_pos = B_possible_wins.index(b_best)
    if (a_pos != b_pos):
        print(sum_dists - a_best - b_best)
    else:
        a_2best = max(A_possible_wins[:a_pos] + A_possible_wins[a_pos + 1:])
        b_2best = max(B_possible_wins[:b_pos] + B_possible_wins[b_pos + 1:])
        print(min(sum_dists - a_best - max(0, b_2best), sum_dists - max(0, a_2best) - b_best))


read = lambda : map(int, input().split())

def dis(x1, y1, x2, y2):

    return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5

ax, ay, bx, by, tx, ty = read()

n = int(input())

a, b = [], []

sum = 0

for i in range(n):

    x, y = read()

    dist = dis(tx, ty, x, y)

    a.append((dis(ax, ay, x, y) - dist, i))

    b.append((dis(bx, by, x, y) - dist, i))

    sum += dist * 2

a.sort()

b.sort()

if n > 1 and a[0][1] == b[0][1]:

    ans = min(a[0][0], b[0][0], a[0][0] + b[1][0], a[1][0] + b[0][0])

else:

    ans = min(a[0][0], b[0][0])

    if (n > 1) :

        ans = min(a[0][0] + b[0][0], ans)

print(ans + sum)

# Made By Mostafa_Khaled


import math

def dis(x1, y1, x2, y2):
  return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

str = input().split()
argu = []
for i in str:
  argu.append(int(i))

n = int(input())
total = 0
array = [[], []]
for i in range(n):
  x, y = input().split()
  x = int(x)
  y = int(y)
  td = dis(x, y, argu[4], argu[5])
  ad = dis(x, y, argu[0], argu[1])
  bd = dis(x, y, argu[2], argu[3])
  total += 2 * td
  array[0].append((i, ad - td))
  array[1].append((i, bd - td))

if n == 1:
  print("%.12f" % (total + min(array[0][0][1], array[1][0][1])))
else:
  def sortkey(x):
    return x[1]

  array[0].sort(key = sortkey)
  array[1].sort(key = sortkey)

  ans = total + array[0][0][1]
  ans = min(ans, total + array[1][0][1])
  for i in range(2):
    for j in range(2):
      tmpa = array[0][i]
      tmpb = array[1][j]
      if tmpa[0] != tmpb[0]:
        ans = min(ans, total + tmpa[1] + tmpb[1])
  print("%.12f" % ans)


import math

def dis(x1, y1, x2, y2):
  return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

str = input().split()
argu = []
for i in str:
  argu.append(int(i))

n = int(input())
total = 0
array = []
for i in range(n):
  x, y = input().split()
  x = int(x)
  y = int(y)
  td = dis(x, y, argu[4], argu[5])
  ad = dis(x, y, argu[0], argu[1])
  bd = dis(x, y, argu[2], argu[3])
  total += 2 * td
  array.append((i, ad - td, bd - td))

if n == 1:
  print("%.12f" % (total + min(array[0][1], array[0][2])))
else:
  def asort(x):
    return x[1]
  def bsort(x):
    return x[2]
  array.sort(key = asort)
  aFirst = array[0]
  aSecond = array[1]
  array.sort(key = bsort)
  bFirst = array[0]
  bSecond = array[1]

  if aFirst[0] != bFirst[0]:
    print("%.12f" % (total + aFirst[1] + bFirst[2]))
  else:
    tmpa = aFirst[1] + bSecond[2]
    tmpb = aSecond[1] + bFirst[2]
    print("%.12f" % (total + min(tmpa, tmpb)))


import math

def dis(x1, y1, x2, y2):
  return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

str = input().split()
argu = []
for i in str:
  argu.append(int(i))

n = int(input())
data = []
for i in range(n):
  x, y = input().split()
  x = int(x)
  y = int(y)
  td = dis(x, y, argu[4], argu[5])
  ad = dis(x, y, argu[0], argu[1])
  bd = dis(x, y, argu[2], argu[3])
  data.append((td, ad, bd))

if n == 1:
  print("%.12f" % (data[0][0] + min(data[0][1], data[0][2])))
else:
  def sortkey(x):
    return x[1]

  array = []
  for i in range(n):
    array.append((i, data[i][1] - data[i][0]))
  array.sort(key = sortkey)
  aFirst = array[0]
  aSecond = array[1]

  array = []
  for i in range(n):
    array.append((i, data[i][2] - data[i][0]))
  array.sort(key = sortkey)
  bFirst = array[0]
  bSecond = array[1]

  def getans(a, b):
    total = 0
    for i in range(n):
      if i == a:
        total += data[i][0] + data[i][1]
      elif i == b:
        total += data[i][0] + data[i][2]
      else:
        total += 2 * data[i][0]
    return total

  if aFirst[0] != bFirst[0]:
    print("%.12f" % getans(aFirst[0], bFirst[0]))
  else:
    tmpa = aFirst[1] + bSecond[1]
    tmpb = aSecond[1] + bFirst[1]
    if tmpa < tmpb:
      print("%.12f" % getans(aFirst[0], bSecond[0]))
    else:
      print("%.12f" % getans(aSecond[0], bFirst[0]))


import math

def dis(x1, y1, x2, y2):
  return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)

str = input().split()
argu = []
for i in str:
  argu.append(int(i))

n = int(input())
data = []
for i in range(n):
  x, y = input().split()
  x = int(x)
  y = int(y)
  td = dis(x, y, argu[4], argu[5])
  ad = dis(x, y, argu[0], argu[1])
  bd = dis(x, y, argu[2], argu[3])
  data.append((td, ad, bd))

if n == 1:
  print("%.12f" % (data[0][0] + min(data[0][1], data[0][2])))
else:
  def sortkey(x):
    return x[1]

  array = []
  for i in range(n):
    array.append((i, data[i][1] - data[i][0]))
  array.sort(key = sortkey)
  aFirst = array[0]
  aSecond = array[1]

  for i in range(n):
    array.append((i, data[i][2] - data[i][0]))
  array.sort(key = sortkey)
  bFirst = array[0]
  bSecond = array[1]

  def getans(a, b):
    total = 0
    for i in range(n):
      if i == a:
        total += data[i][0] + data[i][1]
      elif i == b:
        total += data[i][0] + data[i][2]
      else:
        total += 2 * data[i][0]
    return total

  if aFirst[0] != bFirst[0]:
    print("%.12f" % getans(aFirst[0], bFirst[0]))
  else:
    tmpa = aFirst[1] + bSecond[1]
    tmpb = aSecond[1] + bFirst[1]
    if tmpa < tmpb:
      print("%.12f" % getans(aFirst[0], bSecond[0]))
    else:
      print("%.12f" % getans(aSecond[0], bFirst[0]))


import os,io
from sys import stdout
import collections
# import random
# import math
# from operator import itemgetter
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline
# from collections import Counter
# from decimal import Decimal
# import heapq
# from functools import lru_cache

import sys
# import threading
# sys.setrecursionlimit(10**6)
# threading.stack_size(102400000)

# from functools import lru_cache
# @lru_cache(maxsize=None)

######################
# --- Maths Fns  --- #
######################
def primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

def binomial_coefficient(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok // ktok
    else:
        return 0

def powerOfK(k, max):
    if k == 1:
        return [1]
    if k == -1:
        return [-1, 1]

    result = []
    n = 1
    while n <= max:
        result.append(n)
        n *= k
    return result

def divisors(n):
    i = 1
    result = []
    while i*i <= n:
        if n%i == 0:
            if n/i == i:
                result.append(i)
            else:
                result.append(i)
                result.append(n/i)
        i+=1
    return result

# @lru_cache(maxsize=None)
def digitsSum(n):
    if n == 0:
        return 0
    r = 0
    while n > 0:
        r += n % 10
        n //= 10
    return r

######################
# ---- GRID Fns ---- #
######################
def isValid(i, j, n, m):
    return i >= 0 and i < n and j >= 0 and j < m

def print_grid(grid):
    for line in grid:
        print(" ".join(map(str,line)))

######################
# ---- MISC Fns ---- #
######################
def kadane(a,size):
    max_so_far = 0
    max_ending_here = 0

    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here

        if max_ending_here < 0:
            max_ending_here = 0
    return max_so_far

def prefixSum(arr):
    for i in range(1, len(arr)):
        arr[i] = arr[i] + arr[i-1]
    return arr

def ceil(n, d):
    if n % d == 0:
        return n // d
    else:
        return (n // d) + 1

# INPUTS  --------------------------
# s = input().decode('utf-8').strip()
# n = int(input())
# l = list(map(int, input().split()))
# t = int(input())
# for _ in range(t):
# for _ in range(t):
from decimal import Decimal

def distance(xa, ya, xb, yb):
    return (((ya-yb)**2 + (xa-xb)**2)**Decimal(0.5))

xa, ya, xb, yb, xt, yt = list(map(int, input().split()))
n = int(input())

distanceToA = []
distanceToB = []

for _ in range(n):
    xbt, ybt = list(map(int, input().split()))
    da = distance(xa, ya, xbt, ybt)
    db = distance(xb, yb, xbt, ybt)
    dt = distance(xt, yt, xbt, ybt)
    impA = da-dt
    impB = db-dt
    distanceToA.append((impA, xbt, ybt, dt))
    distanceToB.append((impB, xbt, ybt, dt))

A = sorted(distanceToA, key=lambda x: x[0])
B = sorted(distanceToB, key=lambda x: x[0])

if n == 1:
    impA, xbt, ybt, dt = A[0]
    impB, xbt, ybt, dt = B[0]
    print(min(impA, impB)+2*dt)
    exit()

seen = set()
total = 0
impA, xbtA, ybtA, dtA = A[0]
impB, xbtB, ybtB, dtB = B[0]
if xbtA == xbtB and ybtA == ybtB:
    impA1, xbtA1, ybtA1, dtA1 = A[1]
    impB1, xbtB1, ybtB1, dtB1 = B[1]
    if impA + impB1 < impB + impA1:
        total += 2*dtA+impA
        seen.add((xbtA, ybtA))
        total += 2*dtB1+impB1
        seen.add((xbtB1, ybtB1))
    else:
        total += 2*dtB+impB
        seen.add((xbtB, ybtB))
        total += 2*dtA1+impA1
        seen.add((xbtA1, ybtA1))
else:
    total += 2*dtA + impA
    total += 2*dtB + impB
    seen.add((xbtA, ybtA))
    seen.add((xbtB, ybtB))

for e in A:
    imp, xbt, ybt, dt = e
    if (xbt, ybt) not in seen:
        total += 2*dt
print(total)


import os,io
from sys import stdout
import collections
# import random
# import math
# from operator import itemgetter
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline
# from collections import Counter
# from decimal import Decimal
# import heapq
# from functools import lru_cache

import sys
# import threading
# sys.setrecursionlimit(10**6)
# threading.stack_size(102400000)

# from functools import lru_cache
# @lru_cache(maxsize=None)

######################
# --- Maths Fns  --- #
######################
def primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

def binomial_coefficient(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok // ktok
    else:
        return 0

def powerOfK(k, max):
    if k == 1:
        return [1]
    if k == -1:
        return [-1, 1]

    result = []
    n = 1
    while n <= max:
        result.append(n)
        n *= k
    return result

def divisors(n):
    i = 1
    result = []
    while i*i <= n:
        if n%i == 0:
            if n/i == i:
                result.append(i)
            else:
                result.append(i)
                result.append(n/i)
        i+=1
    return result

# @lru_cache(maxsize=None)
def digitsSum(n):
    if n == 0:
        return 0
    r = 0
    while n > 0:
        r += n % 10
        n //= 10
    return r

######################
# ---- GRID Fns ---- #
######################
def isValid(i, j, n, m):
    return i >= 0 and i < n and j >= 0 and j < m

def print_grid(grid):
    for line in grid:
        print(" ".join(map(str,line)))

######################
# ---- MISC Fns ---- #
######################
def kadane(a,size):
    max_so_far = 0
    max_ending_here = 0

    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here

        if max_ending_here < 0:
            max_ending_here = 0
    return max_so_far

def prefixSum(arr):
    for i in range(1, len(arr)):
        arr[i] = arr[i] + arr[i-1]
    return arr

def ceil(n, d):
    if n % d == 0:
        return n // d
    else:
        return (n // d) + 1

# INPUTS  --------------------------
# s = input().decode('utf-8').strip()
# n = int(input())
# l = list(map(int, input().split()))
# t = int(input())
# for _ in range(t):
# for _ in range(t):

def distance(xa, ya, xb, yb):
    return ((ya-yb)**2 + (xa-xb)**2)**(0.5)

xa, ya, xb, yb, xt, yt = list(map(int, input().split()))
n = int(input())

import math
bottles = []
ans = 0
ra, rb = [], []
for _ in range(n):
    xbt, ybt = list(map(int, input().split()))
    bottles.append((xbt, ybt))
    da = distance(xa, ya, xbt, ybt)
    db = distance(xb, yb, xbt, ybt)
    dt = distance(xt, yt, xbt, ybt)
    ra.append((da-dt, xbt, ybt, dt))
    rb.append((db-dt, xbt, ybt, dt))
    ans += 2*dt

ra = sorted(ra, key=lambda x: x[0])
rb = sorted(rb, key=lambda x: x[0])

if n == 1:
    print(ans+min(ra[0][0], rb[0][0]))
    exit()

a0 = ra[0]
a1 = ra[1]
b0 = rb[0]
b1 = rb[1]
if a0[0] <= 0 and b0[0] <= 0:
    if a0[1] == b0[1] and a0[2] == b0[2]:
        print(ans + min(a0[0]+b1[0], b0[0]+a1[0]))
        exit()
    else:
        print(ans + a0[0] + b0[0])
        exit()
else:
    print(ans + min(a0[0], b0[0]))


import os,io
from sys import stdout
import collections
# import random
# import math
# from operator import itemgetter
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline
# from collections import Counter
# from decimal import Decimal
# import heapq
# from functools import lru_cache

import sys
# import threading
# sys.setrecursionlimit(10**6)
# threading.stack_size(102400000)

# from functools import lru_cache
# @lru_cache(maxsize=None)

######################
# --- Maths Fns  --- #
######################
def primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

def binomial_coefficient(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok // ktok
    else:
        return 0

def powerOfK(k, max):
    if k == 1:
        return [1]
    if k == -1:
        return [-1, 1]

    result = []
    n = 1
    while n <= max:
        result.append(n)
        n *= k
    return result

def divisors(n):
    i = 1
    result = []
    while i*i <= n:
        if n%i == 0:
            if n/i == i:
                result.append(i)
            else:
                result.append(i)
                result.append(n/i)
        i+=1
    return result

# @lru_cache(maxsize=None)
def digitsSum(n):
    if n == 0:
        return 0
    r = 0
    while n > 0:
        r += n % 10
        n //= 10
    return r

######################
# ---- GRID Fns ---- #
######################
def isValid(i, j, n, m):
    return i >= 0 and i < n and j >= 0 and j < m

def print_grid(grid):
    for line in grid:
        print(" ".join(map(str,line)))

######################
# ---- MISC Fns ---- #
######################
def kadane(a,size):
    max_so_far = 0
    max_ending_here = 0

    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here

        if max_ending_here < 0:
            max_ending_here = 0
    return max_so_far

def prefixSum(arr):
    for i in range(1, len(arr)):
        arr[i] = arr[i] + arr[i-1]
    return arr

def ceil(n, d):
    if n % d == 0:
        return n // d
    else:
        return (n // d) + 1

# INPUTS  --------------------------
# s = input().decode('utf-8').strip()
# n = int(input())
# l = list(map(int, input().split()))
# t = int(input())
# for _ in range(t):
# for _ in range(t):
from decimal import Decimal

def distance(xa, ya, xb, yb):
    return (((ya-yb)**2 + (xa-xb)**2)**(0.5))

def distanceDec(xa, ya, xb, yb):
    return (((ya-yb)**2 + (xa-xb)**2)**Decimal(0.5))

xa, ya, xb, yb, xt, yt = list(map(int, input().split()))
n = int(input())

distanceToA = []
distanceToB = []

bottles = []

for _ in range(n):
    xbt, ybt = list(map(int, input().split()))
    bottles.append((xbt, ybt))
    da = distance(xa, ya, xbt, ybt)
    db = distance(xb, yb, xbt, ybt)
    dt = distance(xt, yt, xbt, ybt)
    impA = da-dt
    impB = db-dt
    distanceToA.append((impA, xbt, ybt, dt))
    distanceToB.append((impB, xbt, ybt, dt))

A = sorted(distanceToA, key=lambda x: x[0])
B = sorted(distanceToB, key=lambda x: x[0])

if n == 1:
    impA, xbt, ybt, dt = A[0]
    impB, xbt, ybt, dt = B[0]
    print(min(impA, impB)+2*dt)
    exit()

seen = set()
total = 0
impA, xbtA, ybtA, dtA = A[0]
impB, xbtB, ybtB, dtB = B[0]
if xbtA == xbtB and ybtA == ybtB:
    impA1, xbtA1, ybtA1, dtA1 = A[1]
    impB1, xbtB1, ybtB1, dtB1 = B[1]
    if impA + impB1 < impB + impA1:
        total += 2*dtA+impA
        seen.add((xbtA, ybtA))
        total += 2*dtB1+impB1
        seen.add((xbtB1, ybtB1))
    else:
        total += 2*dtB+impB
        seen.add((xbtB, ybtB))
        total += 2*dtA1+impA1
        seen.add((xbtA1, ybtA1))
else:
    total += 2*dtA + impA
    total += 2*dtB + impB
    seen.add((xbtA, ybtA))
    seen.add((xbtB, ybtB))

for e in bottles:
    total = Decimal(total)
    xbt, ybt = e
    if (xbt, ybt) not in seen:
        total += 2*distanceDec(xbt, ybt, xt, yt)
print(total)


import os,io
from sys import stdout
import collections
# import random
# import math
# from operator import itemgetter
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline
# from collections import Counter
# from decimal import Decimal
# import heapq
# from functools import lru_cache

import sys
# import threading
# sys.setrecursionlimit(10**6)
# threading.stack_size(102400000)

# from functools import lru_cache
# @lru_cache(maxsize=None)

######################
# --- Maths Fns  --- #
######################
def primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

def binomial_coefficient(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok // ktok
    else:
        return 0

def powerOfK(k, max):
    if k == 1:
        return [1]
    if k == -1:
        return [-1, 1]

    result = []
    n = 1
    while n <= max:
        result.append(n)
        n *= k
    return result

def divisors(n):
    i = 1
    result = []
    while i*i <= n:
        if n%i == 0:
            if n/i == i:
                result.append(i)
            else:
                result.append(i)
                result.append(n/i)
        i+=1
    return result

# @lru_cache(maxsize=None)
def digitsSum(n):
    if n == 0:
        return 0
    r = 0
    while n > 0:
        r += n % 10
        n //= 10
    return r

######################
# ---- GRID Fns ---- #
######################
def isValid(i, j, n, m):
    return i >= 0 and i < n and j >= 0 and j < m

def print_grid(grid):
    for line in grid:
        print(" ".join(map(str,line)))

######################
# ---- MISC Fns ---- #
######################
def kadane(a,size):
    max_so_far = 0
    max_ending_here = 0

    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here

        if max_ending_here < 0:
            max_ending_here = 0
    return max_so_far

def prefixSum(arr):
    for i in range(1, len(arr)):
        arr[i] = arr[i] + arr[i-1]
    return arr

def ceil(n, d):
    if n % d == 0:
        return n // d
    else:
        return (n // d) + 1

# INPUTS  --------------------------
# s = input().decode('utf-8').strip()
# n = int(input())
# l = list(map(int, input().split()))
# t = int(input())
# for _ in range(t):
# for _ in range(t):

def distance(xa, ya, xb, yb):
    return ((ya-yb)**2 + (xa-xb)**2)**(0.5)

xa, ya, xb, yb, xt, yt = list(map(int, input().split()))
n = int(input())

import math
bottles = []
ans = 0
ra, rb = [], []
for _ in range(n):
    xbt, ybt = list(map(int, input().split()))
    bottles.append((xbt, ybt))
    da = distance(xa, ya, xbt, ybt)
    db = distance(xb, yb, xbt, ybt)
    dt = distance(xt, yt, xbt, ybt)
    ra.append((da-dt, xbt, ybt, dt))
    rb.append((db-dt, xbt, ybt, dt))
    ans += 2*dt

ra = sorted(ra, key=lambda x: x[0])
rb = sorted(rb, key=lambda x: x[0])

if n == 1:
    print(ans+min(ra[0][0], rb[0][0]))
    exit()

a0 = ra[0]
a1 = ra[1]
b0 = rb[0]
b1 = rb[1]
if a0[0] < 0 and b0[0] < 0:
    if a0[1] == b0[1] and a0[2] == b0[2]:
        print(ans + min(a0[0]+b1[0], b0[0]+a1[0]))
        exit()
    else:
        print(ans + a0[0] + b0[0])
        exit()
else:
    print(ans - min(a0[0], b0[0]))