import java.util.*;
import java.awt.Polygon;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.*;
import java.util.Collection;

public class Solution {

	/**
	 * @param args
	 * @throws IOException
	 */
	static StringTokenizer st;
	static BufferedReader reader;
	public static void main(String[] args) throws IOException {
		reader = new BufferedReader(new InputStreamReader(System.in));
		int xs = NextInt();
		int ys = NextInt();
		int n = NextInt();

		int x[] = new int[n];
		int y[] = new int[n];
		int single[] = new int[n];
		int pair[][] = new int[n][n];
		for (int i = 0; i < n; ++i) {
			x[i] = NextInt();
			y[i] = NextInt();
		}
		for (int i = 0; i < n; ++i)
			single[i] = 2 * dist(xs, ys, x[i], y[i]);
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				pair[i][j] = dist(xs, ys, x[i], y[i]) +
							 dist(x[i], y[i], x[j], y[j]) +
							 dist(x[j], y[j], xs, ys);
		int dp[] = new int[1 << n];
		int prev[] = new int[1 << n];
		for (int mask = 0; mask < (1 << n); ++mask) {
			int p = -1;
			for (int i = 0; i < n; ++i)
				if (((mask >> i) & 1) != 0) {
					p = i;
					break;
				}
			if (p == -1) continue;
			dp[mask] = dp[mask ^ (1 << p)] + single[p];
			prev[mask] = p;
			for (int j = p + 1; j < n; ++j) {
				if (((mask >> j) & 1) != 0) {
					int res = pair[p][j] + dp[mask ^ (1 << p) ^ (1 << j)];
					if (res < dp[mask]) {
						dp[mask] = res;
						prev[mask] = p + 100 * j;
					}
				}
			}
		}
		int cur = (1 << n) - 1;
		System.out.printf("%d\n0 ", dp[cur]);
		while(cur != 0) {
			if (prev[cur] < 100) {
				System.out.printf("%d %d ", prev[cur] + 1, 0);
				cur ^= (1 << prev[cur]);
			} else {
				int i = prev[cur] / 100;
				int j = prev[cur] % 100;
				System.out.printf("%d %d %d ", i + 1, j + 1, 0);
				cur = cur ^ (1 << i) ^ (1 << j);
			}
		}
	}
	static int dist(int x0, int y0, int x1, int y1) {
		return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
	}
	static int NextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(NextToken());
	}
	static String NextToken() throws IOException {
		while(st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(reader.readLine());
		}
		return st.nextToken();
	}

}

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;
/**
 * 9:50 ~
 *
 */
public class Main {
	public static int n, x, y;
	public static int[] a,b;
	public static int dp[], before[];
	public static int dx[];
	public static int d[][];
	public static final int INF = 24 * 201 * 201;
	public static void main(String[] argv) {
		FastScanner scan = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		x = scan.nextInt();
		y = scan.nextInt();

		n = scan.nextInt();

		a = new int[n+1];
		b = new int[n+1];
		dx = new int[n+1];
		d = new int[n+1][n+1];
		for(int i = 0; i < n; ++i){
			a[i] = scan.nextInt();
			b[i] = scan.nextInt();
		}

		for(int i = 0; i < n; ++i){
			dx[i] = dist(i);
		}
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < n; ++j){
				d[i][j] = dist(i,j);
			}
		}

		dp = new int[1 << n];
		before = new int[1 << n];
		Arrays.fill(dp, INF);
		dp[0] = 0;
		for(int state = 0; state < (1<<n); state++){
			//if(dp[state] == INF) continue;
			for(int i = 0; i < n; ++i){
				int ii = (1 << i);
				if((state & ii) > 0){
					if(dp[state - ii] == INF) continue;
					int newdist = dp[state - ii] + dx[i] + dx[i];
					if(dp[state] > newdist){
						dp[state] = newdist;
						before[state] = state - ii;
					}

				} else continue;

				for(int j = i + 1; j < n; ++j){
					if(i == j) continue;
					int jj = (1 << j);
					if((state & jj) > 0){
						if(dp[state - ii - jj] == INF) continue;
						int newdist = dp[state - ii - jj] + dx[i] + d[i][j] + dx[j];
						if(dp[state] > newdist){
							dp[state] = newdist;
							before[state] = state - ii - jj;
						}

					}
				}
				break;
			}
		}

		System.out.println(dp[(1<<n)-1]);
		int state = (1<<n) - 1;
		StringBuffer ret = new StringBuffer();
		while(state > 0){
			int nstate = before[state];
			boolean find = false;
			String made = "";
			for(int i = 0; i < n; ++i){
				if(((state & (1<<i)) > 0) && ((nstate & (1<<i)) == 0)){
					find = true;
					made = made + " " + (i + 1);
				}
			}
			if(find){
				made = made + " 0";
				ret.append(made, 0, made.length());
			}
			state = nstate;
		}
		out.println("0" + ret.toString());
		out.close();
	}
	public static int dist(int to){
		return Math.abs(a[to] - x) * Math.abs(a[to] - x) + Math.abs(b[to] - y) * Math.abs(b[to] - y);
	}
	public static int dist(int from, int to){
		return Math.abs(a[from]-a[to]) * Math.abs(a[from]-a[to]) + Math.abs(b[from]-b[to]) * Math.abs(b[from]-b[to]);
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(InputStream is) {
			try {
				br = new BufferedReader(new InputStreamReader(is));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					return null;
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.valueOf(next());
		}
	}
}

import java.util.*;
import java.io.*;

public class Main {

    static final int MAXN = 24;
    int[] x = new int[MAXN];
    int[] y = new int[MAXN];
    int[][] dist = new int[MAXN][MAXN];
    int[] single = new int[MAXN];

    int sqr(int x) { return x * x; }

    void run(int nT) {
        int xs = cin.nextInt();
        int ys = cin.nextInt();
        int n = cin.nextInt();
        for (int i = 0; i < n; ++i) {
            x[i] = cin.nextInt();
            y[i] = cin.nextInt();
        }
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                dist[i][j] = sqr(x[i] - xs) + sqr(y[i] - ys)
                    + sqr(x[i] - x[j]) + sqr(y[i] - y[j]) + sqr(x[j] - xs) + sqr(y[j] - ys);
            }
        }
        for (int i = 0; i < n; ++i) {
            single[i] = (sqr(x[i] - xs) + sqr(y[i] - ys)) * 2;
        }
        int[] dp = new int[1 << n];
        int[] pre = new int[1 << n];
        int tot = 1 << n;
        for (int s = 1; s < tot; ++s) {
            int i;
            for (i = 0; i < n; ++i) {
                if ((s & (1 << i)) != 0) break;
            }
            dp[s] = dp[s^(1<<i)] + single[i];
            pre[s] = i + 1;
            for (int j = i + 1; j < n; ++j) {
                if ((s & (1 << j)) != 0) {
                    int cur = dp[s^(1 << i) ^(1<<j)] + dist[i][j];
                    if (cur < dp[s]) {
                        dp[s] = cur;
                        pre[s] = (i + 1) * 100 + (j + 1);
                    }
                }
            }
        }
        out.println(dp[tot - 1]);
        int now = tot - 1;
        out.print("0");
        while (now > 0) {
            int what = pre[now];
            int px = what % 100 - 1;
            int py = what / 100 - 1;
            if (px >= 0) {
                out.print(" ");
                out.print(px + 1);
                now ^= 1 << px;
            }
            if (py >= 0) {
                out.print(" ");
                out.print(py + 1);
                now ^= 1 << py;
            }
            out.print(" ");
            out.print("0");
        }
        out.println("");
    }

    public static void main(String[] argv) {
        Main solved = new Main();
        int T = 1;
        // T = solved.cin.nextInt();
        for (int nT = 1; nT <= T; ++nT) {
            solved.run(nT);
        }
        solved.out.close();
    }

    InputReader cin = new InputReader(System.in);
    PrintWriter out = new PrintWriter(System.out);
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }
}

import java.util.*;
import java.io.*;

public class C0008 {

    public static void main(String args[]) throws Exception {
        new C0008();
    }

    int n;
    int target;
    int pow[];
    int dp[];
    int next[];
    int dist[][];

    C0008() throws Exception {
        PandaScanner sc = null;
        PrintWriter out = null;
        try {
            sc = new PandaScanner(System.in);
            out = new PrintWriter(System.out);
        } catch (Exception ignored) {
        }

        pow = new int[26];
        for (int i = 0; i < 26; i++) {
            pow[i] = 1 << i;
        }

        dist = new int[26][26];
        int[][] p = new int[26][];
        p[25] = new int[] {sc.nextInt(), sc.nextInt()};
        n = sc.nextInt();
        target = (1 << n) - 1;

        for (int i = 0; i < n; i++) {
            p[i] = new int[] {sc.nextInt(), sc.nextInt()};
            dist[i][25] = getDist(p[i], p[25]);
            for (int j = 0; j < i; j++) {
                dist[j][i] = getDist(p[j], p[i]);
            }
        }

        next = new int[1 << n];

        dp = new int[1 << n];
        Arrays.fill(dp, -1);

        out.println(go(0));

        ArrayList<Integer> paths = new ArrayList<Integer>();
        paths.add(0);
        int curr = 0;
        while (curr != target) {
            for (Integer i: getBits(next[curr], true)) {
                paths.add(i + 1);
            }
            paths.add(0);
            curr |= next[curr];
        }
        out.println(paths.toString().replaceAll("[^ 0-9]", ""));

        out.close();
        System.exit(0);
    }

    int go(int mask) {
        if (mask == target) {
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }

        ArrayList<Integer> notDone = getBits(mask, false);

        dp[mask] = Integer.MAX_VALUE;

        for (Integer i: notDone) {
            int oneD = (dist[i][25] << 1) + go(mask | pow[i]);
            if (dp[mask] > oneD) {
                dp[mask] = oneD;
                next[mask] = 1 << i;
            }
            for (Integer j: notDone) {
                if (j == i) continue;
                int d = (dist[j][25] + dist[i][j] + dist[i][25]) + go(mask | pow[i] | pow[j]);
                if (dp[mask] > d) {
                    dp[mask] = d;
                    next[mask] = (1 << i) | (1 << j);
                }
            }
            break;
        }

        return dp[mask];
    }

    int getDist(int[] p1, int[] p2) {
        return sq(p1[0] - p2[0]) + sq(p1[1] - p2[1]);
    }

    int sq(int a) {
        return a * a;
    }

    ArrayList<Integer> getBits(int mask, boolean on) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            if (((mask & (1 << i)) == 0) ^ on) {
                res.add(i);
            }
        }
        return res;
    }

    //The PandaScanner class, for Panda fast scanning!
    public class PandaScanner {
        BufferedReader br;
        StringTokenizer st;
        InputStream in;

        PandaScanner(InputStream in) throws Exception {
            br = new BufferedReader(new InputStreamReader(this.in = in));
        }

        public String next() throws Exception {
            if (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(br.readLine().trim());
                return next();
            }
            return st.nextToken();
        }

        public boolean hasNext() throws Exception {
            return (st != null && st.hasMoreTokens()) || in.available() > 0;
        }

        public long nextLong() throws Exception {
            return Long.parseLong(next());
        }

        public int nextInt() throws Exception {
            return Integer.parseInt(next());
        }
    }
}

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.io.Writer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Nguyen Trung Hieu - vuondenthanhcong11@yahoo.com
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int xs = in.readInt();
        int ys = in.readInt();
        int n = in.readInt();
        int[] x = new int[n];
        int[] y = new int[n];
        IOUtils.readIntArrays(in, x, y);
        int[] res = new int[1 << n];
        int[] last = new int[1 << n];
        Arrays.fill(res, Integer.MAX_VALUE);
        int[] ds = new int[n];
        for (int i = 0; i < n; i++) {
            ds[i] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys);
        }
        int[][] d = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++)
                d[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
        }
        res[0] = 0;
        for (int i = 1; i < (1 << n); i++) {
            for (int j = 0; j < n; j++) {
                if (((i >> j) & 1) != 0) {
                    if (res[i - (1 << j)] + 2 * ds[j] < res[i]) {
                        res[i] = res[i - (1 << j)] + 2 * ds[j];
                        last[i] = i - (1 << j);
                    }
                    for (int k = j + 1; k < n; k++) {
                        if (((i >> k) & 1) != 0) {
                            if (res[i - (1 << j) - (1 << k)] + ds[j] + ds[k] + d[j][k] < res[i]) {
                                res[i] = res[i - (1 << j) - (1 << k)] + ds[j] + ds[k] + d[j][k];
                                last[i] = i - (1 << j) - (1 << k);
                            }
                        }
                    }
                    break;
                }
            }
        }
        int cur = (1 << n) - 1;
        out.printLine(res[cur]);
        while (cur != 0) {
            out.print("0 ");
            int dif = cur - last[cur];
            for (int i = 0; i < n && dif != 0; i++) {
                if (((dif >> i) & 1) != 0) {
                    out.print((i + 1) + " ");
                    dif -= (1 << i);
                }
            }
            cur = last[cur];
        }
        out.printLine("0");
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }

    }

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

import java.io.*;
import java.util.*;

public class Main {

    BufferedReader in = null;
    PrintWriter out = null;

    int dist(int x1, int y1, int x2, int y2) {
        int dx = Math.abs(x1 - x2);
        int dy = Math.abs(y1 - y2);
        return dx * dx + dy * dy;
    }

    boolean testBit(int use, int p) {
        return ((use >> p) & 1) == 1;
    }

    int rec(int use, int a[][], int dp[], int next[]) {
        if (dp[use] != -1) {
            return dp[use];
        }
        if (use == 0) {
            return dp[use] = 0;
        }
        int n = a.length;
        int ix = -1;

        for (int i = 0; i < n; ++i) {
            if (testBit(use, i)) {
                if (ix == -1) {
                    ix = i;
                    break;
                }

                /*
                int t = rec(use ^ (1 << i), a, dp);
                t += a[i][i];
                r = Math.min(r, t);*/
            }
        }

        int r = rec(use ^ (1 << ix), a, dp, next) + a[ix][ix];
        next[use] = use ^ (1 << ix);

        for (int i = ix + 1; i < n; ++i) {
            if (!testBit(use, i)) {
                continue;
            }
            int t = rec(use ^ (1 << ix) ^ (1 << i), a, dp, next);
            t += a[ix][i];
            if (t < r) {
                r = t;
                next[use] = use ^ (1 << ix) ^ (1 << i);
            }
        }

        return dp[use] = r;
    }

    void print(int use1, int use2, int n) {
        for (int i = 0; i < n; ++i) {
            if (testBit(use1, i) ^ testBit(use2, i)) {
                int x = i + 1;
                out.print(x + " ");
            }
        }
    }

    void solve() throws IOException {
        in = new BufferedReader(new InputStreamReader(System.in));
        //in = new BufferedReader(new FileReader("input.txt"));
        out = new PrintWriter(System.out);

        StringTokenizer st;
        st = new StringTokenizer(in.readLine());
        int sx = Integer.valueOf(st.nextToken());
        int sy = Integer.valueOf(st.nextToken());
        st = new StringTokenizer(in.readLine());
        int n = Integer.valueOf(st.nextToken());
        int x[] = new int[n];
        int y[] = new int[n];
        for (int i = 0; i < n; ++i) {
            st = new StringTokenizer(in.readLine());
            x[i] = Integer.valueOf(st.nextToken());
            y[i] = Integer.valueOf(st.nextToken());
        }
        int a[][] = new int[n][n];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                a[i][j] = dist(x[i], y[i], sx, sy) + dist(x[j], y[j], sx, sy) + dist(x[i], y[i], x[j], y[j]);
            }
        }

        int dp[] = new int[1 << n];
        Arrays.fill(dp, -1);
        int next[] = new int[1 << n];
        int ans = rec((1 << n) - 1, a, dp, next);

        out.println(ans);

        int use = (1 << n) - 1;
        while (true) {
            int nuse = next[use];
            out.print("0 ");
            print(use, nuse, n);
            if (nuse == 0) break;
            use = nuse;
        }
        out.println("0");

        in.close();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().solve();
    }

}

import static java.util.Arrays.*;
import static java.lang.Math.*;
import java.util.*;
import java.io.*;

public class Main implements Runnable
{
	public static void main(String [] args) throws IOException
	{
		new Thread(null, new Main(), "", 1 << 20).start();
	}

	String file = "input";
	BufferedReader input;
	PrintWriter out;

	public void run()
	{
		try
		{
			//input = new BufferedReader(new FileReader(file + ".in"));
			input = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new BufferedOutputStream(System.out));
			solve();
			input.close();
			out.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}
	}
	int[] x = new int[25];
	int[] y = new int[25];
	int[][] dist = new int[25][25];
	int[] single = new int[25];
	int[] c = new int[25];
	int INF = 1 << 30;
	void solve() throws IOException
	{
		StringTokenizer st = tokens();
		x[0] = nextInt(st);
		y[0] = nextInt(st);
		int n = nextInt();
		for(int i = 1; i <= n; i++)
		{
			st = tokens();
			x[i] = nextInt(st);
			y[i] = nextInt(st);
		}
		for(int i = 1; i <= n; i++)
			single[i] = 2 * ((x[i] - x[0]) * (x[i] - x[0]) + (y[i] - y[0]) * (y[i] - y[0]));
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				dist[i][j] = single[i] / 2 + single[j] / 2 + (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
		int[] dp = new int[1 << n];
		int[] prev = new int[1 << n];
		fill(dp, INF);
		dp[0] = 0;
		for(int i = 1; i < 1 << n; i++)
		{
			for(int j = 0; j < n; j++)
			{
				if((i >> j & 1) != 0)
				{
					if(dp[i] > dp[i ^ (1 << j)] + single[j + 1])
					{
						dp[i] = dp[i ^ (1 << j)] + single[j + 1];
						prev[i] = j + 1;
					}

					for(int k = j + 1; k < n; k++)
						if((i >> k & 1) != 0)
						{
							if(dp[i] > dp[i ^ (1 << j) ^ (1 << k)] + dist[j + 1][k + 1])
							{
								dp[i] = dp[i ^ (1 << j) ^ (1 << k)] + dist[j + 1][k + 1];
								prev[i] = (j + 1) * 100 + (k + 1);
							}
						}
					break;
				}
			}
		}
		out.println(dp[(1 << n) - 1]);
		out.print("0 ");
		int mask = (1 << n) - 1;
		while(mask > 0)
		{
			int s = prev[mask];
			int x = s / 100;
			int y = s % 100;
			if(x == 0)
			{
				out.print(y + " " + 0 + " ");
				mask -= 1 << (y - 1);
			}
			else
			{
				out.print(x + " " + y + " " + 0 + " ");
				mask -= 1 << (y - 1);
				mask -= 1 << (x - 1);
			}
		}
	}

	StringTokenizer tokens() throws IOException
	{
		return new StringTokenizer(input.readLine());
	}

	String next(StringTokenizer st)
	{
		return st.nextToken();
	}

	int nextInt() throws IOException
	{
		return Integer.parseInt(input.readLine());
	}

	int nextInt(StringTokenizer st)
	{
		return Integer.parseInt(st.nextToken());
	}

	double nextDouble() throws IOException
	{
		return Double.parseDouble(input.readLine());
	}

	double nextDouble(StringTokenizer st)
	{
		return Double.parseDouble(st.nextToken());
	}

	void print(Object... o)
	{
		out.println(deepToString(o));
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = Integer.MAX_VALUE;
		int j = 0;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				if (j == 0) {
					ans = Math
							.min(ans, 2 * dist(0, i) + solve(mask | (1 << i)));
					j = i;
				} else
					ans = Math.min(ans, dist(0, i) + dist(i, j) + dist(j, 0)
							+ solve(mask | (1 << i) | (1 << j)));
			}
		return dp[mask] = ans;
	}

	static void prnt(int mask) {
		if (mask == (1 << n) - 1)
			return;
		int j = 0;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				if (j == 0) {
					j = i;
					if (dp[mask] == 2 * dist(0, i) + solve(mask | (1 << i))) {
						out.print(" " + i + " 0");
						prnt(mask | (1 << i));
						return;
					}
				} else if (dp[mask] == dist(0, i) + dist(i, j) + dist(j, 0)
						+ solve(mask | (1 << i) | (1 << j))) {
					out.print(" " + i + " " + j + " 0");
					prnt(mask | (1 << i) | (1 << j));
					return;
				}
			}
	}

	public static void main(String[] args) throws IOException {
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		out.print(0);
		prnt(1 << 0);
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter out = new PrintWriter(System.out);

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class MainC {

    private FastScanner in;
    private PrintWriter out;

    private int N;
    private Dist[] dists;
    private int countDists;
    private int[][] minLeft;// startsFrom, count

    private int[] minOrder;
    private int minOrderCount = 10000000;

    public void solve() throws IOException {
        int xb = in.nextInt();
        int yb = in.nextInt();
        N = in.nextInt();
        int[] x, y;
        boolean isOdd;
        if (N % 2 == 0) {
            x = new int[N];
            y = new int[N];
            isOdd = false;
        }
        else {
            x = new int[N + 1];
            y = new int[N + 1];
            isOdd = true;
        }
        for (int i = 0; i < N; i++) {
            x[i] = in.nextInt() - xb;
            y[i] = in.nextInt() - yb;
        }
        if (N % 2 == 1) {
            N++;
            x[N - 1] = 0;
            y[N - 1] = 0;
        }

        countDists = N * (N - 1) / 2;
        dists = new Dist[countDists];
        int c = 0;
        int commonSum = 0;
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                dists[c] = new Dist();
                dists[c].from = i;
                dists[c].to = j;
                dists[c].dist = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
                                * (y[i] - y[j]);
                dists[c].dist = Math.min(dists[c].dist, x[i] * x[i] + y[i]
                                * y[i] + x[j] * x[j] + y[j] * y[j]);
                c++;
            }
            commonSum += x[i] * x[i] + y[i] * y[i];
        }

        Arrays.sort(dists);

        minLeft = new int[countDists][N + 1];
        for (int i = 0; i < countDists; i++) {
            int sum = 0;
            for (int j = 1; j <= N; j++) {
                if (i + j - 1 < countDists) {
                    sum = sum + dists[i + j - 1].dist;
                    minLeft[i][j] = sum;
                }
                else {
                    minLeft[i][j] = 100000000;
                }
            }
        }

        order(0, new int[N], 0, 0);

        out.println(minOrderCount + commonSum);
        for (int i = 1; i <= N / 2; i++) {
            int first = -1;
            int second = -1;
            for (int j = 0; j < N; j++) {
                if (minOrder[j] == i) {
                    if (first == -1) {
                        first = j;
                    }
                    else {
                        second = j;
                    }
                }
            }

            if (isOdd && (first == N - 1 || second == N - 1)) {
                first++;
                second++;
                out.print("0 " + (first + second - N) + " ");
            }
            else if (x[first] * x[first] + y[first] * y[first] + x[second]
                            * x[second] + y[second] * y[second] < (x[first] - x[second])
                            * (x[first] - x[second])
                            + (y[first] - y[second])
                            * (y[first] - y[second])) {
                first++;
                second++;
                out.print("0 " + first + " 0 " + second + " ");
            }
            else {
                first++;
                second++;
                out.print("0 " + first + " " + second + " ");
            }
        }

        out.println("0");
    }

    private void order(int countOrdered, int[] order, int startsFrom, int sum) {
        if (countOrdered == N) {
            if (sum < minOrderCount) {
                minOrder = Arrays.copyOf(order, N);
                minOrderCount = sum;
            }
            return;
        }

        while (startsFrom < countDists) {
            if (order[dists[startsFrom].from] == 0
                            && order[dists[startsFrom].to] == 0) {
                if (minLeft[startsFrom][(N - countOrdered) / 2] + sum >= minOrderCount) {
                    break;
                }
                order[dists[startsFrom].from] = countOrdered / 2 + 1;
                order[dists[startsFrom].to] = countOrdered / 2 + 1;
                order(countOrdered + 2, order, startsFrom + 1, sum
                                + dists[startsFrom].dist);
                order[dists[startsFrom].from] = 0;
                order[dists[startsFrom].to] = 0;
            }
            startsFrom++;
        }
    }

    private class Dist implements Comparable<Dist> {

        int from;
        int to;
        int dist;

        @Override
        public int compareTo(Dist o) {
            if (dist < o.dist) {
                return -1;
            }
            if (dist == o.dist) {
                return 0;
            }
            return 1;
        }
    }

    public void run() {
        try {
            in = new FastScanner(System.in);
            out = new PrintWriter(System.out);
            solve();
            out.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

    public static void main(String[] arg) {
        new MainC().run();
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            int bestC = best[set ^ (1 << i)] + single[i];
            int prevC = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            int msc = set >> (i + 1);
            for (int j = i + 1, unoJ = 1 << (i + 1); msc != 0 && j < n; ++j, unoJ <<= 1, msc >>= 1)
                if ((msc & 1) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < bestC) {
                        bestC = cur;
                        prevC = unoI | unoJ;
                    }
                }
            best[set] = bestC;
            prev[set] = prevC;
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

import java.util.*;

public class Main {

    static Scanner cin = new Scanner(System.in);
    private int xs, ys, n;
    private int[] x, y;

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    class Item implements Comparable<Item> {

        int w, h, idx;

        Item(int w, int h, int idx) {
            this.w = w;
            this.h = h;
            this.idx = idx;
        }

        @Override
        public int compareTo(Item o) {
            if (this.w == o.w) {
                return this.h - o.h;
            }
            return this.w - o.w;
        }
    }

    private void run() throws Exception {
        xs = cin.nextInt();
        ys = cin.nextInt();
        n = cin.nextInt();
        x = new int[n + 1];
        y = new int[n + 1];
        for (int i = 0; i < n; i++) {
            x[i] = cin.nextInt();
            y[i] = cin.nextInt();
        }
        int[] res = new int[1 << n];
        Arrays.fill(res, Integer.MAX_VALUE);
        int[] ds = new int[n];
        for (int i = 0; i < n; i++) {
            ds[i] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys);
        }
        int[][] d = new int[n + 1][n + 1];
        int[] tr = new int[1 << n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                d[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
            }
        }
        //----------------------
        res[0] = 0;
        for (int i = 1; i < (1 << n); i++) {
            for (int j = 0; j < n; j++) {
                if (((i >> j) & 1) != 0) {
                    if (res[i - (1 << j)] + 2 * ds[j] < res[i]) {
                        res[i] = res[i - (1 << j)] + 2 * ds[j];
                        tr[i] = i - (1 << j);
                    }
                    for (int k = j + 1; k < n; k++) {
                        if (((i >> k) & 1) != 0) {
                            if (res[i - (1 << j) - (1 << k)] + ds[k] + ds[j] + d[k][j] < res[i]) {
                                res[i] = res[i - (1 << j) - (1 << k)] + ds[k] + ds[j] + d[k][j];
                                tr[i] = i - (1 << j) - (1 << k);
                            }
                        }
                    }
                    break;
                }
            }
        }
        System.out.println(res[(1 << n) - 1]);
        int now = (1 << n) - 1;
        while (now != 0) {
            System.out.print("0 ");
            int dif = now - tr[now];
            for (int i = 0; i < n && dif != 0; i++) {
                if (((dif >> i) & 1) != 0) {
                    System.out.print((i + 1) + " ");
                    dif -= (1 << i);
                }
            }
            now=tr[now];
        }
        System.out.print("0");
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        int[] best = new int[1 << n];
        int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            best[set] = best[set ^ (1 << i)] + single[i];
            prev[set] = i + 1;
            for (int j = i + 1; j < n; ++j)
                if ((set & (1 << j)) != 0) {
                    int cur = best[set ^ (1 << i) ^ (1 << j)] + pair[i][j];
                    if (cur < best[set]) {
                        best[set] = cur;
                        prev[set] = (i + 1) * 100 + (j + 1);
                    }
                }
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
            int what = prev[now];
            int wa = what % 100 - 1;
            int wb = what / 100 - 1;
            if (wa >= 0) {
                writer.print(" ");
                writer.print(wa + 1);
                now ^= 1 << wa;
            }
            if (wb >= 0) {
                writer.print(" ");
                writer.print(wb + 1);
                now ^= 1 << wb;
            }
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class CodeD
{
	static class Scanner
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

		public String nextLine()
		{
			try
			{
				return br.readLine();
			}
			catch(Exception e)
			{
				throw(new RuntimeException());
			}
		}

		public String next()
		{
			while(!st.hasMoreTokens())
			{
				String l = nextLine();
				if(l == null)
					return null;
				st = new StringTokenizer(l);
			}
			return st.nextToken();
		}

		public int nextInt()
		{
			return Integer.parseInt(next());
		}

		public long nextLong()
		{
			return Long.parseLong(next());
		}

		public double nextDouble()
		{
			return Double.parseDouble(next());
		}

		public int[] nextIntArray(int n)
		{
			int[] res = new int[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextInt();
			return res;
		}

		public long[] nextLongArray(int n)
		{
			long[] res = new long[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}

		public double[] nextDoubleArray(int n)
		{
			double[] res = new double[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}
		public void sortIntArray(int[] array)
		{
			Integer[] vals = new Integer[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortLongArray(long[] array)
		{
			Long[] vals = new Long[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortDoubleArray(double[] array)
		{
			Double[] vals = new Double[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}
	}
	static final Scanner sc;
	static final int n;
	static final int[][] distancias;
	static final int[] distancia;
	static final int[] dp;
	static final int[] dpNext;
	static final int X;
	static final int Y;

	static
	{
		sc = new Scanner();
		X = sc.nextInt();
		Y = sc.nextInt();
		n = sc.nextInt();
		distancias = new int[n][n];
		distancia = new int[n];
		dp = new int[1 << n];
		Arrays.fill(dp, -1);
		dpNext = new int[1 << n];
	}

	static int dp(int mascara)
	{
		if(dp[mascara] != -1)
			return dp[mascara];
		int highest = -1;
		for(int i = 0, tmp = mascara; tmp != 0; i++, tmp >>= 1)
		{
			if((tmp & 1) == 1)
				highest = i;
		}
		if(highest == -1)
			return 0;
		int nextMsc = mascara ^ (1 << highest);
		int costHighest = distancia[highest];
		int best = (costHighest << 1) + dp(nextMsc);
		int bestNext = nextMsc;
		for(int i = 0, tmp = nextMsc, iC = 1; tmp != 0; i++, tmp >>= 1, iC <<= 1)
		{
			if((tmp & 1) == 1)
			{
				int msc = nextMsc ^ iC;
				int possibleA = costHighest + distancias[highest][i] + distancia[i] + dp(msc);
				if(possibleA < best)
				{
					best = possibleA;
					bestNext = msc;
				}
			}
		}
		dpNext[mascara] = bestNext;
		return dp[mascara] = best;

	}
	public static void main(String[] args)
	{
		int[][] objetos = new int[n][2];
		for(int i = 0; i < n; i++)
		{
			objetos[i][0] = sc.nextInt();
			objetos[i][1] = sc.nextInt();
			distancia[i] = (X - objetos[i][0]) * (X - objetos[i][0]) + (Y - objetos[i][1]) * (Y - objetos[i][1]);
		}
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				distancias[i][j] = (objetos[i][0] - objetos[j][0]) * (objetos[i][0] - objetos[j][0]) + (objetos[i][1] - objetos[j][1]) * (objetos[i][1] - objetos[j][1]);
		int ans = dp((1 << n) - 1);
		System.out.println(ans);
		int current = (1 << n) - 1;
		while(current != 0)
		{
			int next = dpNext[current];
			int differents = next ^ current;
			System.out.print("0 ");
			for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
					System.out.print((i + 1) + " ");
			current = next;
		}
		System.out.println("0");
	}

}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class CodeD
{
	static class Scanner
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

		public String nextLine()
		{
			try
			{
				return br.readLine();
			}
			catch(Exception e)
			{
				throw(new RuntimeException());
			}
		}

		public String next()
		{
			while(!st.hasMoreTokens())
			{
				String l = nextLine();
				if(l == null)
					return null;
				st = new StringTokenizer(l);
			}
			return st.nextToken();
		}

		public int nextInt()
		{
			return Integer.parseInt(next());
		}

		public long nextLong()
		{
			return Long.parseLong(next());
		}

		public double nextDouble()
		{
			return Double.parseDouble(next());
		}

		public int[] nextIntArray(int n)
		{
			int[] res = new int[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextInt();
			return res;
		}

		public long[] nextLongArray(int n)
		{
			long[] res = new long[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}

		public double[] nextDoubleArray(int n)
		{
			double[] res = new double[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}
		public void sortIntArray(int[] array)
		{
			Integer[] vals = new Integer[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortLongArray(long[] array)
		{
			Long[] vals = new Long[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortDoubleArray(double[] array)
		{
			Double[] vals = new Double[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}
	}
	static final Scanner sc;
	static final int n;
	static final int[][] distancias;
	static final int[] distancia;
	static final int[] dp;
	static final int[] dpNext;
	static final int X;
	static final int Y;

	static
	{
		sc = new Scanner();
		X = sc.nextInt();
		Y = sc.nextInt();
		n = sc.nextInt();
		distancias = new int[n][n];
		distancia = new int[n];
		dp = new int[1 << n];
		Arrays.fill(dp, -1);
		dpNext = new int[1 << n];
	}

	static int dp(int mascara)
	{
		if(dp[mascara] != -1)
			return dp[mascara];
		int highest = -1;
		for(int i = 0, tmp = mascara; tmp != 0; i++, tmp >>= 1)
		{
			if((tmp & 1) == 1)
			{
				highest = i;
				break;
			}
		}
		if(highest == -1)
			return 0;
		int nextMsc = mascara ^ (1 << highest);
		int costHighest = distancia[highest];
		int best = (costHighest << 1) + dp(nextMsc);
		int bestNext = nextMsc;
		for(int i = 0, tmp = nextMsc, iC = 1; tmp != 0; i++, tmp >>= 1, iC <<= 1)
		{
			if((tmp & 1) == 1)
			{
				int msc = nextMsc ^ iC;
				int possibleA = costHighest + distancias[highest][i] + distancia[i] + dp(msc);
				if(possibleA < best)
				{
					best = possibleA;
					bestNext = msc;
				}
			}
		}
		dpNext[mascara] = bestNext;
		return dp[mascara] = best;

	}
	public static void main(String[] args)
	{
		int[][] objetos = new int[n][2];
		for(int i = 0; i < n; i++)
		{
			objetos[i][0] = sc.nextInt();
			objetos[i][1] = sc.nextInt();
			distancia[i] = (X - objetos[i][0]) * (X - objetos[i][0]) + (Y - objetos[i][1]) * (Y - objetos[i][1]);
		}
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				distancias[i][j] = (objetos[i][0] - objetos[j][0]) * (objetos[i][0] - objetos[j][0]) + (objetos[i][1] - objetos[j][1]) * (objetos[i][1] - objetos[j][1]);
		int ans = dp((1 << n) - 1);
		System.out.println(ans);
		int current = (1 << n) - 1;
		while(current != 0)
		{
			int next = dpNext[current];
			int differents = next ^ current;
			System.out.print("0 ");
			for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
					System.out.print((i + 1) + " ");
			current = next;
		}
		System.out.println("0");
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            int bestC = best[set ^ (1 << i)] + single[i];
            int prevC = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            for (int j = i + 1, unoJ = 1 << (i + 1); j < n; ++j, unoJ <<= 1)
                if ((set & unoJ) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < bestC) {
                        bestC = cur;
                        prevC = unoI | unoJ;
                    }
                }
            best[set] = bestC;
            prev[set] = prevC;
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class BetaRound8_C implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok;

    @Override
    public void run() {
        try {
            long startTime = System.currentTimeMillis();
            if (System.getProperty("ONLINE_JUDGE") != null) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader("input.txt"));
                out = new PrintWriter("output.txt");
            }
            tok = new StringTokenizer("");
            Locale.setDefault(Locale.US);
            solve();
            in.close();
            out.close();
            long endTime = System.currentTimeMillis();
            long totalMemory = Runtime.getRuntime().totalMemory();
            long freeMemory = Runtime.getRuntime().freeMemory();
            System.err.println("Time = " + (endTime - startTime) + " ms");
            System.err.println("Memory = " + ((totalMemory - freeMemory) / 1024) + " KB");
        } catch (Throwable e) {
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            tok = new StringTokenizer(in.readLine());
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }

    public static void main(String[] args) {
        new Thread(null, new BetaRound8_C(), "", 256 * 1024 * 1024).start();
    }

    // ------------------------------------------------------------------------------

    final int INF = 1000 * 1000 * 1000;

    int x0, y0;
    int n;
    int[] x, y;

    int t(int i, int j) {
        int dx = x[i] - x[j];
        int dy = y[i] - y[j];
        return dx * dx + dy * dy;
    }

    int t0(int i) {
        int dx = x[i] - x0;
        int dy = y[i] - y0;
        return dx * dx + dy * dy;
    }

    int[] dp;
    int[] p;

    void solve() throws IOException {
        x0 = readInt();
        y0 = readInt();
        n = readInt();
        x = new int[n];
        y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = readInt();
            y[i] = readInt();
        }
        dp = new int[1 << n];
        p = new int[1 << n];
        Arrays.fill(dp, INF);
        dp[(1 << n) - 1] = 0;
        get(0);
        out.println(dp[0]);
        printPath();
    }

    int get(int mask) {
        if (dp[mask] != INF) {
            return dp[mask];
        }
        int res = INF;
        for (int i = 0; i < n; i++) {
            if (((1 << i) & mask) == 0) { // порядок неважен, т.к. в i все равно идти, пойдем туда сразу
                int test = get(mask ^ (1 << i)) + 2 * t0(i);
                if (res > test) {
                    res = test;
                    p[mask] = mask ^ (1 << i);
                }
                for (int j = i + 1; j < n; j++) {
                    if (((1 << j) & mask) == 0) {
                        test = get(mask ^ (1 << i) ^ (1 << j)) + t0(i)
                                + t(i, j) + t0(j);
                        if (res > test) {
                            res = test;
                            p[mask] = mask ^ (1 << i) ^ (1 << j);
                        }
                    }
                }
                break;
            }
        }
        return dp[mask] = res;
    }

    void printPath() {
        ArrayList<Integer> ans = new ArrayList<Integer>();
        ans.add(0);
        int mask = 0;
        while (mask != (1 << n) - 1) {
            for (int i = 0; i < n; i++) {
                if (((mask ^ p[mask]) & (1 << i)) != 0) {
                    ans.add(i + 1);
                }
            }
            mask = p[mask];
            ans.add(0);
        }
        for (int x : ans) {
            out.print(x + " ");
        }
    }

}

import java.util.*;

public class C
{
   public static void main(String[] args)
   {
      new C(new Scanner(System.in));
   }

   vect[] vs;
   int N;
   int oo = 987654321;

   ArrayList<choice> cs;
   choice[][] cg;

   int MF;

   int[] memo;
   int[] next;

   int go(int m)
   {
      if (m == MF)
         return 0;
      if (memo[m] != -1)
         return memo[m];

      // Try a new place
      int res = oo;
      int nxt = -1;

      int i=0;
      for (i=0; i<N; i++)
      {
         if (((1<<i)&m) == 0)
            break;
      }

      for (int j=0; j<N; j++)
      {
         choice cc = cg[i][j];
         if ((m&cc.m) > 0)
            continue;

         int r2 = cc.cost+go(m|cc.m);
         if (r2 < res)
         {
            res = r2;
            nxt = cc.index;
         }
      }

      memo[m] = res;
      next[m] = nxt;
      return res;
   }

   public C(Scanner in)
   {
      vect vt = new vect(in.nextInt(), in.nextInt());
      N = in.nextInt();
      vs = new vect[N+1];
      vs[N] = vt;
      for (int i=0; i<N; i++)
         vs[i] = new vect(in.nextInt(), in.nextInt());

      // Precompute all choices and masks
      cs = new ArrayList<choice>();
      cg = new choice[N][N];
      for (int i=0; i<N; i++)
      {
         choice cc = new choice(cs.size(), 2*vs[i].dist(vt), 1<<i);
         cc.add(i);
         cs.add(cc);
         cg[i][i] = cc;
      }

      for (int i=0; i<N; i++)
      {
         for (int j=i+1; j<N; j++)
         {
            int dist = vs[i].dist(vt);
            dist += vs[i].dist(vs[j]);
            dist += vs[j].dist(vt);
            choice cc = new choice(cs.size(), dist, (1<<i)|(1<<j));
            cc.add(i); cc.add(j);
            cs.add(cc);
            cg[i][j] = cc;
            cg[j][i] = cc;
         }
      }

      MF = (1<<N)-1;
      next = new int[MF+1];
      memo = new int[MF+1];

      Arrays.fill(next, -1);
      Arrays.fill(memo, -1);

      int res = go(0);
      System.out.println(res);

      int m = 0;
      StringBuilder sb = new StringBuilder();
      while (m != -1)
      {
         //System.out.println(Integer.toBinaryString(m));
         sb.append(0);
         sb.append(' ');
         int i = next[m];
         if (i == -1)
            break;
         choice cc = cs.get(i);
         for (int j : cc.iv)
         {
            sb.append(f(j));
            sb.append(' ');
         }
         m = m|cc.m;
      }
      System.out.println(sb.toString().trim());
   }

   int f(int i)
   {
      if (i == N)
         return 0;
      return i+1;
   }
}

class choice
{
   int cost;
   int m;
   int index;
   ArrayList<Integer> iv;

   public choice(int ii, int c, int mm)
   {
      index = ii;
      cost = c;
      m = mm;
      iv = new ArrayList<Integer>(2);
   }

   void add(int i)
   {
      iv.add(i);
   }
}

class vect
{
   int x, y;

   public vect(int i, int j)
   {
      x=i; y=j;
   }

   int dist(vect rhs)
   {
      int xx = x-rhs.x;
      int yy = y-rhs.y;
      return xx*xx+yy*yy;
   }
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C8
{

	public static long mod = 1000000007;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);
	static int n;
	static int x,y;
	static int[] xx;
	static int[] yy;
	static int[] dist;
	static int[][] g;
	static int[] dp;
	public static int square(int x)
	{
		return abs(x*x);
	}
	static class Pair
	{
		int x,y;
		Pair(int x,int y)
		{
			this.x=x;
			this.y=y;
		}
	}
	public static void main(String[] args)
	{

		x=in.nextInt();
		y=in.nextInt();
		n=in.nextInt();
		xx=new int[n];
		yy=new int[n];
		dp=new int[1<<n];
		for(int i=0;i<n;i++)
		{
			xx[i]=in.nextInt();
			yy[i]=in.nextInt();
		}
		dist=new int[n];
		g=new int[n][n];
		for(int i=0;i<n;i++)
		{
			dist[i]=square(abs(xx[i]-x))+square(abs(yy[i]-y));
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				g[i][j]=square(abs(xx[i]-xx[j]))+square(yy[i]-yy[j]);
				//System.out.println("i "+i+" j "+j+" "+g[i][j]);
			}
		}
		Arrays.fill(dp, Integer.MAX_VALUE/2);
		dp[0]=0;
		for(int i=0;i<(1<<n);i++)
		{
			//we have to find dp[i]
			for(int j=0;j<n;j++)
			{
				if((i&(1<<j))>0)   //not visited j
				continue;
				dp[i|(1<<j)]=min(dp[i|(1<<j)], dp[i]+2*dist[j]);
				for(int k=j+1;k<n;k++)
				{
					if((i&(1<<k))>0)
						continue;
					dp[i|(1<<j)|(1<<k)]=min(dp[i|(1<<j)|(1<<k)], dp[i]+dist[j]+dist[k]+g[j][k]);
				}
				break;
			}
		}
		out.println(dp[(1<<n)-1]);
		Stack<Integer> stack=new Stack<>();
		stack.push(0);
		int i=(1<<n)-1;
		while(i>0)
		{
			boolean tocontinue=false;
			for(int a=0;a<n;a++)
			{
				if((i&(1<<a))==0)
					continue;
				if(dp[i]==(dp[i^(1<<a)]+2*dist[a]))
				{
					stack.push(a+1);
					stack.push(0);
					i-=(1<<a);
					tocontinue=true;
				}
				if(tocontinue)
					continue;
				for(int b=a+1;b<n;b++)
				{
					if((i & (1<<b)) == 0) continue;
					if(dp[i]==(dp[i^(1<<a)^(1<<b)]+dist[a]+dist[b]+g[a][b]))
					{
						i-=(1<<a);
						i-=(1<<b);
						stack.push(a+1);
						stack.push(b+1);
						stack.push(0);
						tocontinue=true;
					}
					if(tocontinue)
						break;
				}
				if(tocontinue)
					break;
			}

		}
		for(int ii : stack)
			out.print(ii+" ");
		out.close();

	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

		public int read()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = System.in.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

	static class InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream inputstream)
		{
			reader = new BufferedReader(new InputStreamReader(inputstream));
			tokenizer = null;
		}

		public String nextLine()
		{
			String fullLine = null;
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					fullLine = reader.readLine();
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
				return fullLine;
			}
			return fullLine;
		}

		public String next()
		{
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public long nextLong()
		{
			return Long.parseLong(next());
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

		public int nextInt()
		{
			return Integer.parseInt(next());
		}
	}

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
		}

		public OutputWriter(Writer writer)
		{
			this.writer = new PrintWriter(writer);
		}

		public void print(Object... objects)
		{
			for (int i = 0; i < objects.length; i++)
			{
				if (i != 0)
					writer.print(' ');
				writer.print(objects[i]);
			}
		}

		public void println(Object... objects)
		{
			print(objects);
			writer.println();
		}

		public void close()
		{
			writer.close();
		}

		public void flush()
		{
			writer.flush();
		}
	}

}

import java.util.*;
public class c8 {
    static int n;
    static int[] ds;
    static int[][] g;
public static void main(String[] args)
{
    Scanner input = new Scanner(System.in);
    int x = input.nextInt(), y = input.nextInt();
    int n = input.nextInt();
    int[] xs = new int[n], ys = new int[n];
    for(int i = 0; i<n; i++)
    {
        xs[i] = input.nextInt();
        ys[i] = input.nextInt();
    }
    ds = new int[n];
    g = new int[n][n];
    for(int i = 0; i<n; i++)
    {
        ds[i] = (x - xs[i])  *  (x - xs[i]) + (y - ys[i]) * (y - ys[i]);
        for(int j = 0; j<n; j++)
        {
            g[i][j] = (xs[i] - xs[j]) * (xs[i] - xs[j]) + (ys[i] - ys[j]) * (ys[i] - ys[j]);
        }
    }
    int[] dp = new int[1<<n];
    Arrays.fill(dp, 987654321);
    dp[0] = 0;
    for(int i = 0; i<(1<<n); i++)
    {
        if(dp[i] == 987654321) continue;
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) > 0) continue;
            dp[i | (1<<a)] = Math.min(dp[i | (1<<a)], dp[i] + 2*ds[a]);
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) > 0) continue;
                dp[i | (1<<a) | (1<<b)] = Math.min(dp[i | (1<<a) | (1<<b)], dp[i] + ds[a] + ds[b] + g[a][b]);
            }
            break;
        }
    }
    Stack<Integer> stk = new Stack<Integer>();
    stk.add(0);
    int i = (1<<n) - 1;
    //System.out.println(Arrays.toString(dp));

    trace:
    while(i > 0)
    {
        //System.out.println(i);
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) == 0) continue;
            if( dp[i] == dp[i - (1<<a)] + 2*ds[a])
            {
                stk.add(a+1);
                stk.add(0);
                i -= (1<<a);
                continue trace;
            }
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) == 0) continue;
                if(dp[i] == dp[i - (1<<a) - (1<<b)] + ds[a] + ds[b] + g[a][b])
                {
                    stk.add(a+1);
                    stk.add(b+1);
                    stk.add(0);
                    i -= (1<<a) + (1<<b);
                    continue trace;
                }
            }
            //break;
        }
    }
    System.out.println(dp[(1<<n) - 1]);
    while(!stk.isEmpty()) System.out.print(stk.pop()+" ");
}
}

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main implements Runnable {

    // ////////////////////////////////////////////////////////////////////
    // Solution

    private int n;
    private int nn;
    private int[][] D;
    private int[] dp;
    private int[] prev;

    private void solve() throws Throwable {
        int xs = nextInt(), ys = nextInt();
        n = nextInt();
        int[][] pts = new int[n][2];
        for (int i = 0; i < n; i++) {
            pts[i][0] = nextInt();
            pts[i][1] = nextInt();
        }
        D = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    D[i][i] = 2 * (sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys));
                } else {
                    D[i][j] = sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys)
                            + sqr(pts[i][0] - pts[j][0])
                            + sqr(pts[i][1] - pts[j][1]) + sqr(pts[j][0] - xs)
                            + sqr(pts[j][1] - ys);
                }
            }
        }
        nn = 1 << n;
        dp = new int[nn];
        prev = new int[nn];
        Arrays.fill(dp, -1);
        Arrays.fill(prev, -1);
        dp[0] = 0;
        Dp(nn - 1);
        pw.println(dp[nn - 1]);
        pw.print(0);
        for (int p = nn - 1; p != -1 && prev[p] != -1; p = prev[p]) {
            int vv = p ^ prev[p];
            for (int j = 0; j < n; j++) {
                int jj = 1 << j;
                if ((vv & jj) == 0) continue;
                pw.print(' ');
                pw.print(j + 1);
            }
            pw.print(" 0");
        }
        pw.println();
    }

    private int Dp(int i) {
        if (dp[i] != -1) return dp[i];
        int ans = 107374182, p = -1;
        int j1 = 1, pos1 = 0;
        for (; pos1 < n && j1 < nn; j1 *= 2, pos1++) {
            if ((i & j1) == 0) continue;
            int a = D[pos1][pos1] + Dp(i ^ j1);
            if (a < ans) {
                ans = a;
                p = i ^ j1;
            }
            int j2 = j1 * 2, pos2 = pos1 + 1;
            for (; pos2 < n && j2 < nn; j2 *= 2, pos2++) {
                if ((i & j2) == 0) continue;
                a = D[pos1][pos2] + Dp(i ^ (j1 | j2));
                if (a < ans) {
                    ans = a;
                    p = i ^ (j1 | j2);
                }
            }
            break;
        }
        dp[i] = ans;
        prev[i] = p;
        return ans;
    }

    private int sqr(int i) {
        return i * i;
    }

    // ////////////////////////////////////////////////////////////////////
    // Utility functions

    PrintWriter pw;
    BufferedReader in;
    StringTokenizer st;

    void initStreams() throws FileNotFoundException {
        //System.setIn(new FileInputStream("1"));
        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
    }

    String nextString() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws NumberFormatException, IOException {
        return Integer.parseInt(nextString());
    }

    long nextLong() throws NumberFormatException, IOException {
        return Long.parseLong(nextString());
    }

    double nextDouble() throws NumberFormatException, IOException {
        return Double.parseDouble(nextString());
    }

    static Throwable sError;

    public static void main(String[] args) throws Throwable {
//      Thread t = new Thread(null, new Main(), "1", 1 << 27);
//      t.start();
//      t.join();
        new Main().run();
        if (sError instanceof OutOfMemoryError) {
            throw sError;
        }
//      if (sError != null) {
//          throw sError;
//      }
    }

    public void run() {
        try {
            initStreams();
            solve();
        } catch (Throwable e) {
            sError = e;
        } finally {
            if (pw != null)
                pw.close();
        }
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.io.InputStream;
/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int INF = 1000 * 1000 * 1000;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int x0 = in.readInt();
            int y0 = in.readInt();
            int n = in.readInt();
            int[] xs = new int[n + 1], ys = new int[n + 1];
            xs[0] = x0;
            ys[0] = y0;
            for (int i = 1; i <= n; i++) {
                xs[i] = in.readInt();
                ys[i] = in.readInt();
            }
            int[] one = new int[n];
            for (int i = 0; i < n; i++) one[i] = dist(0, i + 1, xs, ys) * 2;
            int[][] two = new int[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    two[i][j] = dist(0, i + 1, xs, ys) + dist(0, j + 1, xs, ys) + dist(i + 1, j + 1, xs, ys);
                }
            }
            int[] dp = new int[(1 << n)];
            Arrays.fill(dp, INF);
            dp[0] = 0;
            int[] prev = new int[(1 << n)];
            for (int mask = 0; mask < (1 << n); mask++) {
                for (int i = 0; i < n; i++) {
                    if (((mask >> i) & 1) != 0) continue;
                    ;
                    int nmask = mask | (1 << i);
                    int cost = one[i] + dp[mask];
                    if (cost < dp[nmask]) {
                        dp[nmask] = cost;
                        prev[nmask] = i;
                    }
                    for (int j = i + 1; j < n; j++) {
                        if (((mask >> j) & 1) != 0) continue;
                        int nnmask = nmask | (1 << j);
                        cost = two[i][j] + dp[mask];
                        if (cost < dp[nnmask]) {
                            dp[nnmask] = cost;
                            prev[nnmask] = n + i * n + j;
                        }
                    }
                    break;
                }
            }
            int mask = (1 << n) - 1;
            out.printLine(dp[mask]);
            ArrayList<Integer> res = new ArrayList<>();
            res.add(0);
            while (mask > 0) {
                if (prev[mask] < n) {
                    res.add(prev[mask] + 1);
                    mask &= ~(1 << prev[mask]);
                } else {
                    int ii = (prev[mask] - n) / n;
                    int jj = (prev[mask] - n) % n;
                    int i = Math.max(ii, jj);
                    int j = Math.min(ii, jj);
                    res.add(i + 1);
                    res.add(j + 1);
                    mask &= ~(1 << i);
                    mask &= ~(1 << j);
                }
                res.add(0);
            }
            Collections.reverse(res);
            for (int val : res) out.print(val + " ");
            out.printLine();
        }

        int dist(int i, int j, int[] xs, int[] ys) {
            return (xs[i] - xs[j]) * (xs[i] - xs[j]) + (ys[i] - ys[j]) * (ys[i] - ys[j]);
        }
    }
    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }
    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine() {
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main implements Runnable {

    // ////////////////////////////////////////////////////
    // Solution

    private int n;
    private int nn;
    private int[][] D;
    private int[] dp;
    private int[] prev;

    private void solve() throws Throwable {
        int xs = nextInt(), ys = nextInt();
        n = nextInt();
        int[][] pts = new int[n][2];
        for (int i = 0; i < n; i++) {
            pts[i][0] = nextInt();
            pts[i][1] = nextInt();
        }
        D = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    D[i][i] = 2 * (sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys));
                } else {
                    D[i][j] = sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys)
                            + sqr(pts[i][0] - pts[j][0])
                            + sqr(pts[i][1] - pts[j][1]) + sqr(pts[j][0] - xs)
                            + sqr(pts[j][1] - ys);
                }
            }
        }
        nn = 1 << n;
        dp = new int[nn];
        prev = new int[nn];
        Arrays.fill(dp, -1);
        Arrays.fill(prev, -1);
        dp[0] = 0;
        Dp(nn - 1);
        pw.println(dp[nn - 1]);
        pw.print(0);
        for (int p = nn - 1; p != -1 && prev[p] != -1; p = prev[p]) {
            int vv = p ^ prev[p];
            for (int j = 0; j < n; j++) {
                int jj = 1 << j;
                if ((vv & jj) == 0)
                    continue;
                pw.print(' ');
                pw.print(j + 1);
            }
            pw.print(" 0");
        }
        pw.println();
    }

    private int Dp(int i) {
        if (dp[i] != -1)
            return dp[i];
        int ans = 107374182, p = -1;
        int j1 = 1, pos1 = 0;
        for (; pos1 < n && j1 < nn; j1 *= 2, pos1++) {
            if ((i & j1) == 0)
                continue;
            int a = D[pos1][pos1] + Dp(i ^ j1);
            if (a < ans) {
                ans = a;
                p = i ^ j1;
            }
            int j2 = j1 * 2, pos2 = pos1 + 1;
            for (; pos2 < n && j2 < nn; j2 *= 2, pos2++) {
                if ((i & j2) == 0)
                    continue;
                a = D[pos1][pos2] + Dp(i ^ (j1 | j2));
                if (a < ans) {
                    ans = a;
                    p = i ^ (j1 | j2);
                }
            }
            break;
        }
        dp[i] = ans;
        prev[i] = p;
        return ans;
    }

    private int sqr(int i) {
        return i * i;
    }

    // ////////////////////////////////////////////////////
    // Utility functions

    private void initstreams() throws Throwable {
        //System.setIn(new FileInputStream("1"));
        in = new BufferedReader(new InputStreamReader(System.in, "ISO-8859-1"));
        pw = new PrintWriter(System.out);
    }

    BufferedReader in;
    PrintWriter pw;
    StringTokenizer st;

    String nextString() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws NumberFormatException, IOException {
        return Integer.parseInt(nextString());
    }

    long nextLong() throws NumberFormatException, IOException {
        return Long.parseLong(nextString());
    }

    double nextDouble() throws NumberFormatException, IOException {
        return Double.parseDouble(nextString());
    }

    @Override
    public void run() {
        try {
            initstreams();
            solve();
        } catch (Throwable e) {
            sError = e;
        } finally {
            if (pw != null)
                pw.close();
        }
    }

    private static Throwable sError;

    public static void main(String[] args) throws Throwable {
        Thread t = new Thread(new Main());
        t.start();
        t.join();
        if (sError != null)
            throw sError;
    }
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.flush();
		out.close();
	}
}

class Pair implements Comparable<Pair> {
	int first;
	int second;

	Pair(int first, int second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public int compareTo(Pair e) {
		return Long.compare(second, e.second);

	}
}

class TaskB {
	int INF = (int) 1e9 + 7;
	int MAX_N = (int) 1e5 + 5;
	long mod = (long) 1e8;

	void solve(int testNumber, InputReader in, PrintWriter pw) {
		int x0 = in.nextInt();
		int y0 = in.nextInt();
		int n = in.nextInt();
		int p[][] = new int[n + 1][];
		p[0] = new int[] { x0, y0 };
		for (int i = 1; i <= n; i++) {
			p[i] = new int[] { in.nextInt(), in.nextInt() };
		}
		int dp[] = new int[1 << n];
		// dp[mask] stores the minimum cost to pickup mask items
		int prev[] = new int[1 << n];
		int two[][] = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				two[i][j] = dist(p[i + 1], p[j + 1]) + dist(p[i + 1], p[0]) + dist(p[j + 1], p[0]);
//				pw.println(i + " " + j + " " + two[i][j]);
			}
		}
		Arrays.fill(dp, INF);
		dp[0] = 0;
		for (int i = 0; i < (1 << n); i++) {
			for (int j = 0; j < n; j++) {
				if (((i >> j) & 1) != 0) {
					continue;
				}
				int mask = i | (1 << j);
				int cost = dp[i] + two[j][j];

				if (cost < dp[mask]) {
					dp[mask] = cost;
					prev[mask] = j;
				}
				for (int k = j + 1; k < n; k++) {
					if (((mask >> k) & 1) != 0) {
						continue;
					}
					int nmask = mask | (1 << k);
					int ncost = dp[i] + two[j][k];
					if (ncost < dp[nmask]) {
						dp[nmask] = ncost;
						prev[nmask] = n + n * j + k;
						// trick to store the two pairs
					}
				}
				break;
			}
		}
		int temp = (1 << n) - 1;
		ArrayList<Integer> ans = new ArrayList<>();
		pw.println(dp[temp]);
		ans.add(0);
		while (temp > 0) {
			int mov = prev[temp];
			if (mov < n) {
				int rem = (1 << prev[temp]);
				temp ^= rem;
				ans.add(mov + 1);
			} else {
				int first = prev[temp] / n - 1;
				int second = prev[temp] % n;
				int rem = (1 << first);
				int rem2 = (1 << second);
				temp ^= rem;
				temp ^= rem2;
				ans.add(first + 1);
				ans.add(second + 1);
			}
			ans.add(0);
		}
		Collections.reverse(ans);
		for (int x : ans) {
			pw.print(x + " ");
		}
	}

	int dist(int[] x, int[] y) {
		return (x[0] - y[0]) * (x[0] - y[0]) + (x[1] - y[1]) * (x[1] - y[1]);

	}

	long gcd(long a, long b) {
		if (b == 0) {
			return a;
		} else {
			return gcd(b, a % b);
		}
	}

	int[] shrink(int a[]) {
		int n = a.length;
		long b[] = new long[n];
		for (int i = 0; i < n; i++) {
			b[i] = ((long) (a[i] << 32)) | i;
		}
		Arrays.sort(b);
		int ret[] = new int[n];
		int p = 0;
		for (int i = 0; i < n; i++) {
			if (i > 0 && (b[i] ^ b[i - 1]) >> 32 != 0) {
				p++;
			}
			ret[(int) b[i]] = p;
		}
		return ret;
	}

	int sum(int ft[], int i) {
		int sum = 0;
		for (int j = i; j >= 1; j -= (j & -j)) {
			sum += ft[j];
//			System.out.println(sum);
		}
		return sum;
	}

	void add(int ft[], int i, int x) {
		for (int j = i; j < ft.length; j += (j & -j)) {
//			System.out.println(j);
			ft[j] += x;
		}
	}

	boolean isValid(int i, int j, char arr[][]) {

		if (i >= arr[0].length || j >= arr[0].length) {
			return false;
		}
		if (arr[i][j] == '*') {
			return false;
		}
		return true;
	}

	long pow(long m, long k) {
		long prod = 1;
		for (int i = 0; i < k; i++) {
			prod = (prod * m) % INF;
		}
		return prod % INF;
	}

//	int sum(int k) {
//		int sum=0;
//		for(int i=k;i>=1;i) {
//			sum+=ft[k];
//		}
//	}

	long fib(int N) {
		long fib[] = new long[N + 1];
		fib[0] = 1;
		fib[1] = 1;
		for (int i = 2; i <= N; i++) {
			fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
		}
		return fib[N] % mod;
	}

	long sum(int i, int j, long arr[]) {
		long sum = 0;
		for (int k = i; k <= j; k++) {
			sum += arr[k];
		}
		return sum;
	}

	int __gcd(int a, int b) {
		if (b == 0)
			return a;
		return __gcd(b, a % b);

	}

	public int isPow(long num) {
		int count = 0;
		while (num > 0) {
			num /= 2;
			count++;
		}
		return count;
	}
}

class InputReader {
	BufferedReader br;
	StringTokenizer st;

	public InputReader(InputStream in) {
		br = new BufferedReader(new InputStreamReader(in));
		st = null;
	}

	public String next() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return st.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}

import java.io.*;
import java.util.*;

public class A558 {
  static BufferedReader in = null;
  static PrintWriter out = null;
  static StringTokenizer st = new StringTokenizer("");

  public static void main(String[] args) {
    try {
      in = new BufferedReader(new InputStreamReader(System.in));
      out = new PrintWriter(System.out);
      solve();
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static String readString() {
    while (!st.hasMoreTokens()) {
      try {
        st = new StringTokenizer(in.readLine(), " \n\r\t:");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return st.nextToken();
  }

  public static int readInt() {
    return Integer.parseInt(readString());
  }

  public static long readLong() {
    return Long.parseLong(readString());
  }

  private static int MAX_VALUE = Integer.MAX_VALUE - 10000000;
  private static int[] dp;
  private static int[] parents;
  private static int[] powers;
  private static int[] x;
  private static int[] y;
  private static int[][] dist;
  private static int[] distFrom0;

  private static void solve() throws IOException {
    int x0 = readInt();
    int y0 = readInt();
    int n = readInt();
    long time = System.currentTimeMillis();
    x = new int[n];
    y = new int[n];
    for (int i = 0; i < n; i++) {
      x[i] = readInt() - x0;
      y[i] = readInt() - y0;
    }
    dist = new int[n][n];
    distFrom0 = new int[n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        dist[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
      }
    }
    for (int i = 0; i < n; i++) {
      distFrom0[i] = x[i] * x[i] + y[i] * y[i];
    }
    powers = new int[n + 1];
    powers[0] = 1;
    for (int i = 1; i < n + 1; i++) {
      powers[i] = powers[i - 1] * 2;
    }
    int maxMask = 1 << n;
    dp = new int[maxMask];
    parents = new int[maxMask];
    Arrays.fill(dp, MAX_VALUE);
    dp[0] = 0;
    for (int i = 0; i < maxMask; i++) {
      if (dp[i] != MAX_VALUE) {
        int curMask = i;
        int notUsed = 0;
        for (int j = 0; j < n; j++) {
          if ((curMask & powers[j]) == 0) {
            notUsed = j;
            break;
          }
        }
        int mask = curMask | powers[notUsed];
        for (int j = notUsed; j < n; j++) {
          if ((powers[j] & curMask) == 0 || j == notUsed) {
            int nextMask = mask | powers[j];
            int minDist = dp[curMask] + distFrom0[notUsed] + dist[notUsed][j] + distFrom0[j];
            if (dp[nextMask] > minDist) {
              dp[nextMask] = minDist;
              parents[nextMask] = curMask;
            }
          }
        }
      }
    }
   // System.err.println(((System.currentTimeMillis() - time)));
    // brute(n, 0)
    maxMask--;
    out.println(dp[maxMask]);
    while (maxMask != 0) {
      out.print("0 ");
      int[] diffBits = getBits(n, maxMask, parents[maxMask]);
      for (int i = 1; i <= diffBits[0]; i++) {
        out.print(diffBits[i] + 1 + " ");
      }
      maxMask = parents[maxMask];
    }
    out.print(0);
    //System.err.println((System.currentTimeMillis() - time));
  }

  private static boolean hasBit(int x, int index) {
    return (powers[index] & x) != 0;
  }

  private static int setBit(int x, int index) {
    return (x | powers[index]);
  }

  private static int getDist(int xFrom, int yFrom, int xTo, int yTo) {
    return (xTo - xFrom) * (xTo - xFrom) + (yTo - yFrom) * (yTo - yFrom);
  }

  private static int[] getBits(int n, int nextMask, int curMask) {
    int[] res = new int[3];
    for (int i = 0; i < n; i++) {
      if (hasBit(nextMask, i) ^ hasBit(curMask, i)) {
        res[++res[0]] = i;
      }
    }
    return res;
  }

  private static void brute(int n, int mask) {
    List<Integer> listNotTaken = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      if (!hasBit(mask, i)) {
        listNotTaken.add(i);
      }
    }
    for (int first : listNotTaken) {
      int temp = setBit(mask, first);
      for (int second : listNotTaken) {
        int nextMask = setBit(temp, second);
        int minDist = dp[mask] + getDist(0, 0, x[first], y[first]) + getDist(x[first], y[first], x[second], y[second]) + getDist(x[second], y[second], 0, 0);
        if (dp[nextMask] > minDist) {
          dp[nextMask] = minDist;
          parents[nextMask] = mask;
          brute(n, nextMask);
        }
      }
    }
  }

}

import java.io.*;

public class MainClass
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s = br.readLine();
		int si = s.indexOf(' ', 0);
		int x = Integer.parseInt(s.substring(0, si));
		int y = Integer.parseInt(s.substring(si + 1));
		int n = Integer.parseInt(br.readLine());
		int[] xx = new int[n + 1];
		int[] yy = new int[n + 1];
		for (int i = 0; i < n; i++) {
			s = br.readLine();
			si = s.indexOf(' ', 0);
			xx[i] = Integer.parseInt(s.substring(0, si));
			yy[i] = Integer.parseInt(s.substring(si + 1));
		}
		xx[n] = x;
		yy[n] = y;
		int[][] dd = new int[n + 1][n + 1];
		for (int i = 0; i <= n; i++)
			for (int j = i + 1; j <= n; j++) {
				int dx = xx[i] - xx[j];
				int dy = yy[i] - yy[j];
				dd[i][j] = dx * dx + dy * dy;
			}
		int[] aa = new int[1 << n];
		int[] bb = new int[1 << n];
		for (int k = 1; k < 1 << n; k++) {
			int a = -1;
			for (int b = 0; b < n; b++)
				if ((k & 1 << b) > 0) {
					a = b;
					break;
				}
			int l = k ^ 1 << a;
			int d = dd[a][n] + dd[a][n];
			aa[k] = aa[l] + d;
			bb[k] = l;
			for (int b = a + 1; b < n; b++)
				if ((k & 1 << b) > 0) {
					l = k ^ 1 << a ^ 1 << b;
					d = dd[a][n] + dd[b][n] + dd[a][b];
					if (aa[l] + d < aa[k]) {
						aa[k] = aa[l] + d;
						bb[k] = l;
					}
				}
		}
		int k = (1 << n) - 1;
		System.out.println(aa[k]);
		StringBuilder sb = new StringBuilder();
		sb.append(0);
		while (k != 0) {
			int l = bb[k];
			int m = k ^ l;
			for (int b = 0; b < n; b++)
				if ((m & 1 << b) > 0)
					sb.append(' ').append(b + 1);
			sb.append(' ').append(0);
			k = l;
		}
		System.out.println(sb);
	}
}

import java.awt.*;
import java.io.*;
import java.util.*;

public class Abc {
    static Point p[];
    static int dp[];
    static int n;
    static Point s;
    static int ans[];
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        s = new Point(sc.nextInt(), sc.nextInt());
        n = sc.nextInt();
        p = new Point[n];
        for (int i = 0; i < n; i++) {
            p[i] = new Point(sc.nextInt(), sc.nextInt());
        }
        dp = new int[1 << n];
        ans = new int[1 << n];
        Arrays.fill(dp, -1);
        System.out.println(dp(0));
        int i = 0;
        StringBuilder sb = new StringBuilder();
        sb.append(0 + " ");
        while (i != (1 << n) - 1) {
            int x = ans[i];
            for (int j = 0; j < n; j++) {
                if ((x & (1 << j)) != 0) {
                    sb.append((j + 1) + " ");
                }
            }
            i = (i | x);
            sb.append(0 + " ");
        }
        System.out.println(sb);
    }

    static int dp(int mask) {
        if (mask == (1 << n) - 1) return 0;
        if (dp[mask] != -1) return dp[mask];
        int i = -1, j = -1;
        for (int k = 0; k < n; k++) {
            if ((mask & (1 << k)) == 0) {
                i=k;
                break;
            }
        }
        int a = dp(mask | (1 << i)) + 2 * dist(p[i], s);
        ans[mask] = (1 << i);
        for (j=i+1;j<n;j++){
            if ((mask&(1<<j))==0) {
                int a3 = dp(mask + (1 << i) + (1 << j)) + dist(p[i], p[j]) + dist(s, p[i]) + dist(p[j], s);
                if (a > a3) {
                    a = a3;
                    ans[mask] = (1 << i) + (1 << j);
                }
            }
        }
        return dp[mask] = a;
    }

    static int dist(Point p1, Point p2) {
        return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	static int[][] pos;
	static int[] dp;
	static int[] nextstate;
	static int[][] dist;
	static int r;
	static int v;

	static void print(int mask) {
		if (mask < v) {
			int c = 0;
			int x = mask ^ nextstate[mask];
			for (int i = 0; i < dist.length - 1; i++) {
				if((x & (1<<i))>0) {
					System.out.print(i+1 + " ");
					c++;
				}
			}
			System.out.print("0 ");
			print(nextstate[mask]);
		}
	}

	static int distace(int x1, int x2, int y1, int y2) {
		return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
	}

	static int solve(int mask) {
		if (mask == v) {
			nextstate[mask] = r;

			return 0;
		}
		if (nextstate[mask] != 0) {
			return dp[mask];
		}

		dp[mask] = (int) 1e9;
		for (int i = 1; i < pos.length; i++) {
			int u = (1 << (i - 1));
			int z = mask | u;
			if ((mask & u) == 0) {
				int x = 2 * dist[i][0] + solve(z);
				if (dp[mask] > x) {
					dp[mask] = x;
					nextstate[mask] = z;
				}

				for (int j = 1; j < pos.length; j++) {
					int m = (1 << j - 1);
					int y = z | m;
					if ((z & m) == 0) {
						x = dist[i][0] + solve(y) + dist[i][j] + dist[j][0];

						if (dp[mask] > x) {
							dp[mask] = x;
							nextstate[mask]= y;
						}

					}
				}
				break;
			}
		}
		return dp[mask];
	}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(), y = in.nextInt();
		int n = in.nextInt();
		r = 1 << n;
		v = r - 1;
		dp = new int[r];
		nextstate = new int[r];
		pos = new int[n + 1][2];
		pos[0][0] = x;
		pos[0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos[i][0] = in.nextInt();
			pos[i][1] = in.nextInt();
		}
		dist = new int[n + 1][n + 1];
		for (int i = 0; i < dist.length; i++) {
			for (int j = i + 1; j < dist.length; j++) {
				dist[i][j] = dist[j][i] = distace(pos[i][0], pos[j][0], pos[i][1], pos[j][1]);
			}
		}

		System.out.println(solve(0));
		System.out.print("0 ");
		print(0);
	}

}

class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

	static int n, memo[], dS[], dd[][];

	static int dp(int idx, int msk)
	{
		if(msk == (1 << n) - 1)
			return 0;
		if(memo[msk] != -1)
			return memo[msk];
		while((msk & 1 << idx) != 0)
			++idx;
		int ret = dS[idx] * 2 + dp(idx + 1, msk | 1 << idx);
		for(int i = 0; i < n; ++i)
			if((msk & 1 << i) == 0)
				ret = Math.min(ret, dS[i] + dS[idx] + dd[i][idx] + dp(idx + 1, msk | 1 << i | 1 << idx));
		return memo[msk] = ret;
	}

	static StringBuilder sb = new StringBuilder("0 ");

	static void print(int idx, int msk)
	{
		if(msk == (1 << n) - 1)
			return;
		int opt = dp(idx, msk);
		while((msk & 1 << idx) != 0)
			++idx;
		if(dS[idx] * 2 + dp(idx + 1, msk | 1 << idx) == opt)
		{
			sb.append((idx + 1) + " 0 ");
			print(idx + 1, msk | 1 << idx);
			return;
		}
		for(int i = 0; i < n; ++i)
			if((msk & 1 << i) == 0)
				if(opt == dS[i] + dS[idx] + dd[i][idx] + dp(idx + 1, msk | 1 << i | 1 << idx))
				{
					sb.append((idx + 1) + " " + (i + 1) + " 0 ");
					print(idx + 1, msk | 1 << i | 1 << idx);
					return;
				}
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Point s = new Point(sc.nextInt(), sc.nextInt());
		n = sc.nextInt();
		Point[] a = new Point[n];
		for(int i = 0; i < n; ++i)
			a[i] = new Point(sc.nextInt(), sc.nextInt());
		dS = new int[n];
		dd = new int[n][n];
		for(int i = 0; i < n; ++i)
		{
			dS[i] = dist2(s, a[i]);
			for(int j = 0; j < n; ++j)
				dd[i][j] = dist2(a[i], a[j]);
		}

		memo = new int[1 << n];
		Arrays.fill(memo, -1);
		out.println(dp(0, 0));
		print(0, 0);
		out.println(sb);
		out.flush();
		out.close();
	}

	static int dist2(Point a, Point b) { return sq(a.x - b.x) + sq(a.y - b.y); }

	static int sq(int x) { return x * x; }

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * Created by James on 1/29/2015.
 */
public class Driver {
    private static int [][] distances, parents;
    private static int [] distance, parent;
    private static String [][] longNames;
    private static String [] shortNames, answers;
    private static int N;

    public static void main(String [] args) throws IOException {
        BufferedReader scanner = new BufferedReader(new InputStreamReader(System.in));

        String [] pieces = scanner.readLine().split("\\s+");

        //totally had to steal the vast majority of this from http://codeforces.com/contest/8/submission/9745593

        Point origin = new Point(Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1]));

        N = Integer.parseInt(scanner.readLine());

        Point [] points = new Point[N + 1];
        distances = new int[N  + 1][N + 1];
        parents = new int[N + 1][N + 1];
        longNames = new String[N][N];
        shortNames = new String[N];

        for (int i = 0; i < N; ++i) {
            pieces = scanner.readLine().split("\\s+");

            points[i] = new Point(Integer.parseInt(pieces[0]), Integer.parseInt(pieces[1]));
        }

        points[N] = origin;

        for (int i = 0; i <= N; ++i) {
            if (i < N) {
                shortNames[i] = (i + 1) + " ";
            }

            for (int j = 0; j <= N; ++j) {
                if (i < N && j < N) {
                    longNames[i][j] = (i + 1) + " " + (j + 1) + " ";
                }

                distances[i][j] = 2 * points[i].distance(points[j]);
                parents[i][j] = points[i].distance(points[N]) + points[i].distance(points[j]) + points[j].distance(points[N]);
            }
        }

        distance = new int[1 << N];
        parent = new int[1 << N];
        answers = new String[1 << N];
        Arrays.fill(distance, -1);
        distance[0] = 0;

        int result = rec((1 << N) - 1);
        StringBuilder answer = new StringBuilder();

        for (int i = distance.length - 1; parent[i] != i; i = parent[i]) {
            answer.append("0 ");
            answer.append(answers[i]);
        }

        answer.append("0");
        System.out.println(result);
        System.out.println(answer.toString());
    }

    private static int rec(int mask) {
        if (distance[mask] != -1) {
            return distance[mask];
        }

        int min = 0;

        while (((1 << min) & mask) == 0) {
            min++;
        }

        int newMask = mask & (~(1 << min));
        distance[mask] = rec(newMask) + distances[min][N];
        parent[mask] = newMask;
        answers[mask] = shortNames[min];

        for (int i = min + 1; i < N; i++) {
            if (((1 << i) & mask) > 0) {
                newMask = mask & (~(1 << i)) & (~(1 << min));

                int temp = rec(newMask) + parents[i][min];

                if (temp< distance[mask]) {
                    distance[mask] = temp;
                    parent[mask] = newMask;
                    answers[mask] = longNames[min][i];
                }
            }
        }

        return distance[mask];
    }

    private static class Point {
        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int distance(Point p) {
            return (int)(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2));
        }
    }
}

// package Dynamic_Programming;

import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;

public class Bitmask_prob1 {
	static int n;
	static long[] dp;
	static pair s,points[];
	public static void main(String[] args) throws IOException {
		FastReader scn = new FastReader();

		OutputStream out = new BufferedOutputStream(System.out);
		int xs = scn.nextInt(),ys = scn.nextInt();
//		s = new pair(xs,ys);
		n = scn.nextInt();

		points = new pair[n];
		for(int i=0;i<n;i++) {
			int x = scn.nextInt()-xs,y =scn.nextInt()-ys;
			points[i] = new pair(x,y);
		}

		long[][] dis =new long[n][n];
		for(int i=0;i<n;i++) {
			for(int j=i;j<n;j++) {
				if(i==j) {
					dis[i][j] = points[i].x*points[i].x+points[i].y*points[i].y;
				}else {
					long dx = points[i].x-points[j].x, dy =points[i].y-points[j].y;

					dis[i][j]=dx*dx+dy*dy;
					dis[j][i]=dis[i][j];
				}
			}
		}

		long[][] route = new long[2][1<<n];
		for(int i=0;i<1<<n;i++) {
			route[0][i] = -1;
			route[1][i] = -1;
		}
		dp = new long[1<<n];
		Arrays.fill(dp, 999999999l);
		dp[0] = 0;
		for(int mask =0;mask<((1<<n)-1);mask++) {
			if(dp[mask]!=999999999) {
				int b =0;
				for(;(mask&(1<<b))>0;b++);
				if(dp[(1<<b)+mask]>dp[mask]+2*dis[b][b]) {
					dp[(1<<b)+mask]=dp[mask]+2*dis[b][b];
					route[0][(1<<b)+mask]=b;
					route[1][(1<<b)+mask]=-1;
				}
				for(int j=b+1;j<n;j++) {
					if(((1<<j)&mask)==0) {
						int new_mask = (1<<b)+(1<<j)+mask;
//						if(new_mask==7) {
//							System.out.println("Aye! Hua");
//						}
						if(dp[new_mask]>dp[mask]+dis[b][b]+dis[j][j]+dis[b][j]) {
							dp[new_mask] = dp[mask]+dis[b][b]+dis[j][j]+dis[b][j];
							route[0][new_mask] = b;
							route[1][new_mask] = j;
						}
					}
				}
			}
		}
		out.write((dp[(1<<n)-1]+"\n0 ").getBytes());
		int cur = (1<<n)-1;
		while(cur>0) {

			int s = 1<<route[0][cur];

			out.write(((route[0][cur]+1)+" ").getBytes());
			if(route[1][cur]>=0) {
				out.write(((route[1][cur]+1)+" ").getBytes());
				s+=1<<route[1][cur];
			}
			out.write("0 ".getBytes());
			cur-=s;
		}
		out.close();
	}
//	static void rec(int i,ArrayList<Integer> taken, int orig, int mask,ArrayList<pair> chosen) {
//		if(chosen.size()==2) {
//			dp[orig] = Math.min(dp[orig], (dp[mask]==Long.MAX_VALUE?0:dp[mask])+chosen.get(0).distance(s)+chosen.get(0).distance(chosen.get(1))+chosen.get(1).distance(s));
////			System.out.println("Here "+mask);
//			return;
//		}
//		if(chosen.size()==1&&taken.size()==1) {
//			dp[orig] = Math.min(dp[orig], (dp[mask]==Long.MAX_VALUE?0:dp[mask])+2*chosen.get(0).distance(s));
////			System.out.println("Here "+mask+" "+dp[mask]);
//			return;
//		}
//		if(i==taken.size()) {
//			return;
//		}
//
//		rec(i+1, taken, orig, mask, chosen);
//		chosen.add(points[taken.get(i)]);
//		rec(i+1, taken, orig, mask^(1<<i), chosen);
//		chosen.remove(chosen.size()-1);
//	}
	static class pair{
		long x, y;
		public pair(long x, long y) {
			this.x = x;
			this.y = y;
		}
		public long distance(pair o) {
			return (this.x-o.x)*(this.x-o.x)+(this.y-o.y)*(this.y-o.y);
		}
	}
	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }

}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class C {
    static int[] DP;
    static Point[] Next;
    static int[][] pair;
    static int[] single;
    static int n;

    public static int get(int mask) {
        if (mask + 1 == (1 << n))
            return 0;
        if (DP[mask] != -1)
            return DP[mask];
        int x = 0;
        for (;; x++)
            if ((mask & (1 << x)) == 0)
                break;
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if ((mask & (1 << i)) != 0 || i == x)
                continue;
            int temp = pair[x][i] + get(mask | (1 << i) | (1 << x));
            if (temp < min) {
                min = temp;
                Next[mask] = new Point(x, i);
            }
        }
        int temp = single[x] + get(mask | (1 << x));
        if (temp < min) {
            min = temp;
            Next[mask] = new Point(x, -1);
        }
        return DP[mask] = min;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Point start = new Point(in.nextInt(), in.nextInt());
        n = in.nextInt();
        Point[] A = new Point[n];
        for (int i = 0; i < n; i++)
            A[i] = new Point(in.nextInt(), in.nextInt());
        DP = new int[1 << n];
        Next = new Point[1 << n];
        Arrays.fill(DP, -1);
        pair = new int[n][n];
        single = new int[n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                int dx1 = A[i].x - start.x;
                int dy1 = A[i].y - start.y;
                int dx2 = A[j].x - A[i].x;
                int dy2 = A[j].y - A[i].y;
                int dx3 = A[j].x - start.x;
                int dy3 = A[j].y - start.y;
                pair[i][j] = dx1 * dx1 + dy1 * dy1 + dx2 * dx2 + dy2 * dy2
                        + dx3 * dx3 + dy3 * dy3;
                single[i] = 2 * (dx1 * dx1 + dy1 * dy1);
            }
        int ans = get(0);
        System.out.println(ans);
        int mask = 0;
        while (mask + 1 != (1 << n)) {
            Point temp = Next[mask];
            if (temp.y == -1)
                System.out.print("0 " + (temp.x + 1) + " ");
            else {
                System.out
                        .print("0 " + (temp.x + 1) + " " + (temp.y + 1) + " ");
                mask |= (1 << temp.y);
            }
            mask |= (1 << temp.x);
        }
        System.out.println("0");
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

public class Handbag
{
	// http://codeforces.com/problemset/problem/8/C
	// Source of most code : http://codeforces.com/contest/8/submission/3492661

	// Keep track of each item location and also be able to
	// calculate distance between it and another object
	public static class Item{
		int x;
		int y;

		Item(int x, int y){
			this.x = x;
			this.y = y;
		}

		// Return distance between two points
		public int dist(Item i){
			int dx = x - i.x;
			int dy = y - i.y;
			return dx*dx + dy*dy;
		}
	}

	// Each value in bits[] is the min time to get certain objects
    // Ex. bits[6] = 110 is the fastest time to get items that correspond with the '1s'
	public static int solve(int bitNum){

		if(bitNum == (1 << N) - 1) // If bitNum is too big for the array
			return 0;

		if(bits[bitNum] != -1) // If bit value has already been calculated
			return bits[bitNum];

		int ans = Integer.MAX_VALUE;
		int j = 0;
		for(int i = 1; i < N; i++){

			if((bitNum & (1 << i)) == 0){ // Performs bitwise AND operation to see if bitNum and i have no bits in common

				if(j == 0){ // Only happens on the first time in IF statement
					// One item that can be picked up before returning to handbag
					ans = 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i)); // Performs bitwise exclusive OR operation
					j = i; // Change value so this case isn't ever hit again && to store value to use in else statement dists
				}
				else{
					// Find the distance between the handbag and the first item
					int dist1 = items[0].dist(items[i]);
					// Find the distance between the first item and the second item
					int dist2 = items[i].dist(items[j]);
					// Find the distance between the second item and the handbag
					int dist3 = items[j].dist(items[0]);

					// Two items that can be picked up before returning to handbag
					// distance covered between any two objects in the time equal
					// to the squared length of the segment between the points of the objects
					ans = Math.min(ans, dist1 + dist2 + dist3 + solve(bitNum | (1 << i) | (1 << j))); // Performs bitwise exclusive OR operation
				}
			}
		}
		return bits[bitNum] = ans; // Store all values in bits[] to speed up solve and for use in printOptPath
	}

	static void printOptPath(int bitNum) {
		if (bitNum == (1 << N) - 1)
			return;

		// Almost identical to solve equation except it doesn't calculate the answer, it checks the stored answer in bits
		int j = 0;
		for (int i = 1; i < N; i++)

			if ((bitNum & (1 << i)) == 0) {
				if (j == 0) {
					j = i; // Change value so this case isn't ever hit again && to find distance to this specific item in else if statement
					if (bits[bitNum] == 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i))) { // solve() should quickly return an answer because the bits[] has already been calculated
						pw.print(" " + i + " 0"); // One item that can be picked up before returning to handbag
						printOptPath(bitNum | (1 << i)); // Recursively call print with new bitNum
						return;
					}
				}
				else if (bits[bitNum] ==
								items[0].dist(items[i]) + items[i].dist(items[j]) + items[j].dist(items[0]) + solve(bitNum | (1 << i) | (1 << j))) {

					pw.print(" " + j + " " + i + " 0"); // Two items that can be picked up before returning to handbag
					printOptPath(bitNum | (1 << i) | (1 << j)); // Recursively call print with new bitNum
					return;
				}
			}
	}

	private static int N = 0;
	private static Item[] items;
	private static int[] bits;

	// PrintWriter needs to be class member because of recursive print strategy
	private static PrintWriter pw = new PrintWriter(System.out);

	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String[] input = br.readLine().split(" ");
		Item handbag = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));

		N = Integer.parseInt(br.readLine()) + 1;
		items = new Item[N];
		for(int n = 1; n < N; n++){
			input = br.readLine().split(" ");
			items[n] = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));
		}
		items[0] = handbag;

		// x << n is a right shift operator
		// which will remove the last n bits from x
		// Ex 1 << 2 => 4
		bits = new int[1 << N]; // Ex: 1 << 3 = 8; 1 << 5 = 64
		Arrays.fill(bits, -1); // Init bits array to hold -1 values

		int ans = solve(1 << 0); // Start solving with bit #1
		pw.println(ans); // Min time needed to put items in handbag

		pw.print("0"); // Init output with handbag location
		printOptPath(1 << 0); // Print possible optimum path to pick up items

		pw.close();
	}
}

import java.util.Scanner;
import java.io.PrintWriter;
import java.util.*;

public class Order8C implements Runnable {
    private Scanner in = new Scanner(System.in);
    private PrintWriter out = new PrintWriter(System.out);

    int mintime;
    String path;

    int xs;
    int ys;
    int n;
    int[] obx;
    int[] oby;

    public static void main(String[] args) {
	new Thread(new Order8C()).start();
    }

    private void read() {
	xs = in.nextInt();
	ys = in.nextInt();
	n = in.nextInt();
	obx = new int[n];
	oby = new int[n];
	for(int i = 0; i<n; i++){
	    obx[i] = in.nextInt();
	    oby[i] = in.nextInt();
	}

    }

    private void solve() {
	/* we will do dynamic programming over the subsets
	   best[m] will be the shortest for binary digits of m
	   being in.
	   last[m] will be the last subset before m */

	int[] ds = new int[n];
	int[][] d = new int[n][n];

	int[] best = new int[1 << n];
	int[] last = new int[1 << n];

	for(int i = 0; i<n; i++){
	    ds[i] = (obx[i]-xs)*(obx[i]-xs) + (oby[i]-ys)*(oby[i]-ys);
	    for(int j = i+1; j<n; j++){
		d[i][j] = (obx[i]-obx[j])*(obx[i]-obx[j]) + (oby[i]-oby[j])*(oby[i]-oby[j]);
		d[j][i] = (obx[i]-obx[j])*(obx[i]-obx[j]) + (oby[i]-oby[j])*(oby[i]-oby[j]);
	    }
	}

	for(int i=0; i< (1<<n); i++){ //goes through subsets before supersets
	    best[i] = 100000000;
	}
	best[0] = 0;

	for(int i=0; i< (1<<n); i++){ //goes through subsets before supersets
	    /*if (i % 1000000 == 0 ){
		System.out.println(i);
		}*/
	    for(int j = 0; j<n; j++){
		if( ((1 << j) & i) != 0){ // if 2^j and i have bitwise sum nonzero
		    if(best[i - (1<<j)] + 2*ds[j] < best[i]){
			best[i] = best[i - (1<<j)] + 2*ds[j];
			last[i] = i - (1<< j);

		    }
		   for(int k = j+1; k<n; k++){
		       if( ((1 << k) & i) != 0){ // if 2^k and i have bitwise sum nonzero
			   if( (best[i-(1<<j) -(1<<k)] +ds[j]+ds[k]+d[j][k]) < best[i]){
			       best[i] = (best[i-(1<<j) -(1<<k)] +ds[j]+ds[k]+d[j][k]);
			       last[i] = i -(1<<j) - (1<< k);

			   }

		       }
		   }
		   break; // break here because order doesn't really matter, just knowing which pairs to roup
		}
	    }
	}
	int i = (1<<n) -1;
	mintime = best[i];
	path = "";

	while(i >0){
	    //System.out.println("Got to i = " + i + " and path is: " + path);
	    path = path + "0 ";
	    int dif = i-last[i]; // this has one or two 1s in binary
	    for(int j=0; j<n; j++){
		if( ((1<<j) & dif) != 0){ // if dif has a 1 in the j'th digit
		    path  = path + (j+1) + " ";
		}
	    }

	    i = last[i];
	}
	path = path + "0";
    }

    private void write() {
	out.println(mintime);
	out.println(path);
    }
    public void run() {
	read();
	solve();
	write();
	out.close();
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 111118315581
 *
 * @author pttrung
 */
public class C {

    static Point hand;
    static int n;
    static Point[] data;
    static int[] next;
    static int[] dp;
    static int[][] pre;

    public static void main(String[] args) {
        Scanner in = new Scanner();
        PrintWriter out = new PrintWriter(System.out);
        // System.out.println(1 << 24);
        hand = new Point(in.nextInt(), in.nextInt());
        n = in.nextInt();
        data = new Point[n];
        for (int i = 0; i < n; i++) {
            data[i] = new Point(in.nextInt(), in.nextInt());
        }
        pre = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                pre[i][j] = distance(data[i], data[j]);
            }
        }

        next = new int[1 << n];
        dp = new int[1 << n];
        Arrays.fill(dp, -1);

        out.println(cal(0));

        int start = 0;

        do {
            int m = next[start];
            int val = m - start;
            out.print(0 + " ");
            for (int i = 0; i < n; i++) {
                if (((1 << i) & val) != 0) {
                    out.print((i + 1) + " ");
                }
            }
            // out.print(0 + " ")  ;
            start = m;
        } while (start != (1 << n) - 1);
        out.println(0);
        out.close();
    }

    public static int cal(int mask) {
        if ((1 << n) - 1 == mask) {
            //  System.out.println(mask);
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (((1 << i) & mask) == 0) {
                int dist = distance(hand, data[i]);

                for (int j = i + 1; j < n; j++) {
                    if (((1 << j) & mask) == 0) {
                        //System.out.println(i + " " + j);
                        int temp = dist + distance(hand, data[j]) + pre[i][j] + cal(mask | (1 << i) | (1 << j));
                        //System.out.println(temp);
                        if (temp < result) {
                            result = temp;
                            next[mask] = (mask | (1 << i) | (1 << j));
                        }

                    }
                }

                    int temp = 2 * dist + cal(mask | (1 << i));
                    if (temp < result) {
                        result = temp;
                        next[mask] = (mask | (1 << i));
                    }

                break;
            }

        }
        dp[mask] = result;
        return result;
    }

    static int distance(Point a, Point b) {
        int total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return total;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}

import java.io.*;
import java.util.*;

public class Solution {
    BufferedReader in;
    StringTokenizer st;
    PrintWriter out;

    public Solution() throws Exception {
	in = new BufferedReader(new InputStreamReader(System.in));
	out = new PrintWriter(System.out);
    }

    public String next() throws Exception {
	if (st == null || !st.hasMoreTokens()) {
	    st = new StringTokenizer(in.readLine());
	}
	return st.nextToken();
    }

    public int nextInt() throws Exception {
	return Integer.parseInt(next());
    }

    public long nextLong() throws Exception {
	return Long.parseLong(next());

    }

    public double nextDouble() throws Exception {
	return Double.parseDouble(next());
    }

    public static void main(String[] args) throws Exception {
	new Solution().run(args);
    }

    public int dist(int x0, int y0, int x1, int y1) {
	return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
    }

    public void run(String[] args) throws Exception {
	int x0 = nextInt();
	int y0 = nextInt();
	int n = nextInt();
	int[] x = new int[n];
	int[] y = new int[n];
	int[][] d = new int[n + 1][n + 1];
	for (int i = 0; i < n; ++i) {
	    x[i] = nextInt();
	    y[i] = nextInt();
	}

	for (int i = 0; i < n; ++i) {
	    for (int j = i; j < n; ++j) {
	    	d[i + 1][j + 1] = d[j + 1][i + 1] = dist(x[i], y[i], x[j], y[j]);
		d[i + 1][0] = d[0][i + 1] = dist(x0, y0, x[i], y[i]);
	    	d[0][j + 1] = d[j + 1][0] = dist(x0, y0, x[j], y[j]);
	    }
	}

	int[] s = new int[(1 << n)];
	int[] path = new int[(1 << n)];
	Arrays.fill(s, Integer.MAX_VALUE / 2);
	s[0] = 0;
	for (int mask = 0; mask < (1 << n); ++mask) {
	    for (int i = 0; i < n; ++i) {
		if ((mask & (1 << i)) == 0) {
		    for (int j = i; j < n; ++j) {
			if ((mask & (1 << j)) == 0) {
			    int newmask = mask | (1 << i) | (1 << j);
			    int score = s[mask] + d[0][i + 1] + d[i + 1][j + 1] + d[0][j + 1];
			    if (s[newmask] > score) {
				s[newmask] = score;
				path[newmask] = mask;
			    }
			}
		    }
		    break;
		}
	    }
	}
	int f = (1 << n) - 1;
	out.println(s[f]);
	LinkedList<Integer> p = new LinkedList<Integer>();
	p.add(0);
	while(f != 0) {
	    int pf = f ^ path[f];
	    for (int i = 0; i < n; ++i) {
		if (((pf >> (i)) & 1) == 1) {
		    p.add(i + 1);
		}
	    }
	    p.add(0);
	    f = path[f];
	}
	out.print(p.pollLast());
	while(!p.isEmpty()) {
	    out.print(" " + p.pollLast());
	}
	out.println();
	in.close();
	out.close();
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class Task8C_v2 {

	private static int n;
	private final static Map<Integer, Result> cache = new HashMap<>();

	public static void clearCache() {
		cache.clear();
	}

	public static void main(String[] args) {
		System.out.println(go(System.in));
	}

	public static String go(InputStream is) {
		XY bag = null;
		XY[] things;
		int mask;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			bag = new XY(br.readLine());
			n = Integer.parseInt(br.readLine());
			things = new XY[n];
			mask = 0;
			for (int i = 0; i < n; i++) {
				things[i] = new XY(br.readLine());
				mask = (mask << 1) + 1;
			}
		} catch (IOException e) {
			System.out.println(e);
			return "-1";
		}
		int mask1 = 1;
		for (int i = 0; i < n; i++) {
			int time = (bag.x - things[i].x) * (bag.x - things[i].x) + (bag.y - things[i].y) * (bag.y - things[i].y);
			cache.put(mask1, new Result(mask1, time));
			mask1 <<= 1;
		}
		mask1 = 1;
		for (int i = 0; i < n; i++) {
			int mask2 = mask1 << 1;
			for (int j = i + 1; j < n; j++) {
				cache.put(mask1 + mask2,
						new Result(mask1 + mask2,
								(things[j].x - things[i].x) * (things[j].x - things[i].x)
										+ (things[j].y - things[i].y) * (things[j].y - things[i].y)
										+ cache.get(mask1).time + cache.get(mask2).time));
				mask2 <<= 1;

			}
			mask1 <<= 1;
		}
		mask1 = 1;
		for (int i = 0; i < n; i++) {
			cache.get(mask1).time <<= 1;
			mask1 <<= 1;
		}
		mask1 = 1;
		return find(mask).toString();
	}

	private static Result find(int mask) {
		Result result = cache.get(mask);
		if (result != null) {
			// System.out.println("Return result: " + result);
			return result;
		}
		int index1 = 1;
		while ((mask & index1) != index1) {
			index1 <<= 1;
		}
		Result result1 = cache.get(index1);
		Result result2 = find(mask - index1);
		Result bestResult = new Result(result1, result2);

		int index2 = index1 << 1;
		while (index2 < mask) {

			if ((mask & index2) == index2) {
				result1 = cache.get(index1 + index2);
				// System.out.println("Result1: " + result1);
				result2 = find(mask - index1 - index2);
				int time = result1.time + result2.time;
				if (time < bestResult.time) {
					bestResult = new Result(result1, result2);
					// System.out.println("New best: " + bestResult);
				}
			}
			index2 <<= 1;
		}
		cache.put(mask, bestResult);
		// System.out.println("Return result: " + bestResult);
		return bestResult;
	}

	static class Result {
		int mask;
		int time;
		Result result = null;

		public Result() {
			time = 0;
		}

		public Result(Result res1, Result res2) {
			this.time = res1.time + res2.time;
			mask = res1.mask;
			result = res2;
		}

		public Result(int mask, int time) {
			this.mask = mask;
			this.time = time;
		}

		private void appendStr(StringBuilder str) {
			int temp = mask;
			int index1 = 1;
			while ((temp & 1) != 1) {
				temp >>= 1;
				index1++;
			}
			str.append(" ").append(index1);
			if (temp > 1) {
				temp--;
				while ((temp & 1) != 1) {
					temp >>= 1;
					index1++;
				}
				str.append(" ").append(index1);
			}
			str.append(" 0");
			if (result != null) {
				result.appendStr(str);
			}
		}

		@Override
		public String toString() {
			StringBuilder str = new StringBuilder(Integer.toString(time));
			str.append("\r\n");
			str.append("0");
			appendStr(str);
			return str.toString();
		}
	}

	static class XY {
		int x;
		int y;

		public XY() {

		}

		public XY(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public XY(String str) {
			String[] strs = str.split(" ");
			x = Integer.parseInt(strs[0]);
			y = Integer.parseInt(strs[1]);
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ProblemC {
	public static void main(String[] args) throws IOException {
		BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);

		// generateRandom();

		int[] pt = readPoint(s);
		int n = Integer.valueOf(s.readLine());
		int[][] xp = new int[n+1][];
		for (int i = 1 ; i <= n ; i++) {
			xp[i] = readPoint(s);
		}
		xp[0] = pt;

		int[][] dist = new int[n+1][n+1];
		for (int i = 0 ; i <= n ; i++) {
			for (int j = 0 ; j <= n ; j++) {
				int dx = Math.abs(xp[i][0] - xp[j][0]);
				int dy = Math.abs(xp[i][1] - xp[j][1]);
				dist[i][j] = dx*dx + dy*dy;
			}
		}

		int[][] dist2 = new int[n+1][n+1];
		for (int i = 0 ; i <= n ; i++) {
			for (int j = 0 ; j <= n ; j++) {
				dist2[i][j] = dist[0][i] + dist[i][j] + dist[j][0];
			}
		}

		int[] dp = new int[1<<n];
		int[][] dp_prev = new int[2][1<<n];
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0] = 0;

		for (int i = 0 ; i < (1<<n) ; i++) {
			if (dp[i] == Integer.MAX_VALUE) {
				continue;
			}
			int base = dp[i];
			// two
			for (int y = 0 ; y < n ; y++) {
				if ((i & (1<<y)) >= 1) {
					break;
				}
				for (int z = y+1 ; z < n ; z++) {
					if ((i & (1<<z)) >= 1) {
						continue;
					}
					int ti = i | (1<<y) | (1<<z);
					int d = dist2[y+1][z+1];
					if (dp[ti] > base + d) {
						dp[ti] = base + d;
						dp_prev[0][ti] = z+1;
						dp_prev[1][ti] = y+1;
					}
				}
			}
		}

		int bestOnes = 0;
		for (int i = 0 ; i < (1<<n) ; i++) {
			if (dp[i] == Integer.MAX_VALUE) {
				continue;
			}
			int sub = (1<<n) - 1 - i;
			int add = 0;
			for (int j = 0 ; j < n ; j++) {
				if ((sub & (1<<j)) >= 1) {
					add += dist[0][j+1] * 2;
				}
			}
			if (dp[i] + add < dp[(1<<n)-1]) {
				dp[(1<<n)-1] = dp[i] + add;
				bestOnes = sub;
			}
		}

		StringBuffer b = new StringBuffer();
		b.append(" 0");
		for (int i = 0 ; i < n ; i++) {
			if ((bestOnes & (1<<i)) >= 1) {
				b.append(" ").append(i+1).append(" ").append(0);
			}
		}

		out.println(dp[(1<<n)-1]);
		int nptn = (1<<n)-1-bestOnes;
		while (nptn >= 1) {
			int i1 = dp_prev[0][nptn];
			int i2 = dp_prev[1][nptn];
			if (i1 >= 1) {
				nptn -= 1<<(i1-1);
				b.append(" ").append(i1);
			}
			if (i2 >= 1) {
				nptn -= 1<<(i2-1);
				b.append(" ").append(i2);
			}
			b.append(" ").append(0);
		}
		out.println(b.substring(1));
		out.flush();
	}

	private static void generateRandom() {
		System.out.println("0 0");
		System.out.println("24");
		for (int i = 0 ; i < 24 ; i++) {
			int a = (int)(Math.random() * 200 - 100);
			int b = (int)(Math.random() * 200 - 100);
			System.out.println(a + " " + b);
		}
	}

	private static int[] readPoint(BufferedReader s) throws IOException {
		int[] ret = new int[2];
		String[] data = s.readLine().split(" ");
		ret[0] = Integer.valueOf(data[0]);
		ret[1] = Integer.valueOf(data[1]);
		return ret;
	}

	public static void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}
}

import java.io.*;

public class CF8C {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s = br.readLine();
		int si = s.indexOf(' ', 0);
		int x = Integer.parseInt(s.substring(0, si));
		int y = Integer.parseInt(s.substring(si + 1));
		int n = Integer.parseInt(br.readLine());
		int[] xx = new int[n + 1];
		int[] yy = new int[n + 1];
		for (int i = 0; i < n; i++) {
			s = br.readLine();
			si = s.indexOf(' ', 0);
			xx[i] = Integer.parseInt(s.substring(0, si));
			yy[i] = Integer.parseInt(s.substring(si + 1));
		}
		xx[n] = x;
		yy[n] = y;
		int[][] dd = new int[n + 1][n + 1];
		for (int i = 0; i <= n; i++)
			for (int j = i + 1; j <= n; j++) {
				int dx = xx[i] - xx[j];
				int dy = yy[i] - yy[j];
				dd[i][j] = dx * dx + dy * dy;
			}
		int[] aa = new int[1 << n];
		int[] bb = new int[1 << n];
		for (int k = 1; k < 1 << n; k++) {
			int a = -1;
			for (int b = 0; b < n; b++)
				if ((k & 1 << b) > 0) {
					a = b;
					break;
				}
			int l = k ^ 1 << a;
			int d = dd[a][n] + dd[a][n];
			aa[k] = aa[l] + d;
			bb[k] = l;
			for (int b = a + 1; b < n; b++)
				if ((k & 1 << b) > 0) {
					l = k ^ 1 << a ^ 1 << b;
					d = dd[a][n] + dd[b][n] + dd[a][b];
					if (aa[l] + d < aa[k]) {
						aa[k] = aa[l] + d;
						bb[k] = l;
					}
				}
		}
		int k = (1 << n) - 1;
		System.out.println(aa[k]);
		StringBuilder sb = new StringBuilder();
		sb.append(0);
		while (k != 0) {
			int l = bb[k];
			int m = k ^ l;
			for (int b = 0; b < n; b++)
				if ((m & 1 << b) > 0)
					sb.append(' ').append(b + 1);
			sb.append(' ').append(0);
			k = l;
		}
		System.out.println(sb);
	}
}

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;

/**
 * Created by 11815 on 2017/7/1.
 */
public class Main {
    private static int[] x = new int[26], y = new int[26], dp = new int[1<<24], pre = new int[1<<24];
    private static int dis(int i, int j) {
        return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int x0 = in.nextInt(), y0 = in.nextInt(), n = in.nextInt();
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        x[n] = x0;
        y[n] = y0;
        int[][] gra = new int[26][26];
        for (int i = 0; i < n + 1; i++) {
            for (int j = i+1; j < n+1; j++) {
                gra[i][j] = gra[j][i] = dis(i,j);
            }
        }
        Arrays.fill(dp, -1);
        dp[0] = 0;
        for (int i = 0; i < 1 << n; i++) {
            if (dp[i] != -1) {
                for (int j = 0; j < n; j++) {
                    if (((1<<j)&i) == 0) {
                        int t = i | (1<<j), tmp = dp[i] + 2*gra[j][n];
                        if (dp[t] == -1 || dp[t] > tmp) {
                            dp[t] = tmp;
                            pre[t] = i;
                        }
                        for (int k = 0; k < n; k++) {
                            if ((t&(1<<k)) == 0) {
                                int t2 = t | (1<<k), tmp2 = dp[i] + gra[n][j] + gra[j][k] + gra[k][n];
                                if (dp[t2] == -1 || dp[t2] > tmp2) {
                                    dp[t2] = tmp2;
                                    pre[t2] = i;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
        int end = (1<<n)-1, cnt = 0;
        int[] ans = new int[60];
        System.out.println(dp[end]);
        while (end != 0) {
            int pr = pre[end];
            int tem = pr^end;
            int a = 0, b = 0;
            for (int i = 0; i < n; i++) {
                if (((1<<i)&tem)!=0) {
                    b=a;
                    a=i+1;
                }
            }
            ans[cnt++] = 0;
            ans[cnt++] = a;
            if (b>0) {
                ans[cnt++] = b;
            }
            end = pr;
        }
        ans[cnt++] = 0;
        for (int i = cnt-1; i >= 0; i--) {
            System.out.print(ans[i] + " ");
        }
        System.out.print("\n");
    }
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class B {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    final PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    StringTokenizer tokenizer;
    final int[][] d;
    final int n;
    final int[] time;
    final Action[] actions;

    private static final class Action {
        int a;
        int b;

        public Action(int a) {
            this.a = this.b = a;
        }

        public Action(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public String toString() {
            if (a == b)
                return " " + (a+1);
            return " " + (a+1) + " " + (b+1);
        }
    }

    private static final int dist(int x1, int y1, int x2, int y2) {
        return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    }

    private final boolean in(int x, int set) {
        return ((1 << x) & set) != 0;
    }

    private final int off(int x, int set) {
        return (set ^ (set & (1 << x)));
    }

    private final int solve(int set) {
        if (time[set] > 0)
            return time[set];
        int min = Integer.MAX_VALUE;
        if (set == 0)
            min = 0;
        else {
            int a;
            for (a = 0; a < n; a++)
                if (in(a, set))
                    break;
            int subset = off(a, set);
            int aux = 2 * d[a][a] + solve(subset);
            if (aux < min) {
                min = aux;
                actions[set] = new Action(a);
            }
            for (int b = a + 1; b < n; b++)
                if (in(b, subset)) {
                    aux = d[a][a] + d[b][b] + d[a][b] + solve(off(b, subset));
                    if (aux < min) {
                        min = aux;
                        actions[set] = new Action(a, b);
                    }
                }
        }
        time[set] = min;
        return min;
    }

    private B() throws IOException {
        int bx = nextInt();
        int by = nextInt();
        n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        reader.close();

        d = new int[n][n];
        for (int i = 0; i < n; i++) {
            d[i][i] = dist(bx, by, x[i], y[i]);// |A|
            for (int j = i + 1; j < n; j++)
                d[i][j] = dist(x[i], y[i], x[j], y[j]);// |AB|
        }
        int set = 1 << n;
        time = new int[set];
        actions = new Action[set];
        set--;
        printer.println(solve(set));
        printer.print("0");
        while (set != 0) {
            solve(set);
            Action action = actions[set];
            printer.print(action);
            printer.print(" 0");
            set = off(action.a, set);
            set = off(action.b, set);
        }

        printer.println();
        printer.close();
    }

    private final int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    private final String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

    public static void main(String[] args) throws IOException {
        new B();
    }

}

import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
	static int dis[][],dp[][];
    public static void main(String args[]) {
    	Scanner cin=new Scanner(System.in);
    	int a=cin.nextInt(),b=cin.nextInt(),n=cin.nextInt();
    	dp=new int[1<<n][3];
    	dis=new int[n+1][n+1];
    	int arr[][]=new int[n+1][2];
    	for(int i=1;i<(1<<n);i++) {
    		Arrays.fill(dp[i], 2147483647);
    	}
    	for(int i=1;i<=n;i++) {
    		arr[i][0]=cin.nextInt();
    		arr[i][1]=cin.nextInt();
    	}
    	arr[0][0]=a;
    	arr[0][1]=b;
    	for(int i=1;i<=n;i++) {
    		for(int j=0;j<i;j++) {
    			dis[j][i]=(int)Math.pow(arr[i][0]-arr[j][0],2)+(int)Math.pow(arr[i][1]-arr[j][1],2);
    			dis[i][j]=dis[j][i];
    		}
    	}
    	for(int i=0;i<(1<<n)-1;i++) {
    		if(dp[i][0]==2147483647) continue;
    		for(int j=1;j<=n;j++) {
    			int t=1<<(j-1);
    			if((t&i)==0) {
    				for(int k=1;k<=n;k++) {
    					if((i&(1<<(k-1)))>0) continue;
    					int tt=1<<(k-1);
    					int op=t==tt?(i+t):(i+t+tt);
    					int di=dis[0][j]+dis[j][k]+dis[k][0];
    					if(dp[i][0]+di<dp[op][0]) {
    						dp[op][0]=dp[i][0]+di;
    						dp[op][1]=k;
    						dp[op][2]=j;
    						if(j==k) dp[op][1]=0;
    					}
    				}
    				break;
    			}
    		}
    	}
    	System.out.println(dp[(1<<n)-1][0]);
    	int m=(1<<n)-1;
    	boolean sign=true;
    	while(m>0) {
    		if(sign) {
    			System.out.print("0 ");
    			sign=false;
    		}
    		System.out.print(dp[m][2]+" "+dp[m][1]+" ");
    		if(dp[m][1]>0) {
    			System.out.print("0 ");
    		}
    		int u=0;
    		if(dp[m][2]>0) u+=(1<<(dp[m][2]-1));
    		if(dp[m][1]>0) u+=(1<<(dp[m][1]-1));
    		m-=u;
    	}
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

import static java.lang.Integer.MAX_VALUE;
import static java.lang.Integer.parseInt;

/**
 * 8C
 *
 * @author artyom
 */
public class LookingForOrder {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] parsedString = parsedString = in.readLine().split(" ");
        int xStart = parseInt(parsedString[0]);
        int yStart = parseInt(parsedString[1]);
        int objectNum = parseInt(in.readLine());

        int[] xLocs = new int[objectNum + 1];
        int[] yLocs = new int[objectNum + 1];
        int[] bitMasks = new int[1 << objectNum];
        Arrays.fill(bitMasks, MAX_VALUE);
        int[] previous = new int[1 << objectNum];

        xLocs[objectNum] = xStart;
        yLocs[objectNum] = yStart;
        for (int i = 0; i < objectNum; i++) {
            parsedString = in.readLine().split(" ");
            xLocs[i] = parseInt(parsedString[0]);
            yLocs[i] = parseInt(parsedString[1]);
        }

        //go through all pairs and find time requirement for each pair of objects
        //the entry at point [i][j] is equal to the time it takes to get from point i to point j
        int[][] times = new int[objectNum + 1][objectNum + 1];
        for (int i = 0; i <= objectNum; i++) {
            for (int j = 0; j <= objectNum; j++) {
                times[i][j] = times[j][i] = (xLocs[i] - xLocs[j]) * (xLocs[i] - xLocs[j]) + (yLocs[i] - yLocs[j]) * (yLocs[i] - yLocs[j]);
            }
        }

        //each value in bitmasks represents the minimum time necessary to get
        //the unmasked bits
        //so bitmasks[5] (5=101) is the fastest time in which you can get
        //items 1 and 3
        bitMasks[0] = 0; //collecting zero objects takes 0 time
        for (int i = 0; i < (1 << objectNum); i++) {
            if (bitMasks[i] != MAX_VALUE) {
                for (int j = 0; j < objectNum; j++) {
                    if (((1 << j) & i) == 0) { //if our current j object hasn't been picked up yet
                        int curState = (1 << j) | i; //ith state after picking up j object
                        int curTime = bitMasks[i] + 2 * times[objectNum][j]; //time required to get object j from bag at state i

                        if (curTime < bitMasks[curState]) {
                            bitMasks[curState] = curTime; //put fastest time in for gettingto our current state
                            previous[curState] = i;
                        }

                        //find another thing while you're out
                        for (int k = 0; k < objectNum; k++) {
                            if (((1 << k) & curState) == 0) { //if the kth position in our current state hasn't been picked up
                                int kState = ((1 << k) | curState); //curstate after picking up the kth object
                                //kTime is time it takes to go from bag, to j, to k and back
                                int kTime = bitMasks[i] + times[objectNum][j] + times[j][k] + times[k][objectNum];

                                if (kTime < bitMasks[kState]) {
                                    bitMasks[kState] = kTime;  //put shortest time for getting to kState in
                                    previous[kState] = i;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }

        int finalState = (1 << objectNum) - 1;

        StringBuilder sb = new StringBuilder();
        sb.append(bitMasks[finalState]).append('\n');

        Deque<Integer> outputQ = new ArrayDeque<>();
        outputQ.add(0);
        int curState = finalState;
        while (curState > 0) {
            //difference is the objects picked up in this state but not in previous state
            int difference = curState ^ previous[curState];
            int firstItem = -1;
            int secondItem = -1;

            for (int i = 0; i < objectNum; i++) {
                if (((1 << i) & difference) > 0) { //if the ith object was picked up in this state
                    secondItem = firstItem; //keep track of how many items are picked up
                    firstItem = i;
                }
            }

            if (secondItem != -1) {
                //put in two items followed by a return to 0
                outputQ.add(firstItem + 1);
                outputQ.add(secondItem + 1);
                outputQ.add(0);
            } else {
                outputQ.add(firstItem + 1);
                outputQ.add(0);
            }

            curState = previous[curState];
        }

        sb.append(outputQ.removeLast());
        while (!outputQ.isEmpty()) {
            sb.append(' ').append(outputQ.removeLast());
        }
        System.out.print(sb);
    }
}

import java.util.Scanner;

public class CF_8C {

	public static void main(String[] args) {

		// Hooray bitmasks! I'm good at these :)

		Scanner in = new Scanner(System.in);

		// Handbag coordinates..
		int hb_x = in.nextInt(), hb_y = in.nextInt();
		int n = in.nextInt();
		int[] ox = new int[n];
		int[] oy = new int[n];

		// Dynamic programming: Also store a matrix of the time to reach one
		//  object from the other.
		// This considers the handbag to be object 0
		int[][] dt = new int[n][n];
		int[] hbd = new int[n];
		for (int i = 0; i < n; i++) {
			ox[i] = in.nextInt();
			oy[i] = in.nextInt();
			hbd[i] = (ox[i] - hb_x) * (ox[i] - hb_x)
					+ (oy[i] - hb_y) * (oy[i] - hb_y);
		}

		// Compute elapsed times...
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				dt[i][j] = (ox[i] - ox[j]) * (ox[i] - ox[j])
						+ (oy[i] - oy[j]) * (oy[i] - oy[j]);
			}
		}

		// Fill up an array with the amount of time it takes to grab
		//  all objects with the specified bitmask.
		int[] sofar = new int[1 << n];
		int[] masks = new int[1 << n];
		sofar[0] = 0;
		for (int i = 1; i < (1 << n); i++) {
			sofar[i] = -1;
		}

		for (int i = 0; i < (1 << n); i++) {
			if (sofar[i] != -1) {
				for (int maskbit = 0; maskbit < n; maskbit++) {
					// Look for first object in bitmask to grab...
					if (((1 << maskbit) & i) == 0) {
						int iffirst = ((1 << maskbit) | i);
						int fromold = sofar[i] + 2 * hbd[maskbit];

						if (sofar[iffirst] == -1 || sofar[iffirst] > fromold) {
							// A better way to get to position J was found, use it.
							sofar[iffirst] = fromold;
							masks[iffirst] = i;
						}

						// Find another thing while you're out...
						for (int otherone = 0; otherone < n; otherone++) {
							if (((1 << otherone) & iffirst) == 0) {
								int iffollow = ((1 << otherone) | iffirst);
								int fromi = sofar[i] + hbd[maskbit] + dt[maskbit][otherone] + hbd[otherone];

								// Did we find a better way to get to iffollow state?
								if (sofar[iffollow] == -1 || sofar[iffollow] > fromi) {
									sofar[iffollow] = fromi;
									masks[iffollow] = i;
								}
							}
						}
						break;
					}
				}
			}
		}

		// After all this time, we have an answer.
		// The minimum time will be the value of sofar at the very end,
		//  which will have the case of if all objects were picked up.
		// Clever, no?
		// The logic came from http://www.darrensun.com/codeforces-round-8/
		// Wish I could claim it mine, but it is not so.

		int end_val = (1 << n) - 1;

		System.out.println(sofar[end_val]);
		System.out.print(0);
		while (end_val > 0) {
			// Which objects were collected in the prvious trip?
			int diff = end_val ^ masks[end_val];
			int obj1 = -1, obj2 = -1;
			for (int i = 0; i < n; i++) {
				if (((1 << i) & diff) > 0) {
					obj2 = obj1;
					obj1 = i;
				}
			}

			if (obj2 >= 0) {
				// Two objects were collected this trip, output them both.
				System.out.print(" " + (obj1 + 1) + " " + (obj2 + 1) + " 0");
			} else {
				// Only one object was collected here.
				System.out.print(" " + (obj1 + 1) + " 0");
			}
			end_val = masks[end_val];
		}

		in.close();
	}

}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
	static final int INF = (int)1e9;
	static Point a[];
	static Point o;
	static int n;
	static int dp[];
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);

		o = new Point(sc.nextInt(), sc.nextInt());
		n = sc.nextInt();
		a = new Point[n];
		for (int i = 0; i < n; i++)
			a[i] = new Point(sc.nextInt(), sc.nextInt());

		dp = new int[(1 << n) + 5];
		Arrays.fill(dp, -1);
		out.println(rec(0));
		out.print(0 + " ");
		path(0);
		out.println();

		out.flush();
		out.close();
	}

	static void path(int msk) {
		if (msk == (1 << n) - 1) return;

		int optimal = rec(msk);
		for (int i = 0; i < n; i++) {
			if ((msk & (1 << i)) == 0) {
				if (rec(msk | (1 << i)) + 2 * o.dist(a[i]) == optimal) {
					out.print((i + 1) + " " + 0 + " ");
					path(msk | (1 << i));
					return;
				}

				for (int j = 0; j < n; j++)
					if (rec(msk | (1 << i) | (1 << j)) + o.dist(a[i]) + a[i].dist(a[j]) + a[j].dist(o) == optimal) {
						out.print((i + 1) + " " + (j + 1) + " " + 0 + " ");
						path(msk | (1 << i) | (1 << j));
						return;
					}
				break;
			}
		}
	}

	static int rec(int msk) {
		if (msk == (1 << n) - 1) return 0;
		if (dp[msk] != -1) return dp[msk];

		int ans = INF;
		for (int i = 0; i < n; i++) {
			if ((msk & (1 << i)) == 0) {
				ans = Math.min(ans, rec(msk | (1 << i)) + 2 * o.dist(a[i]));
				for (int j = 0; j < n; j++) {
					if (i == j) continue;
					if ((msk & (1 << j)) == 0)
						ans = Math.min(ans, rec(msk | (1 << i) | (1 << j)) + o.dist(a[i]) + a[i].dist(a[j]) + a[j].dist(o));
				}
				break;
			}
		}

		return dp[msk] = ans;
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public int dist(Point p) {
			return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
		}
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		public Scanner(FileReader f) {
			br = new BufferedReader(f);
		}

		public Scanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public boolean Ready() throws IOException {
			return br.ready();
		}

		public void waitForInput(long time) {
			long ct = System.currentTimeMillis();
			while(System.currentTimeMillis() - ct < time) {};
		}

	}

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class _8C {

  static int[] x = new int[30], y = new int[30];
  static int[][] dist = new int[30][30];
  static int n;
  static final int M = 1000;
  static int[] bitPos = new int[M];
  static {
    Arrays.fill(bitPos, -1);
    for (int i=0; i<24; i++)
      bitPos[(1 << i) % M] = i;
  }

  static int sqr(int i) {
    return i * i;
  }

  public static void main(String[] args) throws Exception {
    Reader.init(System.in);
    BufferedWriter cout = new BufferedWriter(new OutputStreamWriter(System.out));

    x[0] = Reader.nextInt();
    y[0] = Reader.nextInt();
    n = Reader.nextInt();
    for (int i=1; i<=n; i++) {
      x[i] = Reader.nextInt();
      y[i] = Reader.nextInt();
    }
    for (int i=0; i<=n; i++)
      for (int j=0; j<=n; j++)
        dist[i][j] = sqr(x[i] - x[j]) + sqr(y[i] - y[j]);

    int[] f = new int[1 << n];
    int[] r = new int[1 << n];
    for (int mask=1; mask<(1 << n); mask++) {
      int lowbit = mask & -mask;
      int lowbitPos = bitPos[lowbit % M];
      f[mask] = dist[lowbitPos + 1][0] * 2 + f[mask ^ lowbit];
      r[mask] = lowbit;
        for (int i=mask^(lowbit); i>0; i=i^(i & -i)) {
          int otherBit = i & -i;
          int otherBitPos = bitPos[otherBit % M];
          int tmp = dist[0][lowbitPos + 1] + dist[lowbitPos + 1][otherBitPos + 1] + dist[otherBitPos + 1][0] + f[mask ^ otherBit ^ lowbit];
          if (tmp < f[mask]) {
            f[mask] = tmp;
            r[mask] = lowbit | otherBit;
          }
      }
    }

    System.out.println(f[(1 << n) - 1]);
    int mask = (1 << n) - 1;
    while(mask > 0) {
      if ((r[mask] ^ (r[mask] & -r[mask])) == 0) {
        System.out.print("0 " + (bitPos[r[mask] % M] + 1) + " ");
      }
      else {
        int bit1 = r[mask] & -r[mask];
        int bit2 = r[mask] ^ bit1;
        System.out.print("0 " + (bitPos[bit1 % M] + 1) + " " + (bitPos[bit2 % M] + 1) + " ");
      }
      mask ^= r[mask];
    }
    System.out.println("0");

    cout.close();
  }

  static class Pair<U extends Comparable<U>, V extends Comparable<V>> implements Comparable<Pair<U, V>> {
    final U _1;
    final V _2;

    private Pair(U key, V val) {
      this._1 = key;
      this._2 = val;
    }

    public static <U extends Comparable<U>, V extends Comparable<V>> Pair<U, V> instanceOf(U _1, V _2) {
      return new Pair<U, V>(_1, _2);
    }

    @Override
    public String toString() {
      return _1 + " " + _2;
    }

    @Override
    public int hashCode() {
      int res = 17;
      res = res * 31 + _1.hashCode();
      res = res * 31 + _2.hashCode();
      return res;
    }

    @Override
    public int compareTo(Pair<U, V> that) {
      int res = this._1.compareTo(that._1);
      if (res < 0 || res > 0)
        return res;
      else
        return this._2.compareTo(that._2);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (!(obj instanceof Pair))
        return false;
      Pair<?, ?> that = (Pair<?, ?>) obj;
      return _1.equals(that._1) && _2.equals(that._2);
    }
  }

  /** Class for buffered reading int and double values */
  static class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
      reader = new BufferedReader(new InputStreamReader(input));
      tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
      while (!tokenizer.hasMoreTokens()) {
        // TODO add check for eof if necessary
        tokenizer = new StringTokenizer(reader.readLine());
      }
      return tokenizer.nextToken();
    }

    static int nextInt() throws IOException {
      return Integer.parseInt(next());
    }

    static double nextDouble() throws IOException {
      return Double.parseDouble(next());
    }
  }

  static class ArrayUtil {
    static void swap(int[] a, int i, int j) {
      int tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }

    static void swap(long[] a, int i, int j) {
      long tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }

    static void swap(double[] a, int i, int j) {
      double tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }

    static void swap(char[] a, int i, int j) {
      char tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }

    static void swap(boolean[] a, int i, int j) {
      boolean tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }

    static void reverse(int[] a, int i, int j) {
      for (; i < j; i++, j--)
        swap(a, i, j);
    }

    static void reverse(long[] a, int i, int j) {
      for (; i < j; i++, j--)
        swap(a, i, j);
    }

    static void reverse(double[] a, int i, int j) {
      for (; i < j; i++, j--)
        swap(a, i, j);
    }

    static void reverse(char[] a, int i, int j) {
      for (; i < j; i++, j--)
        swap(a, i, j);
    }

    static void reverse(boolean[] a, int i, int j) {
      for (; i < j; i++, j--)
        swap(a, i, j);
    }

    static long sum(int[] a) {
      int sum = 0;
      for (int i : a)
        sum += i;
      return sum;
    }

    static long sum(long[] a) {
      long sum = 0;
      for (long i : a)
        sum += i;
      return sum;
    }

    static double sum(double[] a) {
      double sum = 0;
      for (double i : a)
        sum += i;
      return sum;
    }

    static int max(int[] a) {
      int max = Integer.MIN_VALUE;
      for (int i : a)
        if (i > max)
          max = i;
      return max;
    }

    static int min(int[] a) {
      int min = Integer.MAX_VALUE;
      for (int i : a)
        if (i < min)
          min = i;
      return min;
    }

    static long max(long[] a) {
      long max = Long.MIN_VALUE;
      for (long i : a)
        if (i > max)
          max = i;
      return max;
    }

    static long min(long[] a) {
      long min = Long.MAX_VALUE;
      for (long i : a)
        if (i < min)
          min = i;
      return min;
    }
  }
}

import java.util.Arrays;
import java.util.Scanner;

public class C
{

    public static void main(String[] args)
    {
        new C();
    }

    final int oo = (int)1e9;

    int Hx,Hy;

    int N;
    int[][] P;

    int[] memo;
    int[][] soln;

    int[] dist1;
    int[][] dist2;

    C()
    {
        Scanner in = new Scanner(System.in);
        Hx=in.nextInt();
        Hy=in.nextInt();

        N=in.nextInt();
        P=new int[N][2];
        for (int i=0; i<N; ++i)
        {
            P[i][0]=in.nextInt();
            P[i][1]=in.nextInt();
        }

        memo=new int[1<<N];
        Arrays.fill(memo, -1);
        soln=new int[2][1<<N];

        dist1=new int[N];
        Arrays.fill(dist1, -1);
        dist2=new int[N][N];
        for (int[] d : dist2) Arrays.fill(d, -1);

        int res=go((1<<N)-1);
        System.out.println(res);

        int set=(1<<N)-1;
        while (set>0)
        {
            System.out.print("0 ");
            System.out.print((soln[0][set]+1)+" ");
            if (soln[1][set]>-1) System.out.print((soln[1][set]+1)+" ");

            if (soln[1][set]>-1)
            {
                set-=((1<<soln[0][set])+(1<<soln[1][set]));
            }
            else
            {
                set-=(1<<soln[0][set]);
            }
        }
        System.out.println("0");
    }

    int go(int set)
    {
        if (set==0)
            return 0;
        if (memo[set]>-1)
            return memo[set];

        int res=oo;
        int i=0;
        while (!on(set,i)) ++i;

        res=dist(i)+go(set-(1<<i));
        soln[0][set]=i;
        soln[1][set]=-1;

        for (int j=i+1; j<N; ++j)
        {
            if (on(set,j))
            {
                int tmp=dist(i,j)+go(set-(1<<i)-(1<<j));
                if (tmp<res)
                {
                    res=tmp;
                    soln[0][set]=i;
                    soln[1][set]=j;
                }
            }
        }

        return memo[set]=res;
    }

    // H->i->H
    int dist(int i)
    {
        if (dist1[i]>-1) return dist1[i];

        int dx=P[i][0]-Hx;
        int dy=P[i][1]-Hy;
        return dist1[i]=2*(dx*dx+dy*dy);
    }

    // H->i->j->H
    int dist(int i, int j)
    {
        if (dist2[i][j]>-1) return dist2[i][j];

        int res=0,dx,dy;

        dx=P[i][0]-Hx;
        dy=P[i][1]-Hy;
        res+=dx*dx+dy*dy;

        dx=P[i][0]-P[j][0];
        dy=P[i][1]-P[j][1];
        res+=dx*dx+dy*dy;

        dx=P[j][0]-Hx;
        dy=P[j][1]-Hy;
        res+=dx*dx+dy*dy;

        return dist2[i][j]=res;
    }

    boolean on(int set, int loc)
    {
        return (set&(1<<loc))>0;
    }
}

import java.io.*;
import java.util.*;

public class Main {
	private void run() throws IOException {
		int cx = in.nextInt();
		int cy = in.nextInt();
		int n = in.nextInt();
		int[] x = new int[n];
		int[] y = new int[n];
		for (int i = 0; i < n; ++i) {
			x[i] = in.nextInt() - cx;
			y[i] = in.nextInt() - cy;
		}
		int[] dp = new int[1 << n];
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0] = 0;
		int[] prev = new int[1 << n];
		for (int mask = 0; mask < (1 << n); ++mask) {
			if (dp[mask] == Integer.MAX_VALUE) {
				continue;
			}
			for (int i = 0; i < n; ++i) {
				if (((mask >> i) & 1) == 0) {
					if (dp[mask | (1 << i)] > dp[mask] + dist(x[i], y[i])) {
						dp[mask | (1 << i)] = dp[mask] + dist(x[i], y[i]);
						prev[mask | (1 << i)] = mask;
					}
					for (int j = i + 1; j < n; ++j) {
						if (((mask >> j) & 1) == 0) {
							if (dp[mask | (1 << i) | (1 << j)] > dp[mask] + dist(x[i], y[i], x[j], y[j])) {
								dp[mask | (1 << i) | (1 << j)] = dp[mask] + dist(x[i], y[i], x[j], y[j]);
								prev[mask | (1 << i) | (1 << j)] = mask;
							}
						}
					}
					break;
				}
			}
		}
		out.println(dp[(1 << n) - 1]);
		int mask = (1 << n) - 1;
		out.print(0);
		while (mask != 0) {
			int p = prev[mask];
			int cur = p ^ mask;
			List<Integer> who = new ArrayList<Integer>();
			for (int i = 0; i < n; ++i) {
				if (((cur >> i) & 1) != 0) {
					who.add(i + 1);
				}
			}
			for (int t : who) {
				out.print(" " + t);
			}
			out.print(" " + 0);
			mask = p;
		}
		out.flush();
	}

	private int dist(int x, int y, int x2, int y2) {
		return x * x + y * y + x2 * x2 + y2 * y2 + (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);
	}

	private int dist(int x, int y) {
		return 2 * (x * x + y * y);
	}

	private class Scanner {
		private StringTokenizer tokenizer;
		private BufferedReader reader;

		public Scanner(Reader in) {
			reader = new BufferedReader(in);
			tokenizer = new StringTokenizer("");
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public boolean hasNext() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				String next = reader.readLine();
				if (next == null)
					return false;
				tokenizer = new StringTokenizer(next);
			}
			return true;
		}

		public String next() throws IOException {
			hasNext();
			return tokenizer.nextToken();
		}

		public String nextLine() throws IOException {
			tokenizer = new StringTokenizer("");
			return reader.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}
	}

	public static void main(String[] args) throws IOException {
		new Main().run();
	}
	Scanner in = new Scanner(new InputStreamReader(System.in));
	PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	void work() {
		int x=in.nextInt(),y=in.nextInt();
		int n=in.nextInt();
		int[][] A=new int[n][2];
		for(int i=0;i<n;i++) {
			A[i]=new int[] {in.nextInt()-x,in.nextInt()-y};
		}
		int[][] dis=new int[n][n];
		for(int i=0;i<n;i++) {
			for(int j=i;j<n;j++) {
				if(i==j) {
					dis[i][i]=A[i][0]*A[i][0]+A[i][1]*A[i][1];
				}else {
					int dx=A[i][0]-A[j][0],dy=A[i][1]-A[j][1];
					dis[i][j]=dx*dx+dy*dy;
					dis[j][i]=dis[i][j];
				}
			}
		}
		int[] dp=new int[1<<n];
		int[][] route=new int[2][1<<n];
		for(int i=0;i<1<<n;i++) {
			route[0][i]=-1;
			route[1][i]=-1;
		}
		for(int i=1;i<1<<n;i++) {
			int b=0;
			for(;((1<<b)&i)==0;b++);
			dp[i]=dp[i-(1<<b)]+2*(dis[b][b]);
			route[0][i]=b;
			for(int j=b+1;j<n;j++) {
				if(((1<<j)&i)>0) {
					int nm=i-(1<<b)-(1<<j);
					int v=dp[nm]+dis[b][j]+dis[b][b]+dis[j][j];
					if(v<dp[i]) {
						dp[i]=v;
						route[0][i]=b;
						route[1][i]=j;
					}
				}
			}
		}
		out.println(dp[(1<<n)-1]);
		out.print(0+" ");
		int cur=(1<<n)-1;
		while(cur>0) {
			int s=1<<route[0][cur];
			out.print((route[0][cur]+1)+" ");
			if(route[1][cur]>=0) {
				out.print((route[1][cur]+1)+" ");
				s+=1<<route[1][cur];
			}
			out.print(0+" ");
			cur-=s;
		}
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;

public class CF8C {
	static int n;
	static int[] mem;
	static HashMap<Integer, String> map;
	static int INF = (int) 1e9;
	static StringBuilder sb;

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner(System.in);
		String s = sc.nextLine();
		n = sc.nextInt();
		mem = new int[1 << n];
		Arrays.fill(mem, -1);
		map = new HashMap<>();
		map.put(0, s);
		for (int i = 1; i <= n; i++) {
			map.put(i, sc.nextLine());
		}
		int val = dp(0);
		PrintWriter pw = new PrintWriter(System.out);
		pw.println(val);
		sb = new StringBuilder();
		sb.append("0 ");
		build(0);
		pw.println(sb);
		pw.flush();
	}

	// node == 0 -- > count 0 // state == 0 has 1 // state == 1 has 2

	private static int dp(int msk) {
		if (msk == (1 << n) - 1)
			return 0;

		if(mem[msk] != -1)
			return mem[msk];

		boolean foundFirst = false;
		int val = (int)1e9;
		int mark = -1;
		for (int i = 1; i <= n; i++) {
			if ((msk & 1 << (i - 1)) == 0){
				if(!foundFirst){
					foundFirst = true;
					mark = i;
					val = dist(0, mark)*2 + dp(msk | 1 << (mark - 1));
				}else{
					val = Math.min(val, dist(0, mark) + dist(mark, i) + dist(i, 0) + dp((msk|1 << (mark - 1))|1 << (i - 1)));
				}
			}
		}
		return mem[msk] = val;
	}

	private static int dist(int node, int i) {
		String from = map.get(i);
		String to = map.get(node);
		String[] fromco = from.split(" ");
		String[] toco = to.split(" ");
		int xs = Integer.parseInt(fromco[0]);
		int ys = Integer.parseInt(fromco[1]);
		int xf = Integer.parseInt(toco[0]);
		int yf = Integer.parseInt(toco[1]);
		return (xs - xf) * (xs - xf) + (ys - yf) * (ys - yf);
	}

	private static void build(int msk) {
		if (msk == (1 << n) - 1)
			return;
		boolean foundFirst = false;
		int ans = dp(msk);
		int mark = -1;
		int val = (int)1e9;
		for (int i = 1; i <= n; i++) {
			if ((msk & 1 << (i - 1)) == 0){
				if(!foundFirst){
					foundFirst = true;
					mark = i;
					val = dist(0, mark)*2 + dp(msk | 1 << (mark - 1));
					if(val == ans){
						sb.append(mark + " 0 ");
						build(msk | 1 << (mark - 1));
						return;
					}
				}else{
					val = dist(0, mark) + dist(mark, i) + dist(i, 0) + dp(msk|1 << (mark - 1)|1 << (i - 1));
					if(val == ans){
						sb.append(mark + " " + i + " 0 ");
						build(msk|1 << (mark - 1)|1 << (i - 1));
						return;
					}
				}
			}
		}
	}

	static class MyScanner {
		StringTokenizer st;
		BufferedReader br;

		public MyScanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public MyScanner(String s) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(new File(s)));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}
}

import java.io.*;
import java.util.*;

public class Main
{
	static final boolean _DEBUG = false;

	private static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner(BufferedReader _br) {
			br = _br;
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					e.printStackTrace();
					return "";
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	static MyScanner   scan;
	static PrintWriter out;

	static int debugCount = 0;
	static void debug(String msg) {
		if (_DEBUG && debugCount < 200) {
			out.println(msg);
			out.flush();
			debugCount++;
		}
	}

    public static void main (String args[]) throws IOException {
//    	scan = new MyScanner(new BufferedReader(new FileReader("test.in")));
    	scan = new MyScanner(new BufferedReader(new InputStreamReader(System.in)));
    	out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        Main inst = new Main();
        inst.execute();
        out.close();
    }

    int dist(int index1, int index2) {
    	int[] loc1, loc2;
    	if (index1 == index2) {
    		return 0;
    	}
    	if (dist[index1+1][index2+1] != 0) {
    		return dist[index1+1][index2+1];
    	}
    	if (index1 == -1) {
    		loc1 = root;
    	} else {
    		loc1 = pos[index1];
    	}
    	if (index2 == -1) {
    		loc2 = root;
    	} else {
    		loc2 = pos[index2];
    	}
    	return dist[index2+1][index1+1] = dist[index1+1][index2+1] =
    			((loc1[0]-loc2[0])*(loc1[0]-loc2[0]))+((loc1[1]-loc2[1])*(loc1[1]-loc2[1]));
    }

    int N, pow;
    int[] root, dp, p;
    int[][] pos, dist;

    void execute() {
    	root = new int[2];
    	root[0] = scan.nextInt();
    	root[1] = scan.nextInt();
    	N = scan.nextInt();
    	pow = 1<<N;
    	dp = new int[pow];
    	p = new int[pow];
    	pos = new int[N][2];
    	dist = new int[N+1][N+1];
    	for (int i = 0; i < N; i++) {
    		pos[i][0] = scan.nextInt();
    		pos[i][1] = scan.nextInt();
    	}
    	p[0] = -1;
    	for (int i = 1; i < pow; i++) {
    		dp[i] = Integer.MAX_VALUE;
    		p[i] = -1;
    		int l = 0;
    		for (;l < N; l++) {
    			if ((i & (1<<l)) != 0) break;
    		}
    		for (int j = l; j < N; j++) {
    			if ((i & (1 << j)) != 0) {
    				int comb = ((1<<j) | (1<<l));
        			int v = i ^ comb;
//        			System.out.println(v);
        			int dis = dp[v] + dist(-1, j) + dist(j, l) + dist(l, -1);
        			if (dis < dp[i]) {
        				dp[i] = dis;
        				p[i] = comb;
        			}
    			}
    		}
    	}
    	out.println(dp[pow-1]);
    	out.print("0");
    	int cur = pow-1;
    	while (p[cur] != -1) {
    		int i = p[cur];
//    		System.out.println(Integer.toBinaryString(cur));
//    		System.out.println(Integer.toBinaryString(i));
    		for (int l = 0; l < N; l++) {
    			if ((i & (1 << l)) != 0) {
    				// find first;
    				out.print(" " + (l+1));
    				i = i ^ (1 << l);
    				for (int second = l+1; second < N; second++) {
    					if ((i & (1 << second)) != 0) {
    						out.print(" " + (second+1));
    					}
    				}
    				break;
    			}
    		}
    		cur = cur ^ p[cur];
    		out.print(" 0");
    	}
    	out.println();
    }
}

import java.util.Scanner;

public class Problem_8C {
  private static int dis(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int ox = sc.nextInt();
    int oy = sc.nextInt();
    int n = sc.nextInt();
    int[] ix = new int[n];
    int[] iy = new int[n];
    int[] single = new int[n];
    int[][] pair = new int[n][n];
    for (int i = 0; i < n; i++) {
      ix[i] = sc.nextInt();
      iy[i] = sc.nextInt();
      single[i] = dis(ox, oy, ix[i], iy[i]) * 2;
      for (int j = 0; j < i; j++) {
        pair[i][j] = pair[j][i] = dis(ix[i], iy[i], ix[j], iy[j]) + (single[i] + single[j]) / 2;
      }
    }
    int[] min = new int[1 << n];
    int[] pre = new int[1 << n];
    for (int set = 1; set < 1 << n; set++) {
      int i;
      for (i = 0; i < n; i++) {
        if ((set & (1 << i)) != 0) {
          break;
        }
      }
      min[set] = min[set ^ (1 << i)] + single[i];
      pre[set] = set ^ (1 << i);
      for (int j = 0; j < n; j++) {
        if ((set & (1 << j)) == 0) {
          continue;
        }
        if (min[set] > min[set ^ (1 << i) ^ (1 << j)] + pair[i][j]) {
          min[set] = min[set ^ (1 << i) ^ (1 << j)] + pair[i][j];
          pre[set] = set ^ (1 << i) ^ (1 << j);
        }
      }
    }
    System.out.println(min[(1 << n) - 1]);
    for (int set = (1 << n) - 1; set != 0; set = pre[set]) {
      System.out.print("0 ");
      for (int i = 0; i < n; i++) {
        if (((set ^ pre[set]) & (1 << i)) != 0) {
          System.out.print((i + 1) + " ");
        }
      }
    }
    System.out.println("0");
    sc.close();
  }
}

import java.io.*;
import java.util.*;

public class LookingForOrder
{
	public Scanner in = new Scanner(System.in);
	public PrintStream out = System.out;

	public int[] go;
	public int[][] cost;

	public int [] sol;
	public Pair[] how;
	public int n, lim;

	public Pair bag;
	public Pair[] obj;

	public void main()
	{
		bag = new Pair(in.nextInt(), in.nextInt());

		n = in.nextInt();
		obj = new Pair[n];
		for(int i=0;i<n;++i) obj[i] = new Pair(in.nextInt(), in.nextInt());

		go = new int[n];
		cost = new int[n][n];
		for(int i=0;i<n;++i)
		{
			go[i] = squDist(bag, obj[i]);
			for(int j=0;j<n;++j) cost[i][j] = squDist(obj[i], obj[j]);
		}

		lim = (1<<n);

		sol = new int[lim];
		Arrays.fill(sol, -1);
		how = new Pair[lim];

		out.println(solve(lim-1));

		Pair T;
		int set = lim-1;

		out.print("0");
		while(set > 0)
		{
			solve(set);
			T = how[set];
			out.print(" "+(T.x+1));
			set = off(T.x, set);
			if(T.y >= 0)
			{
				out.print(" " + (T.y+1));
				set = off(T.y, set);
			}
			out.print(" 0");
		}
		out.println();
	}//end public void main()

	public int oo = 987654321;

	public boolean in(int x, int set) { return ((1<<x) & set) != 0; }
	//Turn on bit x
	public int on(int x, int set) { return (set | (1<<x)); }
	//Turn off bit x
	public int off(int x, int set) { return (set ^ (set & (1<<x)) ); }

	public int solve(int set)
	{
		if(sol[set] >= 0) return sol[set];

		int ret;
		if(set == 0) ret = 0;
		else
		{
			ret = oo;

			int x, y, sub, c;
			for(x=0;x<n;++x) if(in(x, set)) break;

			sub = off(x, set);
			c =  go[x]+go[x]+solve(sub);

			if(c < ret)
			{
				how[set] = new Pair(x, -1);
				ret = c;
			}

			for(y=x+1;y<n;++y) if(in(y, set))
			{
				c = go[x]+cost[x][y]+go[y] + solve(off(y, sub));
				if(c < ret)
				{
					ret = c;
					how[set] = new Pair(x, y);
				}
			}
		}

		return sol[set] = ret;
	}

	public int squDist(int ax, int ay, int bx, int by)
	{
		int dx, dy;
		dx = ax - bx;
		dy = ay - by;
		return dx*dx + dy*dy;
	}

	public int squDist(Pair p, Pair q)
	{
		return squDist(p.x, p.y, q.x, q.y);
	}

	//int pair
	private class Pair implements Comparable<Pair>
	{
		public int x, y;
		public Pair(int xx, int yy) { x = xx; y = yy; }

		public int compareTo(Pair u)
		{
			if(x!=u.x) return x-u.x;
			return y-u.y;
		}

		public String toString() { return "(" + x + "," + y + ")"; }
	}

	public static void main(String[] args)
	{
		(new LookingForOrder()).main();
	}
}

import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class Solution implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer st;

    int[] x;
    int[] y;
    int n;
    int X, Y;

    int[] d;
    int[][] dist;

    int sqr(int a) {
        return a * a;
    }

    int dist(int X, int Y, int i) {
        return sqr(X - x[i]) + sqr(Y - y[i]);
    }

    int[] dp;
    byte[][] pred;

    int rec(int mask) {
        if (dp[mask] == -1) {
            int res = 1 << 29;
            boolean ok = false;
            for (int i = 0; i < n; ++i)
                if ((mask & (1 << i)) > 0) {
                    ok = true;
                    int mm = mask & ~(1 << i);
                    for (int j = i; j < n; j++)
                        if ((mask & (1 << j)) > 0) {
                            int nmask = mm & ~(1 << j);
                            int a = rec(nmask) + d[i] + d[j] + dist[i][j];
                            if (a < res) {
                                res = a;
                                pred[0][mask] = (byte) (i);
                                pred[1][mask] = (byte) (j);
                            }
                        }
                    break;
                }
            if (!ok)
                res = 0;
            dp[mask] = res;
        }
        return dp[mask];
    }

    void solve() throws IOException {
        X = ni();
        Y = ni();
        n = ni();
        // if (n > 5)
        // return;
        x = new int[n];
        y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = ni();
            y[i] = ni();
        }
        d = new int[n];
        dist = new int[n][n];
        for (int i = 0; i < n; ++i)
            d[i] = dist(X, Y, i);
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; j++) {
                dist[i][j] = dist(x[i], y[i], j);
            }
        pred = new byte[2][1 << n];
        dp = new int[1 << n];
        Arrays.fill(dp, -1);
        out.println(rec((1 << n) - 1));
        int a = (1 << n) - 1;
        while (a > 0) {
            if (pred[0][a] != pred[1][a])
                out.print(0 + " " + (pred[0][a] + 1) + " " + (pred[1][a] + 1)
                        + " ");
            else
                out.print(0 + " " + (pred[0][a] + 1) + " ");
            int na = a & ~(1 << pred[0][a]);
            na &= ~(1 << pred[1][a]);
            a = na;
        }
        out.println(0);
    }

    public Solution() throws IOException {
        Locale.setDefault(Locale.US);
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        in.close();
        out.close();
    }

    String ns() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

    int ni() throws IOException {
        return Integer.valueOf(ns());
    }

    long nl() throws IOException {
        return Long.valueOf(ns());
    }

    double nd() throws IOException {
        return Double.valueOf(ns());
    }

    public static void main(String[] args) throws IOException,
            InterruptedException {
        Thread th = new Thread(null, new Solution(), "", 536870912);
        th.start();
        th.join();
    }

    @Override
    public void run() {
        try {
            Locale.setDefault(Locale.US);
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
            solve();
            in.close();
            out.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
static int n;
static int []x,y,memo;
static StringBuilder sb;
static int distance(int i,int j)
{
	int dx=x[i]-x[j];
	int dy=y[i]-y[j];
	return dx*dx+dy*dy;
}
public static int dp(int msk)
{
	if(msk==(1<<(n+1))-2)
		return 0;
	if(memo[msk]!=-1)
		return memo[msk];
	int ans=10000000;
	boolean found=false;
	for(int i=1;i<=n && !found;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				found=true;
				int newM=msk|1<<i;
				newM|=1<<j;
				ans=Math.min(ans, dp(newM)+Math.min(distance(0,i)+distance(i,j)+distance(j,0), distance(0,j)+distance(j,i)+distance(i,0)));
			}
	return memo[msk]=ans;

}
public static void print(int msk)
{
	if(msk==(1<<(n+1))-2)
		return ;

	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				int newM=msk|1<<i;
				newM|=1<<j;
				int d1=distance(0,i)+distance(i,j)+distance(j,0);
				int d2=distance(0,j)+distance(j,i)+distance(i,0);
				if(dp(msk)== dp(newM)+Math.min(d1,d2))
				{

					if(i==j)

						sb.append("0 "+i+" ");

					else if(d1<d2)
						sb.append("0 "+i+" "+j+" ");
					else
						sb.append("0 "+j+" "+i+" ");

					print(newM);
					return ;
				}
			}

}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int xS=sc.nextInt(),yS=sc.nextInt();
		n=sc.nextInt();
		x=new int [n+1];
		y=new int [n+1];
		x[0]=xS;y[0]=yS;
		for(int i=1;i<=n;i++)
		{
			x[i]=sc.nextInt();
			y[i]=sc.nextInt();

		}
		memo=new int [1<<(n+1)];
		Arrays.fill(memo,-1);
		sb=new StringBuilder();

		sb.append(dp(0)+"\n");
		print(0);
		sb.append("0");
		System.out.println(sb);
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		public Scanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());

		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}

import java.util.*;

public class PointsNew {

    static int bagX;
    static int bagY;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        bagX = scanner.nextInt();
        bagY = scanner.nextInt();

        int n = scanner.nextInt();

        TreeSet<Point> points = new TreeSet<>(Comparator.comparingInt(o -> o.id));

        for (int i = 0; i < n; i++) {
            points.add(new Point(i + 1, scanner.nextInt(), scanner.nextInt()));
        }

        Map<Set<Point>, Result> dp = new HashMap<>();

        Result result = solve(points, dp);

        System.out.println(result.min);

        int size = result.deque.size();
        for (int i = 0; i < size - 1; i++) {
            System.out.print(result.deque.pop() + " ");
        }
        System.out.print(result.deque.pop());
    }

    private static Result solve(TreeSet<Point> items, Map<Set<Point>, Result> dp) {
        if (items.isEmpty()) {
            ArrayDeque<Integer> deque = new ArrayDeque<>();
            deque.push(0);
            return new Result(0, deque);
        }
        if (dp.containsKey(items)) return dp.get(items);

        Point first = items.pollFirst();
        Point otherN = null;

        int min = Integer.MAX_VALUE;

        Deque<Integer> deque;

        Result res = solve(items, dp);
        min = Math.min(min, 2 * calculateTime(bagX, bagY, first.x, first.y) + res.min);
        deque = new ArrayDeque<>(res.deque);

        for (Point other : items) {
            TreeSet<Point> left = new TreeSet<>(items);
            left.remove(other);
            int totalDistance = calculateTime(bagX, bagY, first.x, first.y) +
                    calculateTime(bagX, bagY, other.x, other.y) +
                    calculateTime(first.x, first.y, other.x, other.y);

            Result resNew = solve(left, dp);

            if (totalDistance + resNew.min < min) {
                otherN = other;
                min = totalDistance + resNew.min;
                deque = new ArrayDeque<>(resNew.deque);
            }
        }

        deque.push(first.id);

        if (otherN != null) {
            deque.push(otherN.id);
        }

        deque.push(0);

        items.add(first);

        Result result = new Result(min, deque);
        dp.put(items, result);

        return result;
    }

    private static int calculateTime(int x1, int y1, int x2, int y2) {
        return (int) (Math.pow(Math.abs(x1 - x2), 2) + Math.pow(Math.abs(y1 - y2), 2));
    }

    static class Result {
        int min;
        Deque<Integer> deque;

        public Result(int min, Deque<Integer> deque) {
            this.min = min;
            this.deque = deque;
        }
    }

    static class Point {
        int id;
        int x;
        int y;

        public Point(int id, int x, int y) {
            this.id = id;
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return String.valueOf(id);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Point point = (Point) o;
            return id == point.id &&
                    x == point.x &&
                    y == point.y;
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, x, y);
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// Jonathan
// cpt_fwiffo

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] line = in.readLine().split(" ");
        int Xs = Integer.parseInt(line[0]);
        int Ys = Integer.parseInt(line[1]);
        int n = Integer.parseInt(in.readLine());

        int[][] points = new int[n+1][2];
        points[n][0] = Xs;//set starting point as last point for finding distances
        points[n][1] = Ys;

        for(int i=0; i< n ; i++)
        {
            line = in.readLine().split(" ");
            points[i][0] = Integer.parseInt(line[0]);
            points[i][1] = Integer.parseInt(line[1]);
        }

        int[][] distances = new int[n+1][n+1];
        ComputeDistances(points, distances, n);

        int[] dp = new int[1<<n];
        int[] path = new int[1<<n];
        ComputeLowestPath(dp, path, distances, n);
        OutputLowestAndPath(dp, path, n);

    }

    private static void ComputeLowestPath(int[] dp, int[] path, int[][] distances, int n)
    {
        for(int i = 1; i < 1<<n; i++)
        {
            int j = 0;
            while(true) //find first 1 (LSB)
            {
                if((i&(1<<j))!=0) //check for a bit equal to 1 in location j
                {
                    break;
                }
                j++;
            }

            int pastEntry = i & ~(1<<j); //remove first 1 from i
            path[i] = pastEntry; //set the path we came from to trace later
            int distance = distances[j][n] * 2; //distance from origin to the point being removed, and back
            dp[i] = dp[pastEntry] + distance; //set minimum distance if just this point is added to the collection

            for(int m = j +1; m < n; m++)
            {
                if((i & (1<<m))!=0)
                {
                    int entry = i & ~((1<<j)|(1<<m)); //remove both 1 at position j and 1 at position m from i
                    distance = distances[j][n] + distances[j][m] + distances[m][n]; //calculate round-trip distance to grab 2 points

                    if(dp[i] > dp[entry] + distance) // check if this new option is a better choice.  If it is, update our value and our path.
                    {
                        dp[i] = dp[entry] + distance;
                        path[i] = entry;
                    }
                }
            }

        }
    }

    private static void OutputLowestAndPath(int[] dp, int[] path, int n)
    {

        StringBuilder out = new StringBuilder();
        out.append(dp[(1<<n)-1]);//output min value of traversal
        out.append("\n");
        out.append("0 ");
        int index = (1<<n)-1; //start at our min value
        while(index != 0)
        {
            int j = path[index];
            int k = index ^ j; //find the one or two values that were added at this step
            for(int m = 0; m < n; m++)
            {
                if((k & (1 << m)) != 0)
                {
                    out.append(m+1);
                    out.append(" ");
                }
            }
            out.append("0 ");
            index = j;
        }
        System.out.println(out.toString());
    }

    private static void ComputeDistances(int[][] points, int[][] distances, int n)
    {
        for(int i = 0; i <= n; i++) //calculate distances between all points so that we don't have to compute later
        {
            for(int j=i+1; j<=n; j++)
            {
                int x= points[i][0] - points[j][0];
                int y= points[i][1] - points[j][1];
                distances[i][j] = x*x + y*y;
            }
        }
    }

}

import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class Solution {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer st;

    int[] x;
    int[] y;
    int n;
    int X, Y;

    int[] d;
    int[][] dist;

    int sqr(int a) {
        return a * a;
    }

    int dist(int X, int Y, int i) {
        return sqr(X - x[i]) + sqr(Y - y[i]);
    }

    int[] dp;
    byte[][] pred;

    int rec(int mask) {
        if (dp[mask] == -1) {
            int res = 1 << 29;
            boolean ok = false;
            for (int i = 0; i < n; ++i)
                if ((mask & (1 << i)) > 0) {
                    ok = true;
                    int mm = mask & ~(1 << i);
                    for (int j = i; j < n; j++)
                        if ((mask & (1 << j)) > 0) {
                            int nmask = mm & ~(1 << j);
                            int a = rec(nmask) + d[i] + d[j] + dist[i][j];
                            if (a < res) {
                                res = a;
                                pred[0][mask] = (byte) (i);
                                pred[1][mask] = (byte) (j);
                            }
                        }
                    break;
                }
            if (!ok)
                res = 0;
            dp[mask] = res;
        }
        return dp[mask];
    }

    void solve() throws IOException {
        X = ni();
        Y = ni();
        n = ni();
        x = new int[n];
        y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = ni();
            y[i] = ni();
        }
        d = new int[n];
        dist = new int[n][n];
        for (int i = 0; i < n; ++i)
            d[i] = dist(X, Y, i);
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; j++) {
                dist[i][j] = dist(x[i], y[i], j);
            }
        pred = new byte[2][1 << n];
        dp = new int[1 << n];
        Arrays.fill(dp, -1);
        out.println(rec((1 << n) - 1));
        int a = (1 << n) - 1;
        while (a > 0) {
            if (pred[0][a] != pred[1][a])
                out.print(0 + " " + (pred[0][a] + 1) + " " + (pred[1][a] + 1)
                        + " ");
            else
                out.print(0 + " " + (pred[0][a] + 1) + " ");
            int na = a & ~(1 << pred[0][a]);
            na &= ~(1 << pred[1][a]);
            a = na;
        }
        out.println(0);
    }

    public Solution() throws IOException {
        Locale.setDefault(Locale.US);
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        in.close();
        out.close();
    }

    String ns() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

    int ni() throws IOException {
        return Integer.valueOf(ns());
    }

    long nl() throws IOException {
        return Long.valueOf(ns());
    }

    double nd() throws IOException {
        return Double.valueOf(ns());
    }

    public static void main(String[] args) throws IOException {
        new Solution();
    }
}

import java.util.Arrays;
import java.util.Scanner;

public class LookingForOrder {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int bx = in.nextInt();
        int by = in.nextInt();
        in.nextLine();
        int n = in.nextInt();
        int[][] objects = new int[n][2];
        for (int i = 0; i < n; i++) {
            objects[i][0] = in.nextInt();
            objects[i][1] = in.nextInt();
        }

        int[] cs = new int[n];
        for (int i = 0; i < n; i++) {
            cs[i] = 2 * time(objects[i], new int[] { bx, by });
        }

        int[][] cd = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                cd[j][i] = cd[i][j] = time(objects[i], new int[] { bx, by }) + time(objects[j], new int[] { bx, by }) + time(objects[i], objects[j]);
            }
        }

        int maxMask = 1 << n;
        int[] dp = new int[maxMask];
        int[] path = new int[maxMask];
        Arrays.fill(dp, -1);
        dp[0] = 0;

        for (int g = 1; g < maxMask; g++) {
            int min = Integer.MAX_VALUE;
            int minPath = 0;
            int h = 31;
            while ((g & (1 << h)) == 0)
                h--;
            h++;
            int l = 0;
            while ((g & (1 << l)) == 0)
                l++;
            if ((g & 1 << l) > 0) {
                int oneleft = g ^ (1 << l);
                int t = cs[l] + dp[oneleft];
                if (t < min) {
                    min = t;
                    minPath = oneleft;
                }
                for (int j = l + 1; j < h; j++) {
                    if ((oneleft & 1 << j) > 0) {
                        int twoleft = oneleft ^ (1 << j);
                        t = cd[l][j] + dp[twoleft];
                        if (t < min) {
                            min = t;
                            minPath = twoleft;
                        }
                    }
                }
            }
            dp[g] = min;
            path[g] = minPath;
        }

        System.out.println(dp[maxMask - 1]);

        int previous = maxMask - 1;
        int pathElt = path[previous];
        System.out.print("0 ");
        while (previous > 0) {
            int bits = previous - pathElt;
            int h = 31;
            while ((bits & (1 << h)) == 0)
                h--;
            int l = 0;
            while ((bits & (1 << l)) == 0)
                l++;
            String el = h == l ? "" + (h + 1) : (h + 1) + " " + (l + 1);
            System.out.print(el + " " + 0 + " ");
            previous = pathElt;
            pathElt = path[pathElt];
        }
        System.out.println();

    }

    static int time(int[] a, int[] b) {
        int x = b[0] - a[0];
        int y = b[1] - a[1];
        return x * x + y * y;
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class CF8C {

    public static void main(String[] args) {
        int x = IN.nextInt(), y = IN.nextInt();
        int n = IN.nextInt(), A[][] = new int[n][2];
        for (int i = 0; i < n; i++) {
            A[i][0] = IN.nextInt();
            A[i][1] = IN.nextInt();
        }
        solve(x, y, n, A);
    }

    final static int INF = 100000000;

    private static void solve(int x, int y, int n, int[][] A) {
        int distance[][] = new int[n][n], d[] = new int[n];
        int dp[] = new int[1 << n], pre[] = new int[1 << n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                distance[i][j] = (int) Math.pow(A[i][0] - A[j][0], 2) + (int) Math.pow(A[i][1] - A[j][1], 2);
            }
            d[i] = (int) Math.pow(A[i][0] - x, 2) + (int) Math.pow(A[i][1] - y, 2);
        }
        Arrays.fill(dp, INF);
        dp[0] = 0;
        for (int i = 1; i < 1 << n; i++) {
            int ii = Integer.lowestOneBit(i), n1 = getNO(ii), t1 = i;
            while (t1 != 0) {
                int jj = Integer.lowestOneBit(t1);
                int n2 = getNO(jj);
                int cur = dp[i ^ (ii | jj)] + distance[n1][n2] + d[n1] + d[n2];
                if (cur < dp[i]) {
                    pre[i] = i ^ (ii | jj);
                    dp[i] = cur;
                }
                t1 -= jj;
            }
        }
        int cur = (1 << n) - 1;
        StringBuilder sb = new StringBuilder(2 * n + 2);
        sb.append("0 ");
        while (cur > 0) {
            int t1 = cur - pre[cur];
            int lb = Integer.lowestOneBit(t1);
            sb.append(getNO(lb) + 1).append(" ");
            if (t1 - lb != 0) {
                sb.append(getNO(t1 - lb) + 1).append(" ");
            }
            sb.append("0 ");
            cur = pre[cur];
        }
        PrintWriter pr = new PrintWriter(System.out);
        pr.println(dp[(1 << n) - 1] + "\n" + sb.toString().trim());
        pr.flush();
    }

    private static int getNO(int mask) {
        int n = 0;
        while (mask != 0) {
            mask >>= 1;
            n++;
        }
        return n - 1;
    }

    static final class IN {

        private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 65536);
        private static StringTokenizer st = null;

        public static String readLine() throws IOException {
            return br.readLine();
        }

        public static String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    break;
                }
            }
            return st.nextToken();
        }

        public static int nextInt() {
            return Integer.valueOf(next());
        }

        public static long nextLong() {
            return Long.valueOf(next());
        }

        public static void close() {
            try {
                br.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class C8 {
	static int[] mem;
	static int[] bag;
	static int[][] items;
	static int[] close;
	static PrintWriter pw;
	static int n;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		pw = new PrintWriter(System.out);

		bag = new int[2];
		bag[0] = sc.nextInt();
		bag[1] = sc.nextInt();

		n = sc.nextInt();
		items = new int[n][2];

		for(int i = 0;i<n;i++)
		{
			items[i][0] = sc.nextInt();
			items[i][1] = sc.nextInt();
		}

		//System.out.println((items[0][1]-bag[1])*(items[0][1]-bag[1]));

		mem = new int[1<<n];

		Arrays.fill(mem, -1);

		pw.println(dp(0));
		trace(0);
		pw.print(0);

		pw.flush();
	}
	static int dp(int mask){
		if(mask==(1<<n)-1)
			return 0;

		if(mem[mask]!=-1)
			return mem[mask];

		int ans = (int)1e9;
		for(int i = 0;i<n;i++)
			if((1<<i&mask)==0)
			{
				ans = getDisBag(i)*2+dp(mask|1<<i);

				for(int j = i+1;j<n;j++)
					if((1<<j&mask)==0)
						ans = Math.min(ans, getDisBag(i)+getDis(i,j)+getDisBag(j)+dp(mask|1<<i|1<<j));

				break;
			}

		return mem[mask] = ans;
	}
	static int getDis(int i, int j){
		return (items[i][0]-items[j][0])*(items[i][0]-items[j][0])+(items[i][1]-items[j][1])*(items[i][1]-items[j][1]);
	}
	static int getDisBag(int i){
		return (items[i][0]-bag[0])*(items[i][0]-bag[0])+(items[i][1]-bag[1])*(items[i][1]-bag[1]);
	}
	static int getClosest(int i, int mask){
		int ret = -1;
		for(int j = 0;j<n;j++)
			if(i!=j&&(mask&1<<j)==0)
				if(ret==-1||getDis(i, j)<getDis(i, ret))
					ret = j;
		return ret;
	}
	static void trace(int mask){
		if(mask==(1<<n)-1)
			return;

		int ans = (int)1e9;
		for(int i = 0;i<n;i++)
			if((1<<i&mask)==0)
			{
				ans = getDisBag(i)*2+dp(mask|1<<i);
				if(mem[mask]==ans)
				{
					pw.print(0+" "+(i+1)+" ");
					trace(mask|1<<i);
					return;
				}

				for(int j = i+1;j<n;j++)
					if((1<<j&mask)==0)
						if(mem[mask] == getDisBag(i)+getDis(i,j)+getDisBag(j)+dp(mask|1<<i|1<<j))
						{
							pw.print(0+" "+(i+1)+" "+(j+1)+" ");
							trace(mask|1<<i|1<<j);
							return;
						}

			}

	}
	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}

	}
}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class C {

	public static void main(String[] args) {
		//long t = System.currentTimeMillis();
		new C().run();
		//System.out.println(System.currentTimeMillis() - t);
	}

	private void run() {
		Scanner sc = new Scanner(System.in);
		int sx = sc.nextInt();
		int sy = sc.nextInt();
		int n = sc.nextInt();
		int[] x = new int[n];
		int[] y = new int[n];
		for (int i = 0; i < n; i++) {
			x[i] = sc.nextInt();
			y[i] = sc.nextInt();
		}
		sc.close();
		int[] w = new int[n * n];
		int[] pMask = new int[n * n];
		for (int i = 0; i < n; i++) {
			for (int j = i; j < n; j++) {
				int ind = i * n + j;
				if (i == j) {
					w[ind] = 2 * dist(sx, sy, x[i], y[i]);
					pMask[ind] = 1 << i;
				} else {
					w[ind] = dist(sx, sy, x[i], y[i]) + dist(x[i], y[i], x[j], y[j]) + dist(x[j], y[j], sx, sy);
					pMask[ind] = 1 << i | 1 << j;
				}
			}
		}
		int max = 1 << n;
		int[] p = new int[max];
		int[] dist = new int[max];
		Arrays.fill(dist, Integer.MAX_VALUE / 2);
		dist[0] = 0;
		int[] available = new int[n * n];
		for (int mask = 0; mask < max; mask++) {
			int ac = 0;
			for (int i = 0; i < n; i++) {
				if (((mask >> i) & 1) == 0) {
					available[ac++] = i;
				}
			}
			int s = 0;
			//for (int i = 0; i < ac; i++) {
				for (int j = s; j < ac; j++) {
					int a = available[s];
					int b = available[j];
					int ind = a * n + b;
					int nextMask = mask | pMask[ind];
					int newD = dist[mask] + w[ind];
					if (newD < dist[nextMask]) {
						dist[nextMask] = newD;
						//p[nextMask] = a * n + b;
						p[nextMask] = ind;
					}
				}
			//}
		}
		System.out.println(dist[max - 1]);
		ArrayList<Integer> steps = new ArrayList<Integer>();
		int mask = max - 1;
		while (mask > 0) {
			int msk = p[mask];
			steps.add(msk);
			int a = msk / n;
			int b = msk % n;
			if (a == b) {
				mask ^= 1 << a;
			} else {
				mask ^= 1 << a;
				mask ^= 1 << b;
			}
		}
		System.out.print(0);
		for (int i = steps.size() - 1; i >= 0; i--) {
			int msk = steps.get(i);
			int a = msk / n;
			int b = msk % n;
			if (a == b) {
				System.out.printf(" %d 0", a + 1);
			} else {
				System.out.printf(" %d %d 0", a + 1, b + 1);
			}
		}
		System.out.println();
	}

	private int dist(int x1, int y1, int x2, int y2) {
		return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/** Created by huhansan on 2017/10/9. */
public class CF_8C implements Runnable {
  int[] step = new int[1 << 24]; //每个状态所需要的步数
  int[] steplast = new int[1 << 24]; //当前状态上一个
  int n;
  int vs[] = new int[24];
  int vd[][] = new int[24][24];
  int x_bag, y_bag;
  int x[] = new int[24], y[] = new int[24];
  /** */
  private void solve() throws IOException {
    x_bag = nextInt();
    y_bag = nextInt();
    n = nextInt();
    for (int i = 0; i < n; i++) {
      x[i] = nextInt();
      y[i] = nextInt();
    }

    //计算所有物品单取的全值和 任意两件物品一起取的权值
    for (int i = 0; i < n; i++) {
      vs[i] = 2 * ((x[i] - x_bag) * (x[i] - x_bag) + (y[i] - y_bag) * (y[i] - y_bag));
    }
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        vd[i][j] =
            (x[i] - x_bag) * (x[i] - x_bag)
                + (y[i] - y_bag) * (y[i] - y_bag)
                + (x[j] - x_bag) * (x[j] - x_bag)
                + (y[j] - y_bag) * (y[j] - y_bag)
                + (x[i] - x[j]) * (x[i] - x[j])
                + (y[i] - y[j]) * (y[i] - y[j]);
      }
    }

    //记录达到每一个状态所需的最小步数和最后一次取得物品
    for (int i = 1; i < 1 << n; i++) {
      int j, k = 0, l, m, lastState;
      for (j = 1; (i & j) == 0 && j < 1 << n; j <<= 1) {
        k++;
      }
      lastState = i & (~j);
      step[i] = step[lastState] + vs[k];
      steplast[i] = lastState;
      m = k;
      for (l = j << 1; l < 1 << n; l <<= 1) {
        m++;
        if ((lastState & l) != 0) {
          if (step[i] > step[lastState & (~l)] + vd[k][m]) {
            step[i] = step[lastState & (~l)] + vd[k][m];
            steplast[i] = lastState & (~l);
          }
        }
      }
      //      System.out.println(steplast[i]+"---"+i+"---"+step[i]);
    }
    writer.println(step[(1 << n) - 1]);
    int i = (1 << n) - 1;
    writer.print("0 ");
    while (i != 0) {
      for (int j = 1, m = 1; j <= i; j <<= 1, m++) {
        if ((j & (i ^ steplast[i])) != 0) {
          writer.print(m + " ");
        }
      }
      writer.print("0 ");
      i = steplast[i];
    }
  }

  public static void main(String[] args) {
    new CF_8C().run();
  }

  BufferedReader reader;
  StringTokenizer tokenizer;
  PrintWriter writer;

  public void run() {
    try {
      reader = new BufferedReader(new InputStreamReader(System.in));
      tokenizer = null;
      writer = new PrintWriter(System.out);
      solve();
      reader.close();
      writer.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

  long nextLong() throws IOException {
    return Long.parseLong(nextToken());
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  String nextToken() throws IOException {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine());
    }
    return tokenizer.nextToken();
  }
}

import java.util.*;
public class c8 {
    static int n;
    static int[] ds;
    static int[][] g;
public static void main(String[] args)
{
    Scanner input = new Scanner(System.in);
    int x = input.nextInt(), y = input.nextInt();
    int n = input.nextInt();
    int[] xs = new int[n], ys = new int[n];
    for(int i = 0; i<n; i++)
    {
        xs[i] = input.nextInt();
        ys[i] = input.nextInt();
    }
    ds = new int[n];
    g = new int[n][n];
    for(int i = 0; i<n; i++)
    {
        ds[i] = (x - xs[i])  *  (x - xs[i]) + (y - ys[i]) * (y - ys[i]);
        for(int j = 0; j<n; j++)
        {
            g[i][j] = (xs[i] - xs[j]) * (xs[i] - xs[j]) + (ys[i] - ys[j]) * (ys[i] - ys[j]);
        }
    }
    int[] dp = new int[1<<n];
    Arrays.fill(dp, 987654321);
    dp[0] = 0;
    for(int i = 0; i<(1<<n); i++)
    {
        if(dp[i] == 987654321) continue;
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) > 0) continue;
            dp[i | (1<<a)] = Math.min(dp[i | (1<<a)], dp[i] + 2*ds[a]);
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) > 0) continue;
                dp[i | (1<<a) | (1<<b)] = Math.min(dp[i | (1<<a) | (1<<b)], dp[i] + ds[a] + ds[b] + g[a][b]);
            }
            break;
        }
    }
    Stack<Integer> stk = new Stack<Integer>();
    stk.add(0);
    int i = (1<<n) - 1;
    //System.out.println(Arrays.toString(dp));

    trace:
    while(i > 0)
    {
        //System.out.println(i);
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) == 0) continue;
            if( dp[i] == dp[i - (1<<a)] + 2*ds[a])
            {
                stk.add(a+1);
                stk.add(0);
                i -= (1<<a);
                continue trace;
            }
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) == 0) continue;
                if(dp[i] == dp[i - (1<<a) - (1<<b)] + ds[a] + ds[b] + g[a][b])
                {
                    stk.add(a+1);
                    stk.add(b+1);
                    stk.add(0);
                    i -= (1<<a) + (1<<b);
                    continue trace;
                }
            }
            //break;
        }
    }
    System.out.println(dp[(1<<n) - 1]);
    while(!stk.isEmpty()) System.out.print(stk.pop()+" ");
}
}

import java.util.InputMismatchException;
import java.io.*;
import java.util.Vector;
import java.util.Collections;
import java.util.Arrays;

/**
 * Generated by Contest helper plug-in
 * Actual solution is at the bottom
 */
public class Main {
    public static void main(String[] args) {
        InputReader in = new StreamInputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        run(in, out);
    }

    public static void run(InputReader in, PrintWriter out) {
        Solver solver = new Sellerman();
        solver.solve(1, in, out);
        Exit.exit(in, out);
    }
}

class StreamInputReader extends InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar, numChars;

    public StreamInputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    @Override
    public void close() {
        try {
            stream.close();
        } catch (IOException ignored) {
        }
    }
}

abstract class InputReader {
    private boolean finished = false;

    public abstract int read();

    public int nextInt() {
        return Integer.parseInt(nextToken());
    }

    public String nextToken() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }
    private boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public void setFinished(boolean finished) {
        this.finished = finished;
    }

    public abstract void close();
}

interface Solver {
    public void solve(int testNumber, InputReader in, PrintWriter out);
}

class Exit {
    private Exit() {
    }

    public static void exit(InputReader in, PrintWriter out) {
        in.setFinished(true);
        in.close();
        out.close();
    }
}

class Sellerman implements Solver {

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int x0 = in.nextInt();
        int y0 = in.nextInt();
        int n = in.nextInt() + 1;
        int[] x = new int[n];
        int[] y = new int[n];
        x[n - 1] = x0;
        y[n - 1] = y0;
        for (int i = 0; i < n - 1; ++i) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        int [][] g = new int[n][n];
        for(int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j) {
                g[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
            }
        -- n;
        int[] dm = new int[1 << n];
        int[] prev = new int[1 << n];
        byte [] bit = new byte[1 << n];
        byte [] item0 = new byte[1 << n];
        byte [] item1 = new byte[1 << n];
        for (int i = 0; i < n; ++i) {
            bit[1 << i] = (byte) i;
        }
        Arrays.fill(dm, -1);
        dm[0] = 0;
        int tt[][] = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j =0 ; j < n; ++j) {
                tt[i][j] = Math.min(g[n][i] + g[i][j] + g[j][n],
                                    g[n][j] + g[i][j] + g[i][n]);
            }
        for (int i = 0; i < (1 << n); ++i) {
            if (dm[i] == -1)continue;
            int t = (i ^ ((1 << n) - 1));
            int left = bit[t - (t & (t - 1))];
            for (int j = left; j < n; ++j) {
                if ((i & (1 << j)) > 0) continue;
                int nm = i | (1 << left) | (1 << j);
                if (dm[nm] == -1 || dm[nm] > dm[i] + tt[left][j]) {
                    dm[nm] = dm[i] + tt[left][j];
                    prev[nm] = i;
                    item0[nm] = (byte)left;
                    item1[nm] = (byte)j;
                }
            }
        }
        out.println(dm[(1 << n) - 1]);
        Vector<Vector<Integer>> path = new Vector<Vector<Integer>> () ;
        int cmask = (1 << n) - 1;
        while (cmask > 0) {
            int p = prev[cmask];
            Vector<Integer> tmp = new Vector<Integer> () ;
            tmp.add(0);
            tmp.add(item0[cmask] + 1);
            tmp.add(item1[cmask] + 1);
            cmask = prev[cmask];
            path.add(tmp);
        }
        Collections.reverse(path);
        int len = 0;
        for (Vector<Integer> vec : path)
            len += vec.size();
        int ans[] = new int[len];
        boolean[] valid = new boolean[len];
        Arrays.fill(valid, true);
        len = 0;
        for (Vector<Integer> vec : path) {
            for (int ttt : vec) {
                ans[len ++] = ttt;
            }
        }
        for (int i = 0; i < len - 1; ++i) {
            if (ans[i] == ans[i + 1])
                valid[i] = false;
        }
        for (int i = 0; i < len; ++i) {
            if (valid[i]) {
                out.print(ans[i] + " ");
            }
        }
        out.print("0");

    }
}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	void work() {
		int x=in.nextInt(),y=in.nextInt();
		int n=in.nextInt();
		int[][] A=new int[n][2];
		for(int i=0;i<n;i++) {
			A[i]=new int[] {in.nextInt()-x,in.nextInt()-y};
		}
		int[][] dis=new int[n][n];
		for(int i=0;i<n;i++) {
			for(int j=i;j<n;j++) {
				if(i==j) {
					dis[i][i]=A[i][0]*A[i][0]+A[i][1]*A[i][1];
				}else {
					int dx=A[i][0]-A[j][0],dy=A[i][1]-A[j][1];
					dis[i][j]=dx*dx+dy*dy;
					dis[j][i]=dis[i][j];
				}
			}
		}
		int[] dp=new int[1<<n];
		int[][] route=new int[2][1<<n];
		for(int i=0;i<1<<n;i++) {
			route[0][i]=-1;
			route[1][i]=-1;
		}
		Arrays.fill(dp, 999999999);
		dp[0]=0;
		for(int i=0;i<(1<<n)-1;i++) {
			if(dp[i]!=999999999) {
				int b=0;
				for(;(i&(1<<b))>0;b++);
				if(dp[(1<<b)+i]>dp[i]+2*dis[b][b]) {
					dp[(1<<b)+i]=dp[i]+2*dis[b][b];
					route[0][(1<<b)+i]=b;
					route[1][(1<<b)+i]=-1;
				}
				for(int j=b+1;j<n;j++) {
					if(((1<<j)&i)==0) {
						int nm=(1<<b)+(1<<j)+i;
						if(dp[nm]>dp[i]+dis[b][b]+dis[j][j]+dis[b][j]) {
							dp[nm]=dp[i]+dis[b][b]+dis[j][j]+dis[b][j];
							route[0][nm]=b;
							route[1][nm]=j;
						}
					}
				}
			}
		}
		out.println(dp[(1<<n)-1]);
		out.print(0+" ");
		int cur=(1<<n)-1;
		while(cur>0) {
			int s=1<<route[0][cur];
			out.print((route[0][cur]+1)+" ");
			if(route[1][cur]>=0) {
				out.print((route[1][cur]+1)+" ");
				s+=1<<route[1][cur];
			}
			out.print(0+" ");
			cur-=s;
		}
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
    private int[][] distance;
    private int[] dp;
    private int[] prev;

    public static void main(String[] args) throws IOException {
        new LookingForOrder().solve();
    }

    public void solve() throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        int x = Integer.parseInt(tokenizer.nextToken());
        int y = Integer.parseInt(tokenizer.nextToken());
        int n = Integer.parseInt(f.readLine());
        int[][] coords = new int[n + 1][2];
        coords[0][0] = x;
        coords[0][1] = y;
        for (int i = 1; i <= n; i++) {
            tokenizer = new StringTokenizer(f.readLine());
            x = Integer.parseInt(tokenizer.nextToken());
            y = Integer.parseInt(tokenizer.nextToken());
            coords[i][0] = x;
            coords[i][1] = y;
        }

        this.distance = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                distance[i][j] += (coords[i][0] - coords[j][0]) * (coords[i][0] - coords[j][0]);
                distance[i][j] += (coords[i][1] - coords[j][1]) * (coords[i][1] - coords[j][1]);
            }
        }

        int lastSet = 1 << n;
        this.prev = new int[lastSet];

        this.dp = new int[lastSet];
        Arrays.fill(dp, Integer.MAX_VALUE);
        this.dp[0] = 0;
       // this.getMinPath(lastSet);

        for (int i = 1; i < lastSet; i++) {
            /*
            for (int j = 0; j < n; j++) {
                if ((i & (1 << j)) != 0 && this.dp[i ^ (1 << j)] + distance[0][j + 1] * 2 < this.dp[i]) {
                    //System.out.println(Integer.toBinaryString(i) + " " + Integer.toBinaryString(j) + " " + this.dp[i ^ (1 << j)]);
                    this.dp[i] = this.dp[i ^ (1 << j)] + distance[0][j + 1] * 2;
                    this.prev[i] = i ^ (1 << j);
                }
            } */
            //System.out.println(this.dp[i]);
            for (int j = 0; j < n; j++) {
                if ((i & (1 << j)) != 0) {
                    for (int k = j + 1; k < n; k++) {
                        if ((i & (1 << k)) != 0) {
                           // System.out.println(i + " " + j + " " + (i ^ (1 << j) ^ (1 << k)));
                            if (this.dp[i ^ (1 << j) ^ (1 << k)] + this.distance[0][j + 1] + this.distance[0][k + 1] + this.distance[j + 1][k + 1] < this.dp[i]) {
                                this.dp[i] = this.dp[i ^ (1 << j) ^ (1 << k)] + this.distance[0][j + 1] + this.distance[0][k + 1] + this.distance[j + 1][k + 1];
                                this.prev[i] = i ^ (1 << j) ^ (1 << k);
                            }
                        }
                    }

                    if ((i & (1 << j)) != 0 && this.dp[i ^ (1 << j)] + distance[0][j + 1] * 2 < this.dp[i]) {
                        //System.out.println(Integer.toBinaryString(i) + " " + Integer.toBinaryString(j) + " " + this.dp[i ^ (1 << j)]);
                        this.dp[i] = this.dp[i ^ (1 << j)] + distance[0][j + 1] * 2;
                        this.prev[i] = i ^ (1 << j);
                    }
                    break;
                }
            }
          //  System.out.println(this.dp[i]);
        }

        lastSet--;
        PrintWriter out = new PrintWriter(System.out);
        out.println(dp[lastSet]);
        ArrayDeque<Integer> stack = new ArrayDeque<Integer>();
        boolean started = false;
        while (lastSet != 0) {
            // System.out.println(lastSet);
            stack.addFirst(0);
            int diff = lastSet - prev[lastSet];
            //System.out.println(diff);
            for (int i = 1, j = 1; j <= n; j++, i *= 2) {
                if ((diff & i) != 0) {
                    stack.addFirst(j);
                }
            }

            lastSet = this.prev[lastSet];
        }
        stack.addFirst(0);

        while (!stack.isEmpty()) {
            if (!started) {
                out.print(stack.pop());
                started = true;
            } else {
                out.print(" ");
                out.print(stack.pop());
            }
        }

        out.println();
        out.close();
    }

    /*
    private int getMinPath(int set) {
        if (this.dp[set] != Integer.MAX_VALUE) {
            return this.dp[set];
        }

        for (int i = 1, j = 1; i < this.dp.length; i *= 2, j++) {
            if ((set & i) == i) {
                int subPath;
                int possibleMin = getMinPath(set & (set - i)) + (this.distance[0][j] * 2);
                if (possibleMin < this.dp[set]) {
                    this.dp[set] = possibleMin;
                    this.prev[set] = set - i;
                }
            }
        }
        for (int i0 = 1, j0 = 1; i0 < this.dp.length; i0 *= 2, j0++) {
            if ((set & i0) == i0) {
                for (int i1 = i0 * 2, j1 = j0 + 1; i1 < this.dp.length; i1 *= 2, j1++) {
                    if ((set & i1) == i1) {
                        //System.out.println(set + " " + (set & (set - i0 - i1)));
                        int possibleMin = getMinPath(set & (set - i0 - i1)) + this.distance[0][j0] + this.distance[0][j1] + this.distance[j0][j1];
                        if (possibleMin < this.dp[set]) {
                            this.dp[set] = possibleMin;
                            this.prev[set] = set - i0 - i1;
                        }
                    }
                }
                break;
            }
        }

        // System.out.println(this.dp[set] + " " + Integer.toBinaryString(set));
        return this.dp[set];
    } */
}

import java.util.Scanner;

public class C {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int xs = sc.nextInt();
		int ys = sc.nextInt();
		int n = sc.nextInt();
		int[]x = new int[n], y = new int[n];
		for (int i = 0; i < n; i++) {
			x[i] = sc.nextInt();
			y[i] = sc.nextInt();
		}
		int[]single = new int[n];
		int[][]pair = new int[n][n];
		for (int i = 0; i < n; i++) {
			single[i] = 2*((x[i]-xs)*(x[i]-xs)+(y[i]-ys)*(y[i]-ys));
		}
		for (int i = 0; i < n; i++) {
			for (int j = i+1; j < n; j++) {
				pair[i][j] = (x[i]-xs)*(x[i]-xs)+(y[i]-ys)*(y[i]-ys)+(x[j]-xs)*(x[j]-xs)+(y[j]-ys)*(y[j]-ys)+(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
			}
		}
		int[]best = new int[1 << n], prev = new int[1 << n];
		for (int mask = 1; mask < (1 << n); mask++) {
			int i = 0;
			while ((mask & (1 << i))==0)
				i++;
			best[mask] = best[mask ^ (1 << i)]+single[i];
			prev[mask] = i+1;
			for (int j = i+1; j < n; j++) {
				if ((mask & (1 << j)) != 0) {
					int temp = best[mask ^ (1 << i) ^ (1 << j)]+pair[i][j];
					if (temp < best[mask]) {
						best[mask] = temp;
						prev[mask] = (i+1)*100+(j+1);
					}
				}
			}
		}
		System.out.println(best[(1 << n) - 1]);
		System.out.print("0 ");
		int cur = (1 << n) - 1;
		while (cur > 0) {
			int a = prev[cur]  % 100;
			int b = prev[cur] / 100;
			if (a > 0) {
				System.out.print(a+" ");
				cur ^= 1 << (a-1);
			}
			if (b > 0) {
				System.out.print(b+" ");
				cur ^= 1 << (b-1);
			}
			System.out.print(0+" ");
		}
	}
}

import java.util.*;
import java.io.*;

public class C0008 {

    public static void main(String args[]) throws Exception {
        new C0008();
    }

    int n;
    int target;
    int dp[];
    int next[];
    int dist[][];

    C0008() throws Exception {
        PandaScanner sc = null;
        PrintWriter out = null;
        try {
            sc = new PandaScanner(System.in);
            out = new PrintWriter(System.out);
        } catch (Exception ignored) {
        }

        dist = new int[26][26];
        int[][] p = new int[26][];
        p[25] = new int[] {sc.nextInt(), sc.nextInt()};
        n = sc.nextInt();
        target = (1 << n) - 1;

        for (int i = 0; i < n; i++) {
            p[i] = new int[] {sc.nextInt(), sc.nextInt()};
            dist[i][25] = getDist(p[i], p[25]);
            for (int j = 0; j < i; j++) {
                dist[j][i] = getDist(p[j], p[i]);
            }
        }

        next = new int[1 << n];

        dp = new int[1 << n];
        Arrays.fill(dp, -1);

        out.println(go(0));

        ArrayList<Integer> paths = new ArrayList<Integer>();
        paths.add(0);
        int curr = 0;
        while (curr != target) {
            for (Integer i: getBits(next[curr], true)) {
                paths.add(i + 1);
            }
            paths.add(0);
            curr |= next[curr];
        }
        out.println(paths.toString().replaceAll("[^ 0-9]", ""));

        out.close();
        System.exit(0);
    }

    int go(int mask) {
        if (mask == target) {
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }

        ArrayList<Integer> notDone = getBits(mask, false);

        dp[mask] = Integer.MAX_VALUE;

        for (Integer i: notDone) {
            if (dp[mask] > (dist[i][25] << 1) + go(mask | (1 << i))) {
                dp[mask] = (dist[i][25] << 1) + go(mask | (1 << i));
                next[mask] = 1 << i;
            }
            for (Integer j: notDone) {
                if (j == i) break;
                if (dp[mask] > (dist[j][25] + dist[j][i] + dist[i][25]) + go(mask | (1 << i) | (i << j))) {
                    dp[mask] = (dist[j][25] + dist[j][i] + dist[i][25]) + go(mask | (1 << i) | (i << j));
                    next[mask] = (1 << i) | (1 << j);
                }
            }
        }

        return dp[mask];
    }

    int getDist(int[] p1, int[] p2) {
        return sq(p1[0] - p2[0]) + sq(p1[1] - p2[1]);
    }

    int sq(int a) {
        return a * a;
    }

    ArrayList<Integer> getBits(int mask, boolean on) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            if (((mask & (1 << i)) == 0) ^ on) {
                res.add(i);
            }
        }
        return res;
    }

    //The PandaScanner class, for Panda fast scanning!
    public class PandaScanner {
        BufferedReader br;
        StringTokenizer st;
        InputStream in;

        PandaScanner(InputStream in) throws Exception {
            br = new BufferedReader(new InputStreamReader(this.in = in));
        }

        public String next() throws Exception {
            if (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(br.readLine().trim());
                return next();
            }
            return st.nextToken();
        }

        public boolean hasNext() throws Exception {
            return (st != null && st.hasMoreTokens()) || in.available() > 0;
        }

        public long nextLong() throws Exception {
            return Long.parseLong(next());
        }

        public int nextInt() throws Exception {
            return Integer.parseInt(next());
        }
    }
}

import java.util.*;
import java.io.*;

public class Main{

    BufferedReader in;
    StringTokenizer str = null;
    PrintWriter out;

    private String next() throws Exception{
    	if (str == null || !str.hasMoreElements())
    	    str = new StringTokenizer(in.readLine());
    	return str.nextToken();
    }

    private int nextInt() throws Exception{
	   return Integer.parseInt(next());
    }

    int []x,y;
    int n;
    int []dp, prev;

    public void run() throws Exception{
    	in = new BufferedReader(new InputStreamReader(System.in));
    	out = new PrintWriter(System.out);

    	int xs = nextInt();
    	int ys = nextInt();
    	n = nextInt();
    	x = new int[n];
    	y = new int[n];
    	for(int i=0;i<n;i++){
    		x[i] = nextInt();
    		y[i] = nextInt();
    	}

    	int one[] = new int[n];
    	for(int i=0;i<n;i++){
    		one[i] = dist(xs, ys, x[i], y[i]);
    	}

    	int two[][] = new int[n][n];
    	for(int i=0;i<n;i++){
    		for(int j=i+1;j<n;j++){
    			two[i][j] = two[j][i] = dist(xs, ys, x[i], y[i]) + dist(x[i], y[i], x[j], y[j]) + dist(xs, ys, x[j], y[j]);
    		}
    	}

    	dp = new int[1<<n];
    	Arrays.fill(dp, Integer.MAX_VALUE/2);
    	dp[0] = 0;
    	prev = new int[1<<n];
    	Arrays.fill(prev, -1);

    	for(int mask=1;mask<(1<<n);mask++){
    		int i = 0;
    		while((mask & (1<<i)) == 0) i++;
    		dp[mask] = dp[mask ^ (1<<i)] + 2*one[i];
    		prev[mask] = i+1;
    		for(int j=i+1;j<n;j++){
    			if ((mask & (1<<j)) > 0) {
    				if (dp[mask] > dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j]) {
    					dp[mask] = dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j];
    					prev[mask] = 100 * (i+1) + (j+1);
    				}
    			}
    		}
    	}

    	out.println(dp[(1<<n)-1]);
    	out.print(0 + " ");
    	int cur = (1<<n)-1;
    	while(cur > 0) {
    		int i = prev[cur]/100;
    		int j = prev[cur]%100;

    		if (i > 0) {
    			cur^=1<<(i-1);
    			out.print(i + " ");
    		}

    		if (j > 0) {
    			cur^=1<<(j-1);
    			out.print(j + " ");
    		}
    	}
    	out.println(0);
		out.close();
    }

    private String bit2str(int mask, int n) {
    	String s = "";
    	for(int i=0;i<n;i++){
    		if ((mask & (1<<i)) > 0){
    			s+="1";
    		}else{
    			s+="0";
    		}
    	}
    	while(s.length() < n)
    		s+="0";

    	return new StringBuilder(s).reverse().toString();
    }

    private int dist(int x1, int y1, int x2, int y2) {
    	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    }

    public static void main(String args[]) throws Exception{
	   new Main().run();
    }
}

import java.util.*;
import java.io.*;

public class P8C {

  private static void solve() {

    int[] b = new int[] {nextInt(), nextInt()};

    int n = nextInt();

    int[][] items = new int[n][2];

    for (int i = 0; i < n; i++) {
      items[i][0] = nextInt();
      items[i][1] = nextInt();
    }

    int[] one = new int[n];

    for (int i = 0; i < n; i++) {
      one[i] = dist(b, items[i]) * 2;
    }

    int[][] two = new int[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        two[i][j] = dist(b, items[i]) + dist(items[i], items[j]) + dist(items[j], b);

      }
    }

    int[] dp = new int[1 << n];
    int[] bt1 = new int[1 << n];
    int[] bt2 = new int[1 << n];
    int[] bt3 = new int[1 << n];
    Arrays.fill(dp, -1);
    dp[0] = 0;
    System.out.println(rec((1 << n) - 1, one, two, n, dp, bt1, bt2, bt3));

    int start = (1 << n) - 1;

    while (start != 0) {
      System.out.print("0 " + bt2[start] + " " + (bt3[start] == -1 ? "" : bt3[start] + " "));
      start = bt1[start];
    }
    System.out.println("0");
  }

  private static int rec(int rem, int[] one, int[][] two, int n, int[] dp, int[] bt1, int[] bt2, int[] bt3) {
    if (dp[rem] != -1) return dp[rem];
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < n; i++) {
      if ((rem & (1 << i)) != 0) {
        int next = rem & ~(1 << i);
        int local = one[i] + rec(next, one, two, n, dp, bt1, bt2, bt3);
        int bt1_local = next;
        int bt2_local = i;
        int bt3_local = -1;

        for (int j = i + 1; j < n; j++) {
          if ((rem & (1 << j)) != 0) {
            int next2 = rem & ~((1 << i) | (1 << j));
            int ans2 = two[i][j] + rec(next2, one, two, n, dp, bt1, bt2, bt3);
            if (local > ans2) {
              local = ans2;
              bt1_local = next2;
              bt2_local = i + 1;
              bt3_local = j + 1;
            }
          }
        }

        if (min > local) {
          min = local;
          bt1[rem] = bt1_local;
          bt2[rem] = bt2_local;
          bt3[rem] = bt3_local;
        }
        break;
      }
    }

    return (dp[rem] = min);
  }

  private static int dist(int[] f, int[] s) {
    int dx = f[0] - s[0];
    int dy = f[1] - s[1];
    return dx * dx + dy * dy;
  }

  private static void run() {
    br = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out);

    solve();

    out.close();
  }

  private static StringTokenizer st;
  private static BufferedReader br;
  private static PrintWriter out;

  private static String next() {
    while (st == null || !st.hasMoreElements()) {
      String s;
      try {
        s = br.readLine();
      } catch (IOException e) {
        return null;
      }
      st = new StringTokenizer(s);
    }
    return st.nextToken();
  }

  private static int nextInt() {
    return Integer.parseInt(next());
  }

  private static long nextLong() {
    return Long.parseLong(next());
  }

  public static void main(String[] args) {
    run();
  }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp, p;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = 99999999;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				int tmp = 2 * dist(0, i) + solve(mask | (1 << i));
				if (tmp < ans) {
					ans = tmp;
					p[mask] = -i;
				}
			}
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				for (int j = 1; j < n; j++)
					if (i != j && (mask & (1 << j)) == 0) {
						int tmp = dist(0, i) + dist(i, j) + dist(j, 0)
								+ solve(mask | (1 << i) | (1 << j));
						if (tmp < ans) {
							ans = tmp;
							p[mask] = i;
							p[mask | (1 << i)] = -j;
						}
					}
			}
		return dp[mask] = ans;
	}

	public static void main(String[] args) throws IOException {
		PrintWriter out = new PrintWriter(System.out);
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		p = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		int mask = 1 << 0;
		out.print(0);
		while (mask != (1 << n) - 1) {
			out.print(" " + Math.abs(p[mask]));
			if (p[mask] < 0)
				out.print(" 0");
			mask |= (1 << Math.abs(p[mask]));
		}
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class B {
    static int[][] dist;
    static int [] dp;
    static int [] path;
    static int end,x,y;
    static Point[] a;
    public static int doit(int mask) {
        if(mask==end) return 0;
        if(dp[mask]!=-1) return dp[mask];
        int min=Integer.MAX_VALUE;
        boolean found=false;
        int t;
        for(int i=0;i<dist.length;i++) {
            if(((1<<i)|mask)==mask) continue;
            for(int j=i+1;j<dist.length;j++) {
                if(((1<<j)|mask)==mask) continue;
                found=true;
                t=dist[i][j]+doit(mask|(1<<i)|(1<<j));
                if(t<min) {
                    min=t;
                    path[mask]=(1<<i)|(1<<j);
                }
            }
            if(!found) {
                path[mask]=1<<i;
                return dp[mask]=2*((a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y));
            }
        }
        return dp[mask]=min;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
         x=sc.nextInt();y=sc.nextInt();
         a=new Point[sc.nextInt()];
        for(int i=0;i<a.length;i++) {
            a[i]=new Point(sc.nextInt(), sc.nextInt());
        }
        end=(1<<a.length)-1;
        dp=new int[1<<a.length];
        Arrays.fill(dp, -1);
        dist=new int[a.length][a.length];
        for(int i=0;i<a.length;i++) {
            for(int j=i+1;j<a.length;j++) {
                dist[i][j]=(a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y) +
                (a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+
                (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                //System.out.println(dist[i][j]);
            }
        }
        path=new int[dp.length];
        System.out.println(doit(0));
        int e=(int) Math.ceil(a.length/2.0);
        int cur=path[0];
        StringBuffer bf=new StringBuffer();
        bf.append(0+" ");
        for(int i=0;i<e;i++) {
            //System.out.println(Integer.toBinaryString(cur));
            for(int j=0;j<a.length;j++) {
                if(((1<<j)|cur)==cur) {
                    bf.append((j+1)+" ");
                }
            }
            cur=path[cur];
            bf.append(0+" ");
        }
        System.out.println(bf);
    }
}

import java.io.*;
import java.util.*;

public class Solution {
    BufferedReader in;
    StringTokenizer st;
    PrintWriter out;

    public Solution() throws Exception {
	in = new BufferedReader(new InputStreamReader(System.in));
	out = new PrintWriter(System.out);
    }

    public String next() throws Exception {
	if (st == null || !st.hasMoreTokens()) {
	    st = new StringTokenizer(in.readLine());
	}
	return st.nextToken();
    }

    public int nextInt() throws Exception {
	return Integer.parseInt(next());
    }

    public long nextLong() throws Exception {
	return Long.parseLong(next());

    }

    public double nextDouble() throws Exception {
	return Double.parseDouble(next());
    }

    public static void main(String[] args) throws Exception {
	new Solution().run(args);
    }

    public int dist(int x0, int y0, int x1, int y1) {
	return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
    }

    public void run(String[] args) throws Exception {
	int x0 = nextInt();
	int y0 = nextInt();
	int n = nextInt();
	int[] x = new int[n];
	int[] y = new int[n];
	for (int i = 0; i < n; ++i) {
	    x[i] = nextInt();
	    y[i] = nextInt();
	}
	if (n == 1) {
	    int d = dist(x0, y0, x[0], y[0]);
	    out.println(d * 2);
	    out.println("0 1 0");
	    out.close();
	    return;
 	}
	if (n == 2) {
	    int d1 = dist(x0, y0, x[0], y[0]);
	    int d2 = dist(x0, y0, x[1], y[1]);
	    int d3 = dist(x[0], y[0], x[1], y[1]);
	    out.println(d1 + d2 + d3);
	    out.println("0 1 2 0");
	    out.close();
	    return;
 	}

	Queue<State> q = new LinkedList<State>();
	State[] states = new State[(1 << n)];
	LinkedList<Integer> p = new LinkedList<Integer>();
	p.add(0);
	q.add(new State(0, p, 0));

	while(!q.isEmpty()) {
	    State st = q.poll();
	    for (int i = 0; i < n; ++i) {
		if ((st.v & (1 << i)) == 0) {
		    int v = st.v | (1 << i);
		    int d = dist(x0, y0, x[i], y[i]);
		    int c = st.c + d * 2;
		    if (states[v] == null || states[v].c > c) {
			LinkedList<Integer> path = new LinkedList(st.path);
			path.add(i + 1);
			path.add(0);
			State newState = new State(v, path, c);
			if (states[v] == null) q.add(newState);
			states[v] = newState;

		    }
		}
	    }
	    for (int i = 0; i < n; ++i) {
		for (int j = i + 1; j < n; ++j) {
		    if ((st.v & (1 << i)) == 0 && (st.v & (1 << j)) == 0) {
			int v = st.v | (1 << i) | (1 << j);
			int d1 = dist(x0, y0, x[i], y[i]);
			int d2 = dist(x0, y0, x[j], y[j]);
			int d3 = dist(x[i], y[i], x[j], y[j]);
			int c = st.c + d1 + d2 + d3;
			if (states[v] == null || states[v].c > c) {
			    LinkedList<Integer> path = new LinkedList(st.path);
			    path.add(i + 1);
			    path.add(j + 1);
			    path.add(0);
			    State newState = new State(v, path, c);
			    if (states[v] == null) q.add(newState);
			    states[v] = newState;
			}
		    }
		}
	    }

	}
	int v = (1 << n) - 1;
	out.println(states[v].c);
	out.print(states[v].path.pollFirst());
	while(!states[v].path.isEmpty()) {
	    out.print(" " + states[v].path.pollFirst());
	}
	in.close();
	out.close();
    }

    class State implements Comparable <State> {
	int v;
	LinkedList<Integer> path;
	int c;

	public State(int v, LinkedList<Integer> path, int c) {
	    this.v = v;
	    this.path = path;
	    this.c = c;
	}

	public int compareTo(State s) {
	    return Integer.compare(this.c, s.c);
	}
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 111118315581
 *
 * @author pttrung
 */
public class C {

    static Point hand;
    static int n;
    static Point[] data;
    static int[] next;
    static int[] dp;
    static int[][] pre;

    public static void main(String[] args) {
        Scanner in = new Scanner();
        PrintWriter out = new PrintWriter(System.out);
        // System.out.println(1 << 24);
        hand = new Point(in.nextInt(), in.nextInt());
        n = in.nextInt();
        data = new Point[n];
        for (int i = 0; i < n; i++) {
            data[i] = new Point(in.nextInt(), in.nextInt());
        }
        pre = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                pre[i][j] = distance(data[i], data[j]);
            }
        }

        next = new int[1 << n];
        dp = new int[1 << n];
        Arrays.fill(dp, -1);
        if (n % 2 == 0) {
            out.println(cal(0));
        }else{
            int result = Integer.MAX_VALUE;
            for(int i = 0; i < n; i++){
                int temp = cal(1<<i);
                if(temp < result){
                    next[0] = 1<<i;
                    result = temp;
                }

            }
            out.println(result);
        }
        int start = 0;

        do {
            int m = next[start];
            int val = m - start;
            out.print(0 + " ");
            for (int i = 0; i < n; i++) {
                if (((1 << i) & val) != 0) {
                    out.print((i + 1) + " ");
                }
            }
            // out.print(0 + " ")  ;
            start = m;
        } while (start != (1 << n) - 1);
        out.println(0);
        out.close();
    }

    public static int cal(int mask) {
        if ((1 << n) - 1 == mask) {
            //  System.out.println(mask);
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (((1 << i) & mask) == 0) {
                int dist = distance(hand, data[i]);
                for (int j = i + 1; j < n; j++) {
                    if (((1 << j) & mask) == 0) {
                        //System.out.println(i + " " + j);
                        int temp = dist + distance(hand, data[j]) + pre[i][j] + cal(mask | (1 << i) | (1 << j));
                        //System.out.println(temp);
                        if (temp < result) {
                            result = temp;
                            next[mask] = (mask | (1 << i) | (1 << j));
                        }

                    }
                }
            }

        }
        dp[mask] = result;
        return result;
    }

    static int distance(Point a, Point b) {
        int total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return total;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}

import java.io.*;
import java.util.*;

public class Solution {
    BufferedReader in;
    StringTokenizer st;
    PrintWriter out;

    public Solution() throws Exception {
	in = new BufferedReader(new InputStreamReader(System.in));
	out = new PrintWriter(System.out);
    }

    public String next() throws Exception {
	if (st == null || !st.hasMoreTokens()) {
	    st = new StringTokenizer(in.readLine());
	}
	return st.nextToken();
    }

    public int nextInt() throws Exception {
	return Integer.parseInt(next());
    }

    public long nextLong() throws Exception {
	return Long.parseLong(next());

    }

    public double nextDouble() throws Exception {
	return Double.parseDouble(next());
    }

    public static void main(String[] args) throws Exception {
	new Solution().run(args);
    }

    public int dist(int x0, int y0, int x1, int y1) {
	return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
    }

    public void run(String[] args) throws Exception {
	int x0 = nextInt();
	int y0 = nextInt();
	int n = nextInt();
	int[] x = new int[n];
	int[] y = new int[n];
	int[][] d = new int[n + 1][n + 1];
	for (int i = 0; i < n; ++i) {
	    x[i] = nextInt();
	    y[i] = nextInt();
	}

	for (int i = 0; i < n; ++i) {
	    for (int j = i; j < n; ++j) {
	    	d[i + 1][j + 1] = d[j + 1][i + 1] = dist(x[i], y[i], x[j], y[j]);
		d[i + 1][0] = d[0][i + 1] = dist(x0, y0, x[i], y[i]);
	    	d[0][j + 1] = d[j + 1][0] = dist(x0, y0, x[j], y[j]);
	    }
	}

	int[] s = new int[(1 << n)];
	int[] path = new int[(1 << n)];
	Arrays.fill(s, Integer.MAX_VALUE / 2);
	s[0] = 0;
	for (int mask = 0; mask < (1 << n); ++mask) {
	    for (int i = 0; i < n; ++i) {
		if ((mask & (1 << i)) == 0) {
		    for (int j = i; j < n; ++j) {
			if ((mask & (1 << j)) == 0) {
			    int newmask = mask | (1 << i) | (1 << j);
			    if (s[newmask] > s[mask] + d[0][i + 1] + d[i + 1][j + 1] + d[0][j + 1]) {
				s[newmask] = s[mask] + d[0][i + 1] + d[i + 1][j + 1] + d[0][j + 1];
				path[newmask] = mask;
				out.println(s[newmask]);
			    }
			}
		    }
		}
	    }
	}
	int f = (1 << n) - 1;
	out.println(s[f]);
	LinkedList<Integer> p = new LinkedList<Integer>();
	p.add(0);
	while(f != 0) {
	    int pf = f ^ path[f];
	    for (int i = 0; i < n; ++i) {
		if (((pf >> (i)) & 1) == 1) {
		    p.add(i + 1);
		}
	    }
	    p.add(0);
	    f = path[f];
	}
	out.print(p.pollLast());
	while(!p.isEmpty()) {
	    out.print(" " + p.pollLast());
	}
	out.println();
	in.close();
	out.close();
    }

}

import java.io.*;
import java.util.*;

public class CF8C
{
	static final boolean _DEBUG = true;

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner(BufferedReader _br) {
			br = _br;
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					e.printStackTrace();
					return "";
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	static MyScanner   scan;
	static PrintWriter out;

	static int debugCount = 0;
	static void debug(String msg) {
		if (_DEBUG && debugCount < 200) {
			out.println(msg);
			out.flush();
			debugCount++;
		}
	}

	static final int INF = Integer.MAX_VALUE >> 1;

    public static void main (String args[]) throws IOException {
//    	scan = new MyScanner(new BufferedReader(new FileReader("test.in")));
    	scan = new MyScanner(new BufferedReader(new InputStreamReader(System.in)));
    	out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        CF8C inst = new CF8C();
        inst.execute();
        out.close();
    }

    int dp[];
    int p[];
    int x[];
    int y[];
    int[][] dist;
    int n;

    void backtrack() {
    	int last = (1 << n) - 1;
    	out.print(0);
    	while (last != 0) {
    		int t = p[last];
    		for (int i = 0; i < n; i++) {
    			if ((t & (1 << i)) != 0) {
    				out.print(" " + (i+1));
    				for (int j = i + 1; j < n; j++) {
    	    			if ((t & (1 << j)) != 0) {
    	    				out.print(" " + (j+1));
    	    				break;
    	    			}
    				}
    				break;
    			}
    		}
    		out.print(" 0");
    		last ^= t;
    	}
    	out.println();
    }

    void execute() throws IOException {
    	int rootx = scan.nextInt();
    	int rooty = scan.nextInt();
    	n = scan.nextInt();
        int x[] = new int[n+1];
        int y[] = new int[n+1];
        int[][] dist = new int[n+1][n+1];
        for(int i = 0; i < n; i++) {
    		x[i] = scan.nextInt();
    		y[i] = scan.nextInt();
    	}
    	x[n] = rootx;
    	y[n] = rooty;
    	for (int i = 0; i <= n; i++) {
    		for (int j = 0; j <= n; j++) {
    			int dx = x[i] - x[j];
    			int dy = y[i] - y[j];
    			dist[i][j] = dx * dx + dy * dy;
    		}
    	}
    	dp = new int[1<<n];
    	p = new int[1<<n];
    	Arrays.fill(dp, INF);
//    	Arrays.fill(p, -1);
    	dp[0] = 0;
    	p[0] = -1;

    	int last = (1 << n) - 1;
    	for(int i = 1; i <= last; i++) {
    		int first = 0;
    		for (; first < n; first++) {
    			if ((i & (1 << first)) != 0) break;
    		}
    		int temp = dp[i ^ (1 << first)] + dist[n][first] * 2;
    		if (temp < dp[i]) {
    			dp[i] = temp;
    			p[i] = 1 << first;
    		}
    		int second = first + 1;
    		for (; second < n; second++) {
    			if ((i & (1 << second)) != 0) break;
    		}
    		if (second != n) {
    			int s2 = (1 << first) | ( 1 << second);
    			temp = dp[i ^ s2] + dist[n][first] + dist[first][second] + dist[second][n];
    			if (temp < dp[i]) {
    				dp[i] = temp;
    				p[i] = s2;
    			}
    		}
    	}
    	out.println(dp[last]);
    	backtrack();
    }
}

import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {
	int INF = Integer.MAX_VALUE >> 1;

	public static void main(String[] args) throws IOException {
		try {
			if (new File("input.txt").exists()) {
				System.setIn(new FileInputStream("input.txt"));
			}
		} catch (SecurityException e) {
		}

		new Main().run();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	int n;
	int[][] dt;

	int nh;
	int[] match;
	boolean[] used;

	int xs;
	int ys;
	Point[] p;

	int min = INF;
	int[] ans = new int [24];
	int md;

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		xs = nextInt();
		ys = nextInt();
		n = nextInt();

		boolean odd = false;

		if (n % 2 == 1) {
			n++;
			odd = true;
		}

		dt = new int [n][n];
		p = new Point [n];

		for (int i = 0; odd ? (i < n - 1) : (i < n); i++) {
			p[i] = new Point(nextInt(), nextInt());
		}

		if (odd) {
			p[n - 1] = new Point(1000, 1000);
		}

		sort(p);

		int sz = 0;
		int[] ad = new int [n * n];

		for (int i = 0; odd ? (i < n - 1) : (i < n); i++) {
			for (int j = 0; j < i; j++) {
				dt[i][j] = dt[j][i] = d(p[i].x, p[i].y, p[j].x, p[j].y) + p[i].ds + p[j].ds;
				ad[sz++] = dt[i][j];
			}

			if (odd) {
				dt[i][n - 1] = dt[n - 1][i] = 2 * p[i].ds;
			}
		}

		sort(ad, 0, sz);
		md = ad[2 * sz / 3];

//		for (int i = 0; i < n; i++) {
//			System.out.println(Arrays.toString(dt[i]));
//		}

		nh = n / 2;
		match = new int [nh];
		used = new boolean [nh];
		dfs(0);

		out.println(min);
		out.print("0");

		for (int i = 0; i < nh; i++) {
			out.print(" ");
			if (odd && match[i] == n - 1) {
				out.print((i + 1) + " 0");
			} else {
				out.print((i + 1) + " " + (match[i] + 1) + " 0");
			}
		}

		out.println();
		out.close();
	}

	void dfs(int v) {
		if (v == nh) {
			update();
		} else {
			for (int i = 0; i < nh; i++) {
				if (!used[i]) {
					used[i] = true;
					match[v] = i + nh;
					dfs(v + 1);
					used[i] = false;
				}
			}
		}
	}

	void update() {
		int clen = 0;

//		System.out.println(Arrays.toString(match));

		for (int i = 0; i < nh; i++) {
			clen += dt[i][match[i]];
		}

//		System.out.println(clen);

		if (min > clen) {
			min = clen;

			for (int i = 0; i < nh; i++) {
				ans[i] = match[i];
			}
		}

	}

	int d(int x1, int y1, int x2, int y2) {
		return sqr(x2 - x1) + sqr(y2 - y1);
	}

	int sqr(int x) {
		return x * x;
	}

	class Point implements Comparable<Point> {
		int x, y, ds;

		Point(int xx, int yy) {
			x = xx;
			y = yy;
			ds = d(x, y, xs, ys);
		}

		@Override
		public int compareTo(Point p) {
			if (ds == p.ds)
				return 0;
			return ds - p.ds;
		}
	}

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}

		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();

			if (s == null) {
				return true;
			}

			st = new StringTokenizer(s);
		}

		return false;
	}
}

import java.io.*;
import static java.lang.Math.*;
import java.util.*;
import java.util.function.*;
import java.lang.*;

public class Main {
    final static boolean debug = false;
    final static String fileName = "";
    final static boolean useFiles = false;

    public static void main(String[] args) throws FileNotFoundException {
        long start;
        if (debug)
            start = System.nanoTime();
        InputStream inputStream;
        OutputStream outputStream;
        if (useFiles) {
            inputStream = new FileInputStream(fileName + ".in");
            outputStream = new FileOutputStream(fileName + ".out");
        } else {
            inputStream = System.in;
            outputStream = System.out;
        }
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task(in, out);
        solver.solve();
        if(debug)
            out.println((System.nanoTime() - start) / 1e+9);
        out.close();
    }
}
class Task {
    int[] x, y;
    int xs, ys;
    int n;
    int dist(int i, int j) {
        return (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
    }
    void go(int[] prev, String[] leafDescription, int[] d, int len, int add, String description){
        for (int mask = 0; mask < d.length; mask++) {
            int newValue = d[mask & (~add)] + len;
            if (d[mask] > newValue){
                d[mask] = newValue;
                leafDescription[mask] = description;
                prev[mask] = mask & (~add);
            }
        }
    }
    public void solve() {
        final int inf = (int) 1e+9;
        xs = in.nextInt();
        ys = in.nextInt();

        n = in.nextInt();
        x = new int[n + 1];
        y = new int[n + 1];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        x[n] = xs;
        y[n] = ys;
        int[] d = new int[1 << n];
        int[] prev = new int[1 << n];
        String[] leafDescription = new String[1 << n];
        Arrays.fill(d, inf);
        prev[0] = 0;
        d[0] = 0;
        for (int i = 0; i < n; i++) {
            int add = 1 << i;
            int len = 2 * dist(n, i);
            String description = (i + 1) + " ";

            go(prev, leafDescription, d, len, add, description);
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int add = (1 << i) | (1 << j);
                int len = dist(n, i) + dist(i, j) + dist(n, j);
                String description = (i + 1) + " " + (j + 1) + " ";

                go(prev, leafDescription, d, len, add, description);
            }
        }
//        Debug.printObjects(out, d);
//        Debug.printObjects(out, prev);
//        Debug.printObjects(out, leafDescription);
        int result = d[d.length - 1];
        String answer = "";
        for (int curr = d.length - 1; prev[curr] != curr; curr = prev[curr] ){
            answer += "0 " + leafDescription[curr];
        }
        answer += "0";
        out.println(result);
        out.println(answer);
    }

    private InputReader in;
    private PrintWriter out;

    Task(InputReader in, PrintWriter out) {
        this.in = in;
        this.out = out;
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public double nextDouble(){
        return Double.parseDouble(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong(){
        return Long.parseLong(next());
    }

    public byte nextByte(){
        return Byte.parseByte(next());
    }
}

import java.io.*;
import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {
	public static void main(String[] args) throws IOException {
		new Thread(null, new Runnable() {
			public void run() {
				try {
					try {
						if (new File("input.txt").exists())
							System.setIn(new FileInputStream("input.txt"));
					} catch (SecurityException e) {}
					new Main().run();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 24).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	int INF = Integer.MAX_VALUE >> 1;

	int N;
	int HN;
	int FULL;

	int[] xs = new int [24];
	int[] ys = new int [24];

	int[][] dist;

	int best = INF;
	int[] pairs;
	int[] answer;

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		int x0 = nextInt();
		int y0 = nextInt();

		N = nextInt();
		boolean odd = N % 2 == 1;
		for (int i = 0; i < N; i++) {
			xs[i] = nextInt();
			ys[i] = nextInt();
		}

		if (N % 2 == 1) {
			xs[N] = x0;
			ys[N] = y0;
			N++;
		}

		dist = new int [N][N];
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
				dist[i][j] = dist(x0, y0, xs[i], ys[i]) + dist(xs[i], ys[i], xs[j], ys[j]) + dist(xs[j], ys[j], x0, y0);

		HN = N / 2;
		FULL = (1 << N) - 1;
		pairs = new int [HN];
		answer = new int [HN];
		rec(0, 0, 0);

		out.println(best);
		out.print("0");

		for (int p = 0; p < HN; p++) {
			int u = answer[p] / N + 1;
			int v = answer[p] % N + 1;
			out.print(" " + u);
			if (!(odd && v == N)) out.print(" " + v);
			out.print(" 0");
		}
		out.println();

		out.close();
	}

	void rec(int mask, int sum, int p) {
		if (sum >= best) return;
		if (mask == FULL) {
			update(sum);
		} else {
			for (int i = 0; i < N; i++) {
				if ((mask | (1 << i)) == mask) continue;
				for (int j = i + 1; j < N; j++) {
					if ((mask | (1 << j)) == mask) continue;
					pairs[p] = i * N + j;
					rec(mask | (1 << i) | (1 << j), sum + dist[i][j], p + 1);
				}
			}
		}
	}

	void update(int cur) {
		best = cur;
		System.arraycopy(pairs, 0, answer, 0, answer.length);
	}

	int dist(int x1, int y1, int x2, int y2) {
		return sqr(x2 - x1) + sqr(y2 - y1);
	}

	int sqr(int x) {
		return x * x;
	}

	/***************************************************************
	 * Input
	 **************************************************************/
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

public class Newbie {

    static InputReader sc = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {
        solver s = new solver();
        int t = 1;
        while (t > 0) {
            s.solve();
            t--;
        }
        out.close();
    }

    static class InputReader {

        public BufferedReader br;
        public StringTokenizer token;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream), 32768);
            token = null;
        }

        public String sn() {
            while (token == null || !token.hasMoreTokens()) {
                try {
                    token = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return token.nextToken();
        }

        public int ni() {
            return Integer.parseInt(sn());
        }

        public String snl() throws IOException {
            return br.readLine();
        }

        public long nlo() {
            return Long.parseLong(sn());
        }

        public double nd() {
            return Double.parseDouble(sn());
        }

        public int[] na(int n) {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = sc.ni();
            return a;
        }

        public long[] nal(int n) {
            long a[] = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = sc.nlo();
            return a;
        }
    }

    static int inf = 5000013;

    static class solver {
        DecimalFormat df = new DecimalFormat("0.00000000");
        int maxi = 200000000;
        int mod = (int) (1e9 + 7);

        long dis(int x1, int y1, int x2, int y2) {
            return Math.abs(x2 - x1) * Math.abs(x2 - x1) + Math.abs(y2 - y1) * Math.abs(y2 - y1);
        }

        void solve() {
            int hx = sc.ni();
            int hy = sc.ni();
            LinkedList<Integer> ans = new LinkedList<>();
            int n = sc.ni();
            int point[][] = new int[n + 1][2];
            point[0][0] = hx;
            point[0][1] = hy;
            for (int i = 1; i <= n; i++) {
                point[i][0] = sc.ni();
                point[i][1] = sc.ni();
            }
            long mat[][] = new long[n + 1][n + 1];
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= n; j++) {
                    mat[i][j] = dis(point[i][0], point[i][1], point[j][0], point[j][1]);
//                    out.println(mat[i][j]);
                }
            }
            int mask = (1 << n);
            long dp[] = new long[mask];
            Arrays.fill(dp, Integer.MAX_VALUE);
            dp[0] = 0;
            int parent[] = new int[mask];
            for (int i = 0; i < mask; i++) {
                int x = Integer.bitCount(i);
                int last = 0;
                for (int j = 0; j < n; j++) {
                    if ((i & (1 << j)) > 0)
                        last = (j + 1);
                }
                if (x % 2 == 0) {
                    for (int j = 0; j < n; j++) {
                        if ((i & (1 << j)) == 0) {
                            long d = dp[i] + mat[last][0] + mat[0][j + 1];
                            if (dp[i | (1 << j)] > d) {
                                dp[i | (1 << j)] = d;
                                parent[i | (1 << j)] = i;
                            }
                        }
                    }
                } else {
                    for (int j = 0; j < n; j++) {
                        if ((i & (1 << j)) == 0) {
                            long d = dp[i] + mat[last][j + 1];
                            if (dp[i | (1 << j)] > d) {
                                dp[i | (1 << j)] = d;
                                parent[i | (1 << j)] = i;
                            }
                        }
                    }
                }
            }
            int j = -1;
            for (int i = 0; i < n; i++) {
                if ((parent[mask - 1] & (1 << i)) == 0) {
                    j = i + 1;
                    break;
                }
            }
            long res = dp[mask - 1] + mat[j][0];
            int p = mask - 1;
            while (p > 0) {
                int x = p ^ parent[p];
                int bit = (int) (Math.log10(x) / Math.log10(2)) + 1;
                ans.add(0, bit);
                p = parent[p];
            }
            out.println(res);
            p = 2;
            for (int h : ans) {
                if (p == 2) {
                    out.print(0 + " ");
                    p = 0;
                }
                out.print(h + " ");
                p += 1;
            }
            out.println(0);
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	static int[][] pos;
	static int[] dp;
	static int[] nextstate;
	static int[][] dist;
	static int r;
	static int v;

	static void print(int mask) {
		if (mask < v) {
			int c = 0;
			int x = mask ^ nextstate[mask];
			for (int i = 0; i < dist.length - 1; i++) {
				if((x & (1<<i))>0) {
					System.out.println(i+1 + " ");
					c++;
				}
			}
			if(c == 1)System.out.println("0 ");
			print(nextstate[mask]);
		}
	}

	static int distace(int x1, int x2, int y1, int y2) {
		return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
	}

	static int solve(int mask) {
		if (mask == v) {
			nextstate[mask] = r;

			return 0;
		}
		if (nextstate[mask] != 0) {
			return dp[mask];
		}

		dp[mask] = (int) 1e9;
		for (int i = 1; i < pos.length; i++) {
			int u = (1 << (i - 1));
			int z = mask | u;
			if ((mask & u) == 0) {
				int x = 2 * dist[i][0] + solve(z);
				if (dp[mask] > x) {
					dp[mask] = x;
					nextstate[mask] = z;
				}

				for (int j = 1; j < pos.length; j++) {
					int m = (1 << j - 1);
					int y = z | m;
					if ((z & m) == 0) {
						x = dist[i][0] + solve(y) + dist[i][j] + dist[j][0];

						if (dp[mask] > x) {
							dp[mask] = x;
							nextstate[mask]= y;
						}

					}
				}
				break;
			}
		}
		return dp[mask];
	}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(), y = in.nextInt();
		int n = in.nextInt();
		r = 1 << n;
		v = r - 1;
		dp = new int[r];
		nextstate = new int[r];
		pos = new int[n + 1][2];
		pos[0][0] = x;
		pos[0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos[i][0] = in.nextInt();
			pos[i][1] = in.nextInt();
		}
		dist = new int[n + 1][n + 1];
		for (int i = 0; i < dist.length; i++) {
			for (int j = i + 1; j < dist.length; j++) {
				dist[i][j] = dist[j][i] = distace(pos[i][0], pos[j][0], pos[i][1], pos[j][1]);
			}
		}

		System.out.println(solve(0));
		System.out.print("0 ");
		print(0);
	}

}

class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
    private int[][] distance;
    private int[] dp;
    private ArrayList<Integer>[] visited;

    public static void main(String[] args) throws IOException {
        new LookingForOrder().solve();
    }

    public void solve() throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        int x = Integer.parseInt(tokenizer.nextToken());
        int y = Integer.parseInt(tokenizer.nextToken());
        int n = Integer.parseInt(f.readLine());
        int[][] coords = new int[n + 1][2];
        coords[0][0] = x;
        coords[0][1] = y;
        for (int i = 1; i <= n; i++) {
            tokenizer = new StringTokenizer(f.readLine());
            x = Integer.parseInt(tokenizer.nextToken());
            y = Integer.parseInt(tokenizer.nextToken());
            coords[i][0] = x;
            coords[i][1] = y;
        }

        this.distance = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                distance[i][j] += (coords[i][0] - coords[j][0]) * (coords[i][0] - coords[j][0]);
                distance[i][j] += (coords[i][1] - coords[j][1]) * (coords[i][1] - coords[j][1]);
            }
        }

        int lastSet = 1 << n;

        this.visited = new ArrayList[lastSet];

        this.dp = new int[lastSet];
        Arrays.fill(dp, Integer.MAX_VALUE);
        this.dp[0] = 0;
        lastSet--;
        this.getMinPath(lastSet);

        PrintWriter out = new PrintWriter(System.out);
        out.println(dp[lastSet]);
        ArrayDeque<Integer> stack = new ArrayDeque<Integer>();
        boolean started = false;
        while (lastSet != 0) {
           // System.out.println(lastSet);
            stack.addFirst(0);
            int newSet = lastSet;
            for (int visit : visited[lastSet]) {
                stack.addFirst(visit);
                newSet -= 1 << (visit - 1);
            }

            lastSet = newSet;
        }
        stack.addFirst(0);

        while (!stack.isEmpty()) {
            if (!started) {
                out.print(stack.pop());
                started = true;
            } else {
                out.print(" ");
                out.print(stack.pop());
            }
        }

        out.println();
        out.close();
    }

    private int getMinPath(int set) {
        if (this.dp[set] != Integer.MAX_VALUE) {
            return this.dp[set];
        }

        for (int i = 1, j = 1; i < this.dp.length; i *= 2, j++) {
            if ((set & i) == i) {
                int possibleMin = getMinPath(set & (set - i)) + (this.distance[0][j] * 2);
                if (possibleMin < this.dp[set]) {
                    this.dp[set] = possibleMin;
                    ArrayList<Integer> visit = new ArrayList<Integer>();
                    visit.add(j);
                    this.visited[set] = visit;
                }
            }
        }
        for (int i0 = 1, j0 = 1; i0 < this.dp.length; i0 *= 2, j0++) {
            for (int i1 = 1, j1 = 1; i1 < this.dp.length; i1 *= 2, j1++) {
                if ((set & i0) == i0 && (set & i1) == i1) {
                    //System.out.println(set + " " + (set & (set - i0 - i1)));
                    int possibleMin = getMinPath(set & (set - i0 - i1)) + this.distance[0][j0] + this.distance[0][j1] + this.distance[j0][j1];
                    if (possibleMin < this.dp[set]) {
                        this.dp[set] = possibleMin;
                        ArrayList<Integer> visit = new ArrayList<Integer>();
                        visit.add(j0);
                        visit.add(j1);
                        this.visited[set] = visit;
                    }
                }
            }
        }

        //System.out.println(this.dp[set] + " " + Integer.toBinaryString(set));
        return this.dp[set];
    }
}

import java.util.Arrays;
import java.util.Scanner;

public class C
{

    public static void main(String[] args)
    {
        new C();
    }

    final int oo = (int)1e9;

    int Hx,Hy;

    int N;
    int[][] P;

    int[] memo;
    int[][] soln;

    int[] dist1;
    int[][] dist2;

    C()
    {
        Scanner in = new Scanner(System.in);
        Hx=in.nextInt();
        Hy=in.nextInt();

        N=in.nextInt();
        P=new int[N][2];
        for (int i=0; i<N; ++i)
        {
            P[i][0]=in.nextInt();
            P[i][1]=in.nextInt();
        }

        memo=new int[1<<N];
        Arrays.fill(memo, -1);
        soln=new int[2][1<<N];

        dist1=new int[N];
        Arrays.fill(dist1, -1);
        dist2=new int[N][N];
        for (int[] d : dist2) Arrays.fill(d, -1);

        int res=go((1<<N)-1);
        System.out.println(res);

        int set=(1<<N)-1;
        while (set>0)
        {
            System.out.print("0 ");
            System.out.print((soln[0][set]+1)+" ");
            if (soln[1][set]>-1) System.out.print((soln[1][set]+1)+" ");

            if (soln[1][set]>-1)
            {
                set-=((1<<soln[0][set])+(1<<soln[1][set]));
            }
            else
            {
                set-=(1<<soln[0][set]);
            }
        }
        System.out.println("0");
    }

    int go(int set)
    {
        if (set==0)
            return 0;
        if (memo[set]>-1)
            return memo[set];

        if (Integer.bitCount(set)==1)
        {
            int i=0;
            while (!on(set,i)) ++i;
            memo[set]=dist(i);
            soln[0][set]=i;
            soln[1][set]=-1;
            return memo[set];
        }

        int res=oo;
        int i=0;
        while (!on(set,i)) ++i;

        for (int j=i+1; j<N; ++j)
        {
            if (on(set,j))
            {
                int tmp=dist(i,j)+go(set-(1<<i)-(1<<j));
                if (tmp<res)
                {
                    res=tmp;
                    soln[0][set]=i;
                    soln[1][set]=j;
                }
            }
        }

        return memo[set]=res;
    }

    // H->i->H
    int dist(int i)
    {
        if (dist1[i]>-1) return dist1[i];

        int dx=P[i][0]-Hx;
        int dy=P[i][1]-Hy;
        return dist1[i]=2*(dx*dx+dy*dy);
    }

    // H->i->j->H
    int dist(int i, int j)
    {
        if (dist2[i][j]>-1) return dist2[i][j];

        int res=0,dx,dy;

        dx=P[i][0]-Hx;
        dy=P[i][1]-Hy;
        res+=dx*dx+dy*dy;

        dx=P[i][0]-P[j][0];
        dy=P[i][1]-P[j][1];
        res+=dx*dx+dy*dy;

        dx=P[j][0]-Hx;
        dy=P[j][1]-Hy;
        res+=dx*dx+dy*dy;

        return dist2[i][j]=res;
    }

    boolean on(int set, int loc)
    {
        return (set&(1<<loc))>0;
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp, p;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = 99999999;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				int tmp = 2 * dist(0, i) + solve(mask | (1 << i));
				if (tmp < ans) {
					ans = tmp;
					p[mask] = -i;
				}
				for (int j = 1; j < n; j++)
					if (i != j && (mask & (1 << j)) == 0) {
						tmp = dist(0, i) + dist(i, j) + dist(j, 0)
								+ solve(mask | (1 << i) | (1 << j));
						if (tmp < ans) {
							ans = tmp;
							p[mask] = i;
							p[mask | (1 << i)] = -j;
						}
					}
			}
		return dp[mask] = ans;
	}

	public static void main(String[] args) throws IOException {
		PrintWriter out = new PrintWriter(System.out);
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		p = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		int mask = 1 << 0;
		out.print(0);
		while (mask != (1 << n) - 1) {
			out.print(" " + Math.abs(p[mask]));
			if (p[mask] < 0)
				out.print(" 0");
			mask |= (1 << Math.abs(p[mask]));
		}
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.io.*;
import java.util.*;
//import java.lang.*;

public class Main {

	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		String input[] = kek.readLine().split(" ");
		int xH = Integer.parseInt(input[0]);
		int yH = Integer.parseInt(input[1]);
		int N = Integer.parseInt(kek.readLine());
		int xcoords[] = new int[N + 1];
		int ycoords[] = new int[N + 1];
		int dFromStart[] = new int[N + 1];
		int dFromEachOther[][] = new int[N + 1][N + 1];
		boolean taken[] = new boolean[N + 1];
		List<Integer> finalPath = new ArrayList<>();
		int minFromStart = 1;
		int mini = 0;
		int minj = 0;
		int objTrack = N;

		for(int i = 1; i <= N; i++){
			input = kek.readLine().split(" ");
			int x = Integer.parseInt(input[0]);
			int y = Integer.parseInt(input[1]);
			xcoords[i] = x;
			ycoords[i] = y;
			dFromStart[i] = getTime(xH, yH, x, y);
			minFromStart = dFromStart[minFromStart] > dFromStart[i] ? i : minFromStart;
			taken[i] = false;
		}
		int tempMin = 100000;
		for(int i = 1; i <= N; i++){
			int x = xcoords[i];
			int y = ycoords[i];
			for(int j = 1; j <= N; j++){
				int x2 = xcoords[j];
				int y2 = ycoords[j];
				if(j != i){
					dFromEachOther[i][j] = getTime(x, y, x2, y2);
					if(tempMin > dFromEachOther[i][j]){
						tempMin = dFromEachOther[i][j];
						mini = i;
						minj = j;
					}
				} else {
					dFromEachOther[i][j] = 10000;
				}
			}
		}

		finalPath.add(0);
		finalPath.add(mini);
		finalPath.add(minj);
		finalPath.add(0);
		objTrack -= 2;
		taken[mini] = true;
		taken[minj] = true;
		int res = dFromStart[mini];
		res += tempMin;
		res += dFromStart[minj];
		System.out.println(objTrack);

		if(objTrack % 2 == 0){
			while(objTrack > 0){
				int coords[] = shortPath(dFromEachOther, taken, N);
				mini = coords[0];
				minj = coords[1];
				if(mini != -1 || minj != -1){
					finalPath.add(0);
					finalPath.add(mini);
					finalPath.add(minj);
					finalPath.add(0);
					objTrack -= 2;
					taken[mini] = true;
					taken[minj] = true;
					res += dFromStart[mini];
					res += tempMin;
					res += dFromStart[minj];
				}
			}
		} else {
			if(objTrack > 2){
				while(objTrack > 2){
					int coords[] = shortPath(dFromEachOther, taken, N);
					mini = coords[0];
					minj = coords[1];
					if(mini != -1 || minj != -1){
						finalPath.add(0);
						finalPath.add(mini);
						finalPath.add(minj);
						finalPath.add(0);
						objTrack -= 2;
						taken[mini] = true;
						taken[minj] = true;
						res += dFromStart[mini];
						res += tempMin;
						res += dFromStart[minj];
					}
				}
			}

			for(int c = 1; c <= N; c++){
				if(taken[c] == false){
					finalPath.add(c);
					finalPath.add(0);
					objTrack--;
					taken[c] = true;
					res += 2 * dFromStart[c];
				}
			}

		}

		System.out.println(res);
		for(int i : finalPath){
			System.out.print(i + " ");
		}

	}

	static int getTime(int x1, int y1, int x2, int y2){
		int x = (x2 - x1);
		int fx = x * x;
		int y = (y2 - y1);
		int fy = y * y;
		int result = fx + fy;
		return result;
	}

	static int[] shortPath(int[][] paths, boolean[] taken, int N){
		int coords[] = new int[2];
		int min = 10000;
		int m1 = -1;
		int m2 = -1;
		for(int i = 1; i <= N; i++){
			if(taken[i] == true){
				continue;
			}
			for(int j = 1; j <= N; j++){
				if(taken[j] == true){
					continue;
				} else {
					if(min > paths[i][j]){
						min = paths[i][j];
						m1 = i;
						m2 = j;
					}
				}
			}
		}

		coords[0] = m1;
		coords[1] = m2;

		return coords;
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
static int n;
static int []x,y,memo;
static StringBuilder sb;
static int distance(int i,int j)
{
	int dx=x[i]-x[j];
	int dy=y[i]-y[j];
	return dx*dx+dy*dy;
}
public static int dp(int msk)
{
	if(msk==(1<<(n+1))-2)
		return 0;
	if(memo[msk]!=-1)
		return memo[msk];
	int ans=100000;
	boolean found=false;
	for(int i=1;i<=n && !found;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				found=true;
				int newM=msk|1<<i;
				newM|=1<<j;
				ans=Math.min(ans, dp(newM)+Math.min(distance(0,i)+distance(i,j)+distance(j,0), distance(0,j)+distance(j,i)+distance(i,0)));
			}
	return memo[msk]=ans;

}
public static void print(int msk)
{
	if(msk==(1<<(n+1))-2)
		return ;

	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				int newM=msk|1<<i;
				newM|=1<<j;
				int d1=distance(0,i)+distance(i,j)+distance(j,0);
				int d2=distance(0,j)+distance(j,i)+distance(i,0);
				if(dp(msk)== dp(newM)+Math.min(d1,d2))
				{

					if(i==j)

						sb.append("0 "+i+" ");

					else if(d1<d2)
						sb.append("0 "+i+" "+j+" ");
					else
						sb.append("0 "+j+" "+i+" ");

					print(newM);
					return ;
				}
			}

}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int xS=sc.nextInt(),yS=sc.nextInt();
		n=sc.nextInt();
		x=new int [n+1];
		y=new int [n+1];
		x[0]=xS;y[0]=yS;
		for(int i=1;i<=n;i++)
		{
			x[i]=sc.nextInt();
			y[i]=sc.nextInt();

		}
		memo=new int [1<<(n+1)];
		Arrays.fill(memo,-1);
		sb=new StringBuilder();

		sb.append(dp(0)+"\n");
		print(0);
		sb.append("0");
		System.out.println(sb);
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		public Scanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());

		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}

import java.io.*;
import java.util.*;

public class A558 {
  static BufferedReader in = null;
  static PrintWriter out = null;
  static StringTokenizer st = new StringTokenizer("");

  public static void main(String[] args) {
    try {
      in = new BufferedReader(new InputStreamReader(System.in));
      out = new PrintWriter(System.out);
      solve();
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static String readString() {
    while (!st.hasMoreTokens()) {
      try {
        st = new StringTokenizer(in.readLine(), " \n\r\t:");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return st.nextToken();
  }

  public static int readInt() {
    return Integer.parseInt(readString());
  }

  public static long readLong() {
    return Long.parseLong(readString());
  }

  private static int MAX_VALUE = Integer.MAX_VALUE - 10000000;
  private static int[] dp;
  private static int[] parents;
  private static int[] powers;
  private static int[] x;
  private static int[] y;
  private static int[][] dist;
  private static int[] distFrom0;

  private static void solve() throws IOException {
    int x0 = readInt();
    int y0 = readInt();
    int n = readInt();
    x = new int[n];
    y = new int[n];
    for (int i = 0; i < n; i++) {
      x[i] = readInt() - x0;
      y[i] = readInt() - y0;
    }
    dist = new int[n][n];
    distFrom0 = new int[n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        dist[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
      }
    }
    for (int i = 0; i < n; i++) {
      distFrom0[i] = x[i] * x[i] + y[i] * y[i];
    }
    powers = new int[n + 1];
    powers[0] = 1;
    for (int i = 1; i < n + 1; i++) {
      powers[i] = powers[i - 1] * 2;
    }
    int maxMask = 1 << n;
    dp = new int[maxMask];
    parents = new int[maxMask];
    Arrays.fill(dp, MAX_VALUE);
    dp[0] = 0;
    for (int i = 0; i < maxMask; i++) {
      if (dp[i] != MAX_VALUE) {
        int curMask = i;
        for (int k = 0; k < n; k++) {
          if ((powers[k] & curMask) == 0) {
            int mask = curMask | powers[k];
            for (int j = k; j < n; j++) {
              if ((powers[j] & mask) == 0) {
                int nextMask = mask | powers[j];
                int minDist = dp[curMask] + distFrom0[k] + dist[k][j] + distFrom0[j];
                if (dp[nextMask] > minDist) {
                  dp[nextMask] = minDist;
                  parents[nextMask] = curMask;
                }
              }
            }
          }
        }
      }
    }
    // brute(n, 0);
    maxMask--;
    out.println(dp[maxMask]);
    while (maxMask != 0) {
      out.print("0 ");
      int[] diffBits = getBits(n, maxMask, parents[maxMask]);
      for (int i = 1; i <= diffBits[0]; i++) {
        out.print(diffBits[i] + 1 + " ");
      }
      maxMask = parents[maxMask];
    }
    out.print(0);
  }

  private static boolean hasBit(int x, int index) {
    return (powers[index] & x) != 0;
  }

  private static int setBit(int x, int index) {
    return (x | powers[index]);
  }

  private static int getDist(int xFrom, int yFrom, int xTo, int yTo) {
    return (xTo - xFrom) * (xTo - xFrom) + (yTo - yFrom) * (yTo - yFrom);
  }

  private static int[] getBits(int n, int nextMask, int curMask) {
    int[] res = new int[3];
    for (int i = 0; i < n; i++) {
      if (hasBit(nextMask, i) ^ hasBit(curMask, i)) {
        res[++res[0]] = i;
      }
    }
    return res;
  }

  private static void brute(int n, int mask) {
    List<Integer> listNotTaken = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      if (!hasBit(mask, i)) {
        listNotTaken.add(i);
      }
    }
    for (int first : listNotTaken) {
      int temp = setBit(mask, first);
      for (int second : listNotTaken) {
        int nextMask = setBit(temp, second);
        int minDist = dp[mask] + getDist(0, 0, x[first], y[first]) + getDist(x[first], y[first], x[second], y[second]) + getDist(x[second], y[second], 0, 0);
        if (dp[nextMask] > minDist) {
          dp[nextMask] = minDist;
          parents[nextMask] = mask;
          brute(n, nextMask);
        }
      }
    }
  }

}

import java.util.*;
import java.io.*;

public class Main{

    BufferedReader in;
    StringTokenizer str = null;
    PrintWriter out;

    private String next() throws Exception{
    	if (str == null || !str.hasMoreElements())
    	    str = new StringTokenizer(in.readLine());
    	return str.nextToken();
    }

    private int nextInt() throws Exception{
	   return Integer.parseInt(next());
    }

    int []x,y;
    int n;
    int []dp, prev;

    public void run() throws Exception{
    	in = new BufferedReader(new InputStreamReader(System.in));
    	out = new PrintWriter(System.out);

    	int xs = nextInt();
    	int ys = nextInt();
    	n = nextInt();
    	x = new int[n];
    	y = new int[n];
    	for(int i=0;i<n;i++){
    		x[i] = nextInt();
    		y[i] = nextInt();
    	}

    	int one[] = new int[n];
    	for(int i=0;i<n;i++){
    		one[i] = dist(xs, ys, x[i], y[i]);
    	}

    	int two[][] = new int[n][n];
    	for(int i=0;i<n;i++){
    		for(int j=i+1;j<n;j++){
    			two[i][j] = two[j][i] = dist(xs, ys, x[i], y[i]) + dist(x[i], y[i], x[j], y[j]) + dist(xs, ys, x[j], y[j]);
    		}
    	}

    	dp = new int[1<<n];
    	Arrays.fill(dp, Integer.MAX_VALUE/2);
    	dp[0] = 0;
    	prev = new int[1<<n];
    	Arrays.fill(prev, -1);

    	for(int mask=1;mask<(1<<n);mask++){
    		int i = 0;
    		while((mask & (1<<i)) == 0) i++;
    		dp[mask] = dp[mask ^ (1<<i)] + 2*one[i];
    		prev[mask] = i+1;
    		for(int j=i+1;j<n;j++){
    			if ((mask & (1<<j)) > 0) {
    				if (dp[mask] > dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j]) {
    					dp[mask] = dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j];
    					prev[mask] = 100 * (i+1) + (j+1);
    				}
    			}
    		}
    	}

    	out.println(dp[(1<<n)-1]);
    	out.print(0 + " ");
    	int cur = (1<<n)-1;
    	while(cur > 0) {
    		int i = prev[cur]/100;
    		int j = prev[cur]%100;

    		if (i > 0) {
    			cur^=1<<(i-1);
    			out.print(i + " ");
    		}

    		if (j > 0) {
    			cur^=1<<(j-1);
    			out.print(j + " ");
    		}
    	}
    	out.println(0);
		out.close();
    }

    private String bit2str(int mask, int n) {
    	String s = "";
    	for(int i=0;i<n;i++){
    		if ((mask & (1<<i)) > 0){
    			s+="1";
    		}else{
    			s+="0";
    		}
    	}
    	while(s.length() < n)
    		s+="0";

    	return new StringBuilder(s).reverse().toString();
    }

    private int dist(int x1, int y1, int x2, int y2) {
    	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    }

    public static void main(String args[]) throws Exception{
	   new Main().run();
    }
}

import java.util.*;

public class C
{
   public static void main(String[] args)
   {
      new C(new Scanner(System.in));
   }

   vect[] vs;
   int N;
   int oo = 987654321;

   ArrayList<choice> cs;
   choice[][] cg;

   int MF;

   int[] memo;
   int[] next;

   int go(int m)
   {
      if (m == MF)
         return 0;
      if (memo[m] != -1)
         return memo[m];

      // Try a new place
      int res = oo;
      int nxt = -1;

      int i=0;
      for (i=0; i<N; i++)
      {
         if (((1<<i)&m) == 0)
            break;
      }

      for (int j=0; j<N; j++)
      {
         choice cc = cg[i][j];
         if ((m&cc.m) > 0)
            continue;

         int r2 = cc.cost+go(m|cc.m);
         if (r2 < res)
         {
            res = r2;
            nxt = i;
         }
      }

      memo[m] = res;
      next[m] = nxt;
      return res;
   }

   public C(Scanner in)
   {
      vect vt = new vect(in.nextInt(), in.nextInt());
      N = in.nextInt();
      vs = new vect[N+1];
      vs[N] = vt;
      for (int i=0; i<N; i++)
         vs[i] = new vect(in.nextInt(), in.nextInt());

      // Precompute all choices and masks
      cs = new ArrayList<choice>();
      cg = new choice[N][N];
      for (int i=0; i<N; i++)
      {
         choice cc = new choice(2*vs[i].dist(vt), 1<<i);
         cc.add(i);
         cs.add(cc);
         cg[i][i] = cc;
      }

      for (int i=0; i<N; i++)
      {
         for (int j=i+1; j<N; j++)
         {
            int dist = vs[i].dist(vt);
            dist += vs[i].dist(vs[j]);
            dist += vs[j].dist(vt);
            choice cc = new choice(dist, (1<<i)|(1<<j));
            cc.add(i); cc.add(j);
            cs.add(cc);
            cg[i][j] = cc;
            cg[j][i] = cc;
         }
      }

      MF = (1<<N)-1;
      next = new int[MF+1];
      memo = new int[MF+1];

      Arrays.fill(next, -1);
      Arrays.fill(memo, -1);

      int res = go(0);
      System.out.println(res);

      int m = 0;
      StringBuilder sb = new StringBuilder();
      while (m != -1)
      {
         //System.out.println(Integer.toBinaryString(m));
         sb.append(0);
         sb.append(' ');
         int i = next[m];
         if (i == -1)
            break;
         choice cc = cs.get(i);
         for (int j : cc.iv)
         {
            sb.append(f(j));
            sb.append(' ');
         }
         m = m|cc.m;
      }
      System.out.println(sb.toString().trim());
   }

   int f(int i)
   {
      if (i == N)
         return 0;
      return i+1;
   }
}

class choice
{
   int cost;
   int m;
   ArrayList<Integer> iv;

   public choice(int c, int mm)
   {
      cost = c;
      m = mm;
      iv = new ArrayList<Integer>(2);
   }

   void add(int i)
   {
      iv.add(i);
   }
}

class vect
{
   int x, y;

   public vect(int i, int j)
   {
      x=i; y=j;
   }

   int dist(vect rhs)
   {
      int xx = x-rhs.x;
      int yy = y-rhs.y;
      return xx*xx+yy*yy;
   }
}

import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.HashSet;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alex
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
	    int handx = in.ri(), handy = in.ri();
	    int n = in.ri();
	    IntPair[] cords = new IntPair[n];
	    for(int i = 0; i < n; i++) {
		    int x = in.ri() - handx;
		    int y = in.ri() - handy;
		    cords[i] = new IntPair(x, y);
	    }
	    int[] perms = new int[n];
	    for(int i = 0; i < n; i++) perms[i] = i;
	    Pair<Integer, ArrayList<Integer>> res = Pair.makePair(10000000, null);
	    int[] bestperm = new int[n];
	    while(true){
		    int[] next = new int[n];
		    Pair<Integer, ArrayList<Integer>> best = dp(0, next, perms, cords);
		    if (best.first < res.first){
			    res = best;
			    bestperm = perms.clone();
		    }
		    if (!ArrayUtils.nextPermutation(perms)) break;
	    }
	    out.printLine(res.first);
	    ArrayList<Integer> ans = new ArrayList<>();
	    ans.add(0);
	    for(int i = 0; i < n; i++)  {
		    ans.add(bestperm[i] + 1);
		    if (res.second.contains(i)) ans.add(0);
	    }
	    for(int i : ans) out.print(i + " ");
    }
	Pair<Integer, ArrayList<Integer>> dp(int cur, int[] next, int[] perms, IntPair[] cords){
		if (cur == perms.length) return Pair.makePair(0, new ArrayList<>());
		Pair<Integer, ArrayList<Integer>> restone = dp(cur + 1, next, perms, cords);
		int takeone = 2 * cords[perms[cur]].first * cords[perms[cur]].first + 2 * cords[perms[cur]].second * cords[perms[cur]].second;
		Pair<Integer, ArrayList<Integer>> resttwo = Pair.makePair(100000, new ArrayList<>());
		int taketwo = 100000;
		if (cur < perms.length - 1){
			resttwo = dp(cur + 2, next, perms, cords);
			taketwo = cords[perms[cur]].first * cords[perms[cur]].first + cords[perms[cur]].second * cords[perms[cur]].second +
					(cords[perms[cur + 1]].first - cords[perms[cur]].first) * (cords[perms[cur + 1]].first - cords[perms[cur]].first) +
					(cords[perms[cur + 1]].second - cords[perms[cur]].second) * (cords[perms[cur + 1]].second - cords[perms[cur]].second) +
					cords[perms[cur + 1]].first * cords[perms[cur + 1]].first + cords[perms[cur + 1]].second * cords[perms[cur + 1]].second;
		}
		if (takeone + restone.first <= taketwo + resttwo.first){
			return Pair.makePair(takeone + restone.first, restone.second);
		}
		next[cur] = 1000;
		next[cur + 1] = -1000;
resttwo.second.add(cur);
		return Pair.makePair(taketwo + resttwo.first, resttwo.second);
	}
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int ri(){
		return readInt();
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IntPair implements Comparable<IntPair> {
public int first, second;

	public IntPair(int first, int second) {
		this.first = first;
		this.second = second;
	}
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;

		IntPair intPair = (IntPair) o;

		return first == intPair.first && second == intPair.second;

	}

	public int hashCode() {
		int result = first;
		result = 31 * result + second;
		return result;
	}

	public int compareTo(IntPair o) {
		if (first < o.first)
			return -1;
		if (first > o.first)
			return 1;
		if (second < o.second)
			return -1;
		if (second > o.second)
			return 1;
		return 0;
	}
}

class Pair<U, V> implements Comparable<Pair<U, V>> {
	public U first;
	public V second;

	public static<U, V> Pair<U, V> makePair(U first, V second) {
		return new Pair<U, V>(first, second);
	}

	private Pair(U first, V second) {
		this.first = first;
		this.second = second;
	}

	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;

		Pair pair = (Pair) o;

		return !(first != null ? !first.equals(pair.first) : pair.first != null) && !(second != null ? !second.equals(pair.second) : pair.second != null);

	}

	public int hashCode() {
		int result = first != null ? first.hashCode() : 0;
		result = 31 * result + (second != null ? second.hashCode() : 0);
		return result;
	}
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	public int compareTo(Pair<U, V> o) {
		int value = ((Comparable<U>)first).compareTo(o.first);
		if (value != 0)
			return value;
		return ((Comparable<V>)second).compareTo(o.second);
	}
}

class ArrayUtils {
	public static boolean nextPermutation(int[] array) {
		return new IntArray(array).nextPermutation();
	}
}

abstract class IntCollection {
	public abstract int size();
}

interface IntIterator {
	public int value() throws NoSuchElementException;
	public void advance() throws NoSuchElementException;
	public boolean isValid();
}

interface IntComparator {
    public static final IntComparator DEFAULT = new IntComparator() {
        public int compare(int first, int second) {
            if (first < second)
                return -1;
            if (first > second)
                return 1;
            return 0;
        }
    };
	public int compare(int first, int second);
}

abstract class IntList extends IntCollection implements Comparable<IntList> {
	public abstract int get(int index);
	public abstract void set(int index, int value);

	public IntIterator iterator() {
		return new IntIterator() {
			private int size = size();
			private int index = 0;

			public int value() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				return get(index);
			}

			public void advance() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				index++;
			}

			public boolean isValid() {
				return index < size;
			}
		};
	}
	public boolean nextPermutation() {
		return nextPermutation(IntComparator.DEFAULT);
	}

	private boolean nextPermutation(IntComparator comparator) {
		int size = size();
		int last = get(size - 1);
		for (int i = size - 2; i >= 0; i--) {
			int current = get(i);
			if (comparator.compare(last, current) > 0) {
				for (int j = size - 1; j > i; j--) {
					if (comparator.compare(get(j), current) > 0) {
						swap(i, j);
						subList(i + 1, size).inPlaceReverse();
						return true;
					}
				}
			}
			last = current;
		}
		return false;
	}

	public void inPlaceReverse() {
		for (int i = 0, j = size() - 1; i < j; i++, j--)
			swap(i, j);
	}

	public IntList subList(final int from, final int to) {
		return new SubList(from, to);
	}

	private void swap(int first, int second) {
		if (first == second)
			return;
		int temp = get(first);
		set(first, get(second));
		set(second, temp);
	}
	public int hashCode() {
		int hashCode = 1;
		for (IntIterator i = iterator(); i.isValid(); i.advance())
			hashCode = 31 * hashCode + i.value();
		return hashCode;
	}

	public boolean equals(Object obj) {
		if (!(obj instanceof IntList))
			return false;
		IntList list = (IntList)obj;
		if (list.size() != size())
			return false;
		IntIterator i = iterator();
		IntIterator j = list.iterator();
		while (i.isValid()) {
			if (i.value() != j.value())
				return false;
			i.advance();
			j.advance();
		}
		return true;
	}

	public int compareTo(IntList o) {
		IntIterator i = iterator();
		IntIterator j = o.iterator();
		while (true) {
			if (i.isValid()) {
				if (j.isValid()) {
					if (i.value() != j.value()) {
						if (i.value() < j.value())
							return -1;
						else
							return 1;
					}
				} else
					return 1;
			} else {
				if (j.isValid())
					return -1;
				else
					return 0;
			}
			i.advance();
			j.advance();
		}
	}
	private class SubList extends IntList {
        private final int to;
        private final int from;
        private int size;

        public SubList(int from, int to) {
            this.to = to;
            this.from = from;
            size = to - from;
        }

        public int get(int index) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            return IntList.this.get(index + from);
        }

        public void set(int index, int value) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            IntList.this.set(index + from, value);
        }

        public int size() {
            return size;
        }
	}
}
class IntArray extends IntList {
	private final int[] array;

	public IntArray(int[] array) {
		this.array = array;
	}
	public int get(int index) {
		return array[index];
	}

	public void set(int index, int value) {
		array[index] = value;
	}

	public int size() {
		return array.length;
	}
}

import java.io.*;
import java.util.*;
//import java.lang.*;

public class Main {

	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		String input[] = kek.readLine().split(" ");
		int xH = Integer.parseInt(input[0]);
		int yH = Integer.parseInt(input[1]);
		int N = Integer.parseInt(kek.readLine());
		int xcoords[] = new int[N + 1];
		int ycoords[] = new int[N + 1];
		int dFromStart[] = new int[N + 1];
		int dFromEachOther[][] = new int[N + 1][N + 1];
		boolean taken[] = new boolean[N + 1];
		List<Integer> finalPath = new ArrayList<>();
		int minFromStart = 1;
		int mini = 0;
		int minj = 0;
		int objTrack = N;

		for(int i = 1; i <= N; i++){
			input = kek.readLine().split(" ");
			int x = Integer.parseInt(input[0]);
			int y = Integer.parseInt(input[1]);
			xcoords[i] = x;
			ycoords[i] = y;
			dFromStart[i] = getTime(xH, yH, x, y);
			minFromStart = dFromStart[minFromStart] > dFromStart[i] ? i : minFromStart;
			taken[i] = false;
		}
		int tempMin = 100000;
		for(int i = 1; i <= N; i++){
			int x = xcoords[i];
			int y = ycoords[i];
			for(int j = 1; j <= N; j++){
				int x2 = xcoords[j];
				int y2 = ycoords[j];
				if(j != i){
					dFromEachOther[i][j] = getTime(x, y, x2, y2);
					if(tempMin > dFromEachOther[i][j]){
						tempMin = dFromEachOther[i][j];
						mini = i;
						minj = j;
					}
				} else {
					dFromEachOther[i][j] = 10000;
				}
			}
		}
		int res = 0;
		finalPath.add(0);
		if(objTrack >= 2){
			finalPath.add(mini);
			finalPath.add(minj);
			finalPath.add(0);
			objTrack -= 2;
			taken[mini] = true;
			taken[minj] = true;
			res = dFromStart[mini];
			res += tempMin;
			res += dFromStart[minj]; //I left a system out in the last submission gah
		}

		if(objTrack % 2 == 0){
			while(objTrack > 0){
				int coords[] = shortPath(dFromEachOther, taken, N);
				mini = coords[0];
				minj = coords[1];
				if(mini != -1 || minj != -1){
					finalPath.add(0);
					finalPath.add(mini);
					finalPath.add(minj);
					finalPath.add(0);
					objTrack -= 2;
					taken[mini] = true;
					taken[minj] = true;
					res += dFromStart[mini];
					res += tempMin;
					res += dFromStart[minj];
				}
			}
		} else {
			if(objTrack > 2){
				while(objTrack > 2){
					int coords[] = shortPath(dFromEachOther, taken, N);
					mini = coords[0];
					minj = coords[1];
					if(mini != -1 || minj != -1){
						finalPath.add(0);
						finalPath.add(mini);
						finalPath.add(minj);
						finalPath.add(0);
						objTrack -= 2;
						taken[mini] = true;
						taken[minj] = true;
						res += dFromStart[mini];
						res += tempMin;
						res += dFromStart[minj];
					}
				}
			}

			for(int c = 1; c <= N; c++){
				if(taken[c] == false){
					finalPath.add(c);
					finalPath.add(0);
					objTrack--;
					taken[c] = true;
					res += 2 * dFromStart[c];
				}
			}

		}

		System.out.println(res);
		for(int i : finalPath){
			System.out.print(i + " ");
		}

	}

	static int getTime(int x1, int y1, int x2, int y2){
		int x = (x2 - x1);
		int fx = x * x;
		int y = (y2 - y1);
		int fy = y * y;
		int result = fx + fy;
		return result;
	}

	static int[] shortPath(int[][] paths, boolean[] taken, int N){
		int coords[] = new int[2];
		int min = 10000;
		int m1 = -1;
		int m2 = -1;
		for(int i = 1; i <= N; i++){
			if(taken[i] == true){
				continue;
			}
			for(int j = 1; j <= N; j++){
				if(taken[j] == true){
					continue;
				} else {
					if(min > paths[i][j]){
						min = paths[i][j];
						m1 = i;
						m2 = j;
					}
				}
			}
		}

		coords[0] = m1;
		coords[1] = m2;

		return coords;
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ProblemC {
    public static void main(String[] args) throws IOException {
        BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);

        // generateRandom();

        int[] pt = readPoint(s);
        int n = Integer.valueOf(s.readLine());
        int[][] xp = new int[n+1][];
        for (int i = 1 ; i <= n ; i++) {
            xp[i] = readPoint(s);
        }
        xp[0] = pt;

        int[][] dist = new int[n+1][n+1];
        for (int i = 0 ; i <= n ; i++) {
            for (int j = 0 ; j <= n ; j++) {
                int dx = Math.abs(xp[i][0] - xp[j][0]);
                int dy = Math.abs(xp[i][1] - xp[j][1]);
                dist[i][j] = dx*dx + dy*dy;
            }
        }

        int[][] dist2 = new int[n+1][n+1];
        for (int i = 0 ; i <= n ; i++) {
            for (int j = 0 ; j <= n ; j++) {
                dist2[i][j] = dist[0][i] + dist[i][j] + dist[j][0];
            }
        }

        int[] dp = new int[1<<n];
        int[][] dp_prev = new int[2][1<<n];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;

        for (int i = 0 ; i < (1<<n) ; i++) {
            if (dp[i] == Integer.MAX_VALUE) {
                continue;
            }
            int base = dp[i];
            // two
            for (int y = 0 ; y < n ; y++) {
                if ((i & (1<<y)) >= 1) {
                    continue;
                }
                for (int z = y+1 ; z < n ; z++) {
                    if ((i & (1<<z)) >= 1) {
                        continue;
                    }
                    int ti = i | (1<<y) | (1<<z);
                    int d = dist2[y+1][z+1];
                    if (dp[ti] > base + d) {
                        dp[ti] = base + d;
                        dp_prev[0][ti] = z+1;
                        dp_prev[1][ti] = y+1;
                    }
                }
            }
        }

        int bestOnes = 0;
        for (int i = 0 ; i < (1<<n) ; i++) {
            if (dp[i] == Integer.MAX_VALUE) {
                continue;
            }
            int sub = (1<<n) - 1 - i;
            int add = 0;
            for (int j = 0 ; j < n ; j++) {
                if ((sub & (1<<j)) >= 1) {
                    add += dist[0][j+1] * 2;
                }
            }
            if (dp[i] + add < dp[(1<<n)-1]) {
                dp[(1<<n)-1] = dp[i] + add;
                bestOnes = sub;
            }
        }

        StringBuffer b = new StringBuffer();
        b.append(" 0");
        for (int i = 0 ; i < n ; i++) {
            if ((bestOnes & (1<<i)) >= 1) {
                b.append(" ").append(i+1);
            }
        }

        out.println(dp[(1<<n)-1]);
        int nptn = (1<<n)-1-bestOnes;
        while (nptn >= 1) {
            int i1 = dp_prev[0][nptn];
            int i2 = dp_prev[1][nptn];
            if (i1 >= 1) {
                nptn -= 1<<(i1-1);
                b.append(" ").append(i1);
            }
            if (i2 >= 1) {
                nptn -= 1<<(i2-1);
                b.append(" ").append(i2);
            }
            b.append(" ").append(0);
        }
        out.println(b.substring(1));
        out.flush();
    }

    private static void generateRandom() {
        System.out.println("0 0");
        System.out.println("24");
        for (int i = 0 ; i < 24 ; i++) {
            int a = (int)(Math.random() * 200 - 100);
            int b = (int)(Math.random() * 200 - 100);
            System.out.println(a + " " + b);
        }
    }

    private static int[] readPoint(BufferedReader s) throws IOException {
        int[] ret = new int[2];
        String[] data = s.readLine().split(" ");
        ret[0] = Integer.valueOf(data[0]);
        ret[1] = Integer.valueOf(data[1]);
        return ret;
    }

    public static void debug(Object... os){
        System.err.println(Arrays.deepToString(os));
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp, p;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = 99999999;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				int tmp = 2 * dist(0, i) + solve(mask | (1 << i));
				if (tmp < ans) {
					ans = tmp;
					p[mask] = -i;
				}
			}
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				for (int j = 1; j < n; j++)
					if (i != j && (mask & (1 << j)) == 0) {
						int tmp = dist(0, i) + dist(i, j) + dist(j, 0)
								+ solve(mask | (1 << i) | (1 << j));
						if (tmp < ans) {
							ans = tmp;
							p[mask] = i;
							p[mask | (1 << i)] = -j;
						}
					}
			}
		return dp[mask] = ans;
	}

	public static void main(String[] args) throws IOException {
		PrintWriter out = new PrintWriter(System.out);
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		p = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		int mask = 1 << 0;
		out.print(0);
		while (mask != (1 << n) - 1) {
			out.print(" " + Math.abs(p[mask]));
			if (p[mask] < 0)
				out.print(" 0");
			mask |= (1 << Math.abs(p[mask]));
		}
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class LookingForOrder {
	static final int INF = (int)1e9;
	static int closest[][];
	static int arr[];
	static Point a[];
	static Point o;
	static int n;
	static int dp[];
	static PrintWriter out;

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);

		o = new Point(sc.nextInt(), sc.nextInt());
		n = sc.nextInt();
		a = new Point[n];
		for (int i = 0; i < n; i++)
			a[i] = new Point(sc.nextInt(), sc.nextInt());

		closest = new int[n][(1 << n) + 1];
		for (int i = 0; i < n; i++)
			Arrays.fill(closest[i], -1);
		for (int i = 0; i < n; i++) {
			PriorityQueue<Pair> pq = new PriorityQueue<>();
			for (int j = 0; j < n; j++) {
				if (i == j) continue;
				pq.add(new Pair(j, a[i].dist(a[j])));
			}

			arr = new int[n];
			Arrays.fill(arr, -1);
			while (!pq.isEmpty()) {
				Pair p = pq.remove();
				arr[p.idx] = 0;
				go(0, i, p.idx);
				arr[p.idx] = 1;
			}
		}

		dp = new int[(1 << n) + 5];
		Arrays.fill(dp, -1);
		out.println(rec(0));
		out.print(0 + " ");
		path(0);
		out.println();

		out.flush();
		out.close();
	}

	static void go(int idx, int f, int s) {
		if (idx == n) {
			int num = 0;
			for (int i = 0; i < n; i++)
				if (arr[i] == 1)
					num |= 1 << (n-i-1);
//			System.out.println(Arrays.toString(arr));

			closest[f][num] = s;
			return;
		}

		if (arr[idx] == -1) {
			arr[idx] = 0;
			go(idx+1, f, s);
			arr[idx] = 1;
			go(idx+1, f, s);
			arr[idx] = -1;
		}
		else
			go(idx+1, f, s);
	}

	static void path(int msk) {
		if (msk == (1 << n) - 1) return;

		int optimal = rec(msk);
		for (int i = 0; i < n; i++) {
			if ((msk & (1 << i)) == 0) {
				if (rec(msk | (1 << i)) + 2 * o.dist(a[i]) == optimal) {
					out.print((i + 1) + " " + 0 + " ");
					path(msk | (1 << i));
					return;
				}

				int close = closest[i][msk];
				if (close != -1)
					if (rec(msk | (1 << i) | (1 << close)) + o.dist(a[i]) + a[i].dist(a[close]) + a[close].dist(o) == optimal) {
						out.print((i + 1) + " " + (close + 1) + " " + 0 + " ");
						path(msk | (1 << i) | (1 << close));
						return;
					}
			}
		}
	}

	static int rec(int msk) {
		if (msk == (1 << n) - 1) return 0;
		if (dp[msk] != -1) return dp[msk];

		int ans = INF;
		for (int i = 0; i < n; i++) {
			if ((msk & (1 << i)) == 0) {
				ans = Math.min(ans, rec(msk | (1 << i)) + 2 * o.dist(a[i]));

				int close = closest[i][msk];
				if (close != -1)
					ans = Math.min(ans, rec(msk | (1 << i) | (1 << close)) + o.dist(a[i]) + a[i].dist(a[close]) + a[close].dist(o));
			}
		}

		return dp[msk] = ans;
	}

	static class Pair implements Comparable<Pair> {
		int idx, dist;

		public Pair(int i, int d) {
			idx = i;
			dist = d;
		}

		@Override
		public int compareTo(Pair o) {
			if (Integer.compare(dist, o.dist) != 0)
				return Integer.compare(dist, o.dist);
			return Integer.compare(idx, o.idx);
		}

		@Override
		public String toString() {
			return "(" + idx + ", " + dist + ")";
		}
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public int dist(Point p) {
			return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
		}
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		public Scanner(FileReader f) {
			br = new BufferedReader(f);
		}

		public Scanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public boolean Ready() throws IOException {
			return br.ready();
		}

		public void waitForInput(long time) {
			long ct = System.currentTimeMillis();
			while(System.currentTimeMillis() - ct < time) {};
		}

	}

}

import java.io.*;
import java.util.*;

public class CF8C {
	FastScanner in;
	PrintWriter out;

	int[] x, y;

	int dist(int v, int u) {
		return (x[v] - x[u]) * (x[v] - x[u]) + (y[v] - y[u]) * (y[v] - y[u]);
	}

	void solve() {
		int x1 = in.nextInt();
		int y1 = in.nextInt();
		int n = in.nextInt();

		x = new int[n + 1];
		y = new int[n + 1];
		for (int i = 1; i <= n; i++) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
		}
		x[0] = x1;
		y[0] = y1;
		long[] dp = new long[(1 << n)];
		int[][] dpFrom = new int[1 << n][2];
		Arrays.fill(dp, Long.MAX_VALUE);
		dp[0] = 0;
		for (int st = 0; st < (1 << n); st++) {
			if (dp[st] == Long.MAX_VALUE) continue;
			ArrayList<Integer> available = new ArrayList<Integer>();
			for (int i = 0; i < n; i++)
				if ((st & (1 << i)) == 0)
					available.add(i);
			if (available.size() == 0) continue;
			if (available.size() == 1) {
				long val = dp[st] + dist(available.get(0) + 1, 0) * 2;
				if (dp[(1 << n) - 1] > val) {
					dp[(1 << n) - 1] = val;
					dpFrom[(1 << n) - 1][0] = available.get(0);
					dpFrom[(1 << n) - 1][1] = -1;
				}
				continue;
			}
			for (int i = 0; i < available.size(); i++)
				for (int j = i + 1; j < available.size(); j++) {
					long val = dp[st] + dist(available.get(i) + 1, 0) + dist(available.get(j) + 1, 0) + dist(available.get(i) + 1, available.get(j) + 1);
					if (dp[st | (1 << available.get(i)) | (1 << available.get(j))] > val) {
						dp[st | (1 << available.get(i)) | (1 << available.get(j))] = val;
						dpFrom[st | (1 << available.get(i)) | (1 << available.get(j))][0] = available.get(i);
						dpFrom[st | (1 << available.get(i)) | (1 << available.get(j))][1] = available.get(j);
					}
				}
		}
		out.println(dp[(1 << n) - 1]);
		int nowSt = (1 << n) - 1;
		ArrayList<Integer> ans = new ArrayList<Integer>();
		ans.add(0);
		while (nowSt != 0) {
			int n1 = dpFrom[nowSt][0];
			int n2 = dpFrom[nowSt][1];
			if (n1 != -1)
				ans.add(n1 + 1);
			if (n2 != -1)
				ans.add(n2 + 1);
			if (n1 != -1)
				nowSt -= (1 << n1);
			if (n2 != -1)
				nowSt -= (1 << n2);
			ans.add(0);
		}
		for (int i = ans.size() - 1; i >= 0; i--)
			out.print(ans.get(i) + " ");
	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}
	}

	public static void main(String[] args) {
		new CF8C().runIO();
	}
}

import java.awt.Point;
import java.util.Scanner;

public class LookingForOrder {
	int [][] pos;
	int [][] dp;
	boolean [][]visited;
	int [][][]nextstate;

	public LookingForOrder(int[][] pos, int[][] dp, boolean[][] visited, int[][][] nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.visited = visited;
		this.nextstate = nextstate;
	}
	void print(int mask,int n) {
		if(mask <= (1<<pos.length) - 2 ) {
			System.out.print(nextstate[mask][n][0] + " ");
			print(nextstate[mask][n][1], nextstate[mask][n][2]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask,int idx,int n) {
		if(mask == (1<<pos.length) - 2 ) {
			nextstate [mask][n][0] = 0;
			nextstate[mask][n][1] = 1<<pos.length;
			nextstate[mask][n][2] = 1;

			return	distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) ;
		}
		if (visited [mask][n]) {
			return dp[mask][n];
		}
		visited [mask][n] = true;
		if(idx == 0) {
			dp[mask][n] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i)) == 0) {
					int x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<i)), i, 1);
					if(dp[mask][n] > x) {
						dp[mask][n] = x;
						nextstate[mask][n][0] = i;
						nextstate[mask][n][1] = (mask | (1<<i));
						nextstate[mask][n][2] = 1;
					}
				}
			}
			return dp[mask][n];
		}
		if(n == 2) {
			nextstate[mask][n][0] = 0;
			nextstate[mask][n][1] = mask;
			nextstate[mask][n][2] = 0;
			return dp[mask][n] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		}
		dp[mask][n] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		nextstate[mask][n][0] = 0;
		nextstate[mask][n][1] = mask ;
		nextstate[mask][n][2] = 0;
		for (int i = 1; i < pos.length; i++) {
			if ((mask & (1<<i)) == 0) {
				int x = distace(pos[idx][0], pos[i][0], pos[idx][1], pos[i][1]) + solve((mask | (1<<i)), i, 2);
				if(dp[mask][n] > x) {
					dp[mask][n] = x;
					nextstate[mask][n][0] = i;
					nextstate[mask][n][1] = (mask | (1<<i));
					nextstate[mask][n][2] = 1;
				}

			}
		}
		return dp[mask][n];
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n + 1)][3], new boolean[1<<(n + 1)][3], new int[1<<(n + 1)][3][3]);
		System.out.println(z.solve(0, 0, 0));
		System.out.print(0+" ");
		z.print(0, 0);
	}

}

import java.util.*;
import java.awt.Polygon;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.*;
import java.util.Collection;

public class Solution {

	/**
	 * @param args
	 * @throws IOException
	 */
	static StringTokenizer st;
	static BufferedReader reader;
	public static void main(String[] args) throws IOException {
		reader = new BufferedReader(new InputStreamReader(System.in));
		int xs = NextInt();
		int ys = NextInt();
		int n = NextInt();

		int x[] = new int[n];
		int y[] = new int[n];
		int single[] = new int[n];
		int pair[][] = new int[n][n];
		for (int i = 0; i < n; ++i) {
			x[i] = NextInt();
			y[i] = NextInt();
		}
		for (int i = 0; i < n; ++i)
			single[i] = 2 * dist(xs, ys, x[i], y[i]);
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				pair[i][j] = dist(xs, ys, x[i], y[i]) +
							 dist(x[i], y[i], x[j], y[j]) +
							 dist(x[j], y[j], xs, ys);
		int dp[] = new int[1 << n];
		int prev[] = new int[1 << n];
		for (int mask = 0; mask < (1 << n); ++mask) {
			int p = -1;
			for (int i = 0; i < n; ++i)
				if (((mask >> i) & 1) != 0) {
					p = i;
					break;
				}
			if (p == -1) continue;
			dp[mask] = dp[mask ^ (1 << p)] + single[p];
			prev[mask] = p;
			for (int j = p + 1; j < n; ++j) {
				if (((mask >> j) & 1) != 0) {
					int res = pair[p][j] + dp[mask ^ (1 << p) ^ (1 << j)];
					if (res < dp[mask]) {
						dp[mask] = res;
						prev[mask] = p + 100 * j;
					}
				}
			}
		}
		int cur = (1 << n) - 1;
		System.out.printf("%d\n", dp[cur]);
		while(cur != 0) {
			if (prev[cur] < 100) {
				System.out.printf("%d %d ", prev[cur] + 1, 0);
				cur ^= (1 << prev[cur]);
			} else {
				int i = prev[cur] / 100;
				int j = prev[cur] % 100;
				System.out.printf("%d %d %d ", i + 1, j + 1, 0);
				cur = cur ^ (1 << i) ^ (1 << j);
			}
		}
	}
	static int dist(int x0, int y0, int x1, int y1) {
		return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
	}
	static int NextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(NextToken());
	}
	static String NextToken() throws IOException {
		while(st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(reader.readLine());
		}
		return st.nextToken();
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = Integer.MAX_VALUE;
		int j = 0;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				if (j == 0) {
					ans = Math
							.min(ans, 2 * dist(0, i) + solve(mask | (1 << i)));
					j = i;
				} else
					ans = Math.min(ans, dist(0, i) + dist(i, j) + dist(j, 0)
							+ solve(mask | (1 << i) | (1 << j)));
			}
		return dp[mask] = ans;
	}

	static void prnt(int mask) {
		if (mask == (1 << n) - 1)
			return;
		int j = 0;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				if (j == 0) {
					j = i;
					if (dp[mask] == 2 * dist(0, i) + dp[mask | (1 << i)]) {
						out.print(" " + i + " 0");
						prnt(mask | (1 << i));
						return;
					}
				} else if (dp[mask] == dist(0, i) + dist(i, j) + dist(j, 0)
						+ solve(mask | (1 << i) | (1 << j))) {
					out.print(" " + i + " " + j + " 0");
					prnt(mask | (1 << i) | (1 << j));
					return;
				}
			}
	}

	public static void main(String[] args) throws IOException {
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		out.print(0);
		prnt(1 << 0);
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter out = new PrintWriter(System.out);

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.io.*;
import java.util.*;
//import java.lang.*;

public class Main {

	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		String input[] = kek.readLine().split(" ");
		int xH = Integer.parseInt(input[0]);
		int yH = Integer.parseInt(input[1]);
		int N = Integer.parseInt(kek.readLine());
		int xcoords[] = new int[N + 1];
		int ycoords[] = new int[N + 1];
		int dFromStart[] = new int[N + 1];
		int dFromEachOther[][] = new int[N + 1][N + 1];
		boolean taken[] = new boolean[N + 1];
		List<Integer> finalPath = new ArrayList<>();
		int minFromStart = 1;
		int mini = 0;
		int minj = 0;
		int objTrack = N;

		for(int i = 1; i <= N; i++){
			input = kek.readLine().split(" ");
			int x = Integer.parseInt(input[0]);
			int y = Integer.parseInt(input[1]);
			xcoords[i] = x;
			ycoords[i] = y;
			dFromStart[i] = getTime(xH, yH, x, y);
			minFromStart = dFromStart[minFromStart] > dFromStart[i] ? i : minFromStart;
			taken[i] = false;
		}
		int tempMin = 100000;
		for(int i = 1; i <= N; i++){
			int x = xcoords[i];
			int y = ycoords[i];
			for(int j = 1; j <= N; j++){
				int x2 = xcoords[j];
				int y2 = ycoords[j];
				if(j != i){
					dFromEachOther[i][j] = getTime(x, y, x2, y2);
					if(tempMin > dFromEachOther[i][j]){
						tempMin = dFromEachOther[i][j];
						mini = i;
						minj = j;
					}
				} else {
					dFromEachOther[i][j] = 10000;
				}
			}
		}

		finalPath.add(0);
		finalPath.add(mini);
		finalPath.add(minj);
		finalPath.add(0);
		objTrack -= 2;
		taken[mini] = true;
		taken[minj] = true;
		int res = dFromStart[mini];
		res += tempMin;
		res += dFromStart[minj]; //I left a system out in the last submission gah

		if(objTrack % 2 == 0){
			while(objTrack > 0){
				int coords[] = shortPath(dFromEachOther, taken, N);
				mini = coords[0];
				minj = coords[1];
				if(mini != -1 || minj != -1){
					finalPath.add(0);
					finalPath.add(mini);
					finalPath.add(minj);
					finalPath.add(0);
					objTrack -= 2;
					taken[mini] = true;
					taken[minj] = true;
					res += dFromStart[mini];
					res += tempMin;
					res += dFromStart[minj];
				}
			}
		} else {
			if(objTrack > 2){
				while(objTrack > 2){
					int coords[] = shortPath(dFromEachOther, taken, N);
					mini = coords[0];
					minj = coords[1];
					if(mini != -1 || minj != -1){
						finalPath.add(0);
						finalPath.add(mini);
						finalPath.add(minj);
						finalPath.add(0);
						objTrack -= 2;
						taken[mini] = true;
						taken[minj] = true;
						res += dFromStart[mini];
						res += tempMin;
						res += dFromStart[minj];
					}
				}
			}

			for(int c = 1; c <= N; c++){
				if(taken[c] == false){
					finalPath.add(c);
					finalPath.add(0);
					objTrack--;
					taken[c] = true;
					res += 2 * dFromStart[c];
				}
			}

		}

		System.out.println(res);
		for(int i : finalPath){
			System.out.print(i + " ");
		}

	}

	static int getTime(int x1, int y1, int x2, int y2){
		int x = (x2 - x1);
		int fx = x * x;
		int y = (y2 - y1);
		int fy = y * y;
		int result = fx + fy;
		return result;
	}

	static int[] shortPath(int[][] paths, boolean[] taken, int N){
		int coords[] = new int[2];
		int min = 10000;
		int m1 = -1;
		int m2 = -1;
		for(int i = 1; i <= N; i++){
			if(taken[i] == true){
				continue;
			}
			for(int j = 1; j <= N; j++){
				if(taken[j] == true){
					continue;
				} else {
					if(min > paths[i][j]){
						min = paths[i][j];
						m1 = i;
						m2 = j;
					}
				}
			}
		}

		coords[0] = m1;
		coords[1] = m2;

		return coords;
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            best[set] = best[set ^ (1 << i)] + single[i];
            prev[set] = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            for (int j = i + 1, unoJ = 1; j < n; ++j, unoJ <<= 1)
                if ((set & unoJ) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < best[set]) {
                        best[set] = cur;
                        prev[set] = unoI | unoJ;
                    }
                }
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C8
{

	public static long mod = 1000000007;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);
	static int n;
	static int x,y;
	static int[] xx;
	static int[] yy;
	static int[] dist;
	static int[][] g;
	static int[] dp;
	public static int square(int x)
	{
		return abs(x*x);
	}
	static class Pair
	{
		int x,y;
		Pair(int x,int y)
		{
			this.x=x;
			this.y=y;
		}
	}
	public static void main(String[] args)
	{

		x=in.nextInt();
		y=in.nextInt();
		n=in.nextInt();
		xx=new int[n];
		yy=new int[n];
		dp=new int[1<<n];
		for(int i=0;i<n;i++)
		{
			xx[i]=in.nextInt();
			yy[i]=in.nextInt();
		}
		dist=new int[n];
		g=new int[n][n];
		for(int i=0;i<n;i++)
		{
			dist[i]=square(abs(xx[i]-x))+square(abs(yy[i]-y));
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				g[i][j]=square(abs(xx[i]-xx[j]))+square(yy[i]-yy[j]);
				//System.out.println("i "+i+" j "+j+" "+g[i][j]);
			}
		}
		Arrays.fill(dp, Integer.MAX_VALUE/2);
		dp[0]=0;
		for(int i=0;i<(1<<n);i++)
		{
			//we have to find dp[i]
			for(int j=0;j<n;j++)
			{
				if((i&(1<<j))==0)   //not visited j
				{
				dp[i|(1<<j)]=min(dp[i|(1<<j)], dp[i]+2*dist[j]);
				}
				for(int k=0;k<n;k++)
				{
					if(k==j)
						continue;
					dp[i|(1<<j)|(1<<k)]=min(dp[i|(1<<j)|(1<<k)], dp[i]+dist[j]+dist[k]+g[j][k]);
				}

			}
		}
		out.println(dp[(1<<n)-1]);
		Set<Integer> alone=new HashSet<>();
		for(int i=0;i<n;i++)
		{
			if(dp[(1<<n)-1]==(dp[((1<<n)-1)^(1<<i)]+2*dist[i]))
				alone.add(i+1);
		}
		ArrayList<Pair> pairs=new ArrayList<>();
		for(int i=0;i<n;i++)
		{
			if(alone.contains(i+1))
				continue;
			for(int j=i+1;j<n;j++)
			{
				if(alone.contains(j+1))
					continue;
				if(dp[(1<<n)-1]==(dp[((1<<n)-1)^(1<<i)^(1<<j)]+dist[i]+dist[j]+g[i][j]))
				{
					pairs.add(new Pair(i+1, j+1));
				}
			}
		}
		out.print("0 ");
		for(int i : alone)
			out.print(i+" 0 ");
		for(Pair p : pairs)
		{
			out.print(p.x+" "+p.y+" 0 ");
		}
		out.close();

	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

		public int read()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = System.in.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

	static class InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream inputstream)
		{
			reader = new BufferedReader(new InputStreamReader(inputstream));
			tokenizer = null;
		}

		public String nextLine()
		{
			String fullLine = null;
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					fullLine = reader.readLine();
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
				return fullLine;
			}
			return fullLine;
		}

		public String next()
		{
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public long nextLong()
		{
			return Long.parseLong(next());
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

		public int nextInt()
		{
			return Integer.parseInt(next());
		}
	}

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
		}

		public OutputWriter(Writer writer)
		{
			this.writer = new PrintWriter(writer);
		}

		public void print(Object... objects)
		{
			for (int i = 0; i < objects.length; i++)
			{
				if (i != 0)
					writer.print(' ');
				writer.print(objects[i]);
			}
		}

		public void println(Object... objects)
		{
			print(objects);
			writer.println();
		}

		public void close()
		{
			writer.close();
		}

		public void flush()
		{
			writer.flush();
		}
	}

}

import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.HashSet;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alex
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
	    int handx = in.ri(), handy = in.ri();
	    int n = in.ri();
	    IntPair[] cords = new IntPair[n];
	    for(int i = 0; i < n; i++) {
		    int x = in.ri() - handx;
		    int y = in.ri() - handy;
		    cords[i] = new IntPair(x, y);
	    }
	    int[] perms = new int[n];
	    for(int i = 0; i < n; i++) perms[i] = i;
	    int ans = Integer.MAX_VALUE;
	    int[] ansarr = new int[1];
	    int[] bestnext = new int[1];
	    while(true){
		    int[] next = new int[n];
		    Arrays.fill(next, -1);
		    int best = dp(0, next, perms, cords);
		    if (best < ans){
			    ans = best;
			    ansarr = perms.clone();
			    bestnext = next;
		    }
		    if (!ArrayUtils.nextPermutation(perms)) break;
	    }
	    out.printLine(ans);
	    ArrayList<Integer> res = new ArrayList<>();
	    res.add(-1);
	    for(int i = 0; i < n; i++) {
		    res.add(ansarr[i]);
		    if (bestnext[i] == -1) res.add(-1);
	    }
	    for(int i : res) out.print((i + 1) + " ");
    }
	int dp(int cur, int[] next, int[] perms, IntPair[] cords){
		if (cur == perms.length) {
			return 0;
		}
		int[] nextfirst = next.clone();
		int takeone = 2 * cords[perms[cur]].first * cords[perms[cur]].first + 2 * cords[perms[cur]].second * cords[perms[cur]].second + dp(cur + 1, nextfirst, perms, cords);
		int taketwo = Integer.MAX_VALUE;
		if (cur < perms.length - 1){
			taketwo = cords[perms[cur]].first * cords[perms[cur]].first + cords[perms[cur]].second * cords[perms[cur]].second +
					(cords[perms[cur + 1]].first - cords[perms[cur]].first) * (cords[perms[cur + 1]].first - cords[perms[cur]].first) +
					(cords[perms[cur + 1]].second - cords[perms[cur]].second) * (cords[perms[cur + 1]].second - cords[perms[cur]].second) +
					cords[perms[cur + 1]].first * cords[perms[cur + 1]].first + cords[perms[cur + 1]].second * cords[perms[cur + 1]].second +
					dp(cur + 2, next, perms, cords);
		}
		if (takeone <= taketwo){
			nextfirst[cur] = -1;
			next = nextfirst;
			return takeone;
		}
		next[cur] = 1000;
		next[cur + 1] = -1;
		return taketwo;
	}
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int ri(){
		return readInt();
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IntPair implements Comparable<IntPair> {
public int first, second;

	public IntPair(int first, int second) {
		this.first = first;
		this.second = second;
	}
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;

		IntPair intPair = (IntPair) o;

		return first == intPair.first && second == intPair.second;

	}

	public int hashCode() {
		int result = first;
		result = 31 * result + second;
		return result;
	}

	public int compareTo(IntPair o) {
		if (first < o.first)
			return -1;
		if (first > o.first)
			return 1;
		if (second < o.second)
			return -1;
		if (second > o.second)
			return 1;
		return 0;
	}
}

class ArrayUtils {
	public static boolean nextPermutation(int[] array) {
		return new IntArray(array).nextPermutation();
	}
}

abstract class IntCollection {
	public abstract int size();
}

interface IntIterator {
	public int value() throws NoSuchElementException;
	public void advance() throws NoSuchElementException;
	public boolean isValid();
}

interface IntComparator {
    public static final IntComparator DEFAULT = new IntComparator() {
        public int compare(int first, int second) {
            if (first < second)
                return -1;
            if (first > second)
                return 1;
            return 0;
        }
    };
	public int compare(int first, int second);
}

abstract class IntList extends IntCollection implements Comparable<IntList> {
	public abstract int get(int index);
	public abstract void set(int index, int value);

	public IntIterator iterator() {
		return new IntIterator() {
			private int size = size();
			private int index = 0;

			public int value() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				return get(index);
			}

			public void advance() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				index++;
			}

			public boolean isValid() {
				return index < size;
			}
		};
	}
	public boolean nextPermutation() {
		return nextPermutation(IntComparator.DEFAULT);
	}

	private boolean nextPermutation(IntComparator comparator) {
		int size = size();
		int last = get(size - 1);
		for (int i = size - 2; i >= 0; i--) {
			int current = get(i);
			if (comparator.compare(last, current) > 0) {
				for (int j = size - 1; j > i; j--) {
					if (comparator.compare(get(j), current) > 0) {
						swap(i, j);
						subList(i + 1, size).inPlaceReverse();
						return true;
					}
				}
			}
			last = current;
		}
		return false;
	}

	public void inPlaceReverse() {
		for (int i = 0, j = size() - 1; i < j; i++, j--)
			swap(i, j);
	}

	public IntList subList(final int from, final int to) {
		return new SubList(from, to);
	}

	private void swap(int first, int second) {
		if (first == second)
			return;
		int temp = get(first);
		set(first, get(second));
		set(second, temp);
	}
	public int hashCode() {
		int hashCode = 1;
		for (IntIterator i = iterator(); i.isValid(); i.advance())
			hashCode = 31 * hashCode + i.value();
		return hashCode;
	}

	public boolean equals(Object obj) {
		if (!(obj instanceof IntList))
			return false;
		IntList list = (IntList)obj;
		if (list.size() != size())
			return false;
		IntIterator i = iterator();
		IntIterator j = list.iterator();
		while (i.isValid()) {
			if (i.value() != j.value())
				return false;
			i.advance();
			j.advance();
		}
		return true;
	}

	public int compareTo(IntList o) {
		IntIterator i = iterator();
		IntIterator j = o.iterator();
		while (true) {
			if (i.isValid()) {
				if (j.isValid()) {
					if (i.value() != j.value()) {
						if (i.value() < j.value())
							return -1;
						else
							return 1;
					}
				} else
					return 1;
			} else {
				if (j.isValid())
					return -1;
				else
					return 0;
			}
			i.advance();
			j.advance();
		}
	}
	private class SubList extends IntList {
        private final int to;
        private final int from;
        private int size;

        public SubList(int from, int to) {
            this.to = to;
            this.from = from;
            size = to - from;
        }

        public int get(int index) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            return IntList.this.get(index + from);
        }

        public void set(int index, int value) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            IntList.this.set(index + from, value);
        }

        public int size() {
            return size;
        }
	}
}
class IntArray extends IntList {
	private final int[] array;

	public IntArray(int[] array) {
		this.array = array;
	}
	public int get(int index) {
		return array[index];
	}

	public void set(int index, int value) {
		array[index] = value;
	}

	public int size() {
		return array.length;
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
static int n;
static int []x,y,memo;
static StringBuilder sb;
static int distance(int i,int j)
{
	int dx=x[i]-x[j];
	int dy=y[i]-y[j];
	return dx*dx+dy*dy;
}
public static int dp(int msk)
{
	if(msk==(1<<(n+1))-2)
		return 0;
	if(memo[msk]!=-1)
		return memo[msk];
	int ans=100000;
	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{
				int newM=msk|1<<i;
				newM|=1<<j;
				ans=Math.min(ans, dp(newM)+Math.min(distance(0,i)+distance(i,j)+distance(j,0), distance(0,j)+distance(j,i)+distance(i,0)));
			}
		return memo[msk]=ans;

}
public static void print(int msk)
{
	if(msk==(1<<(n+1))-2)
		return ;

	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{
				int newM=msk|1<<i;
				newM|=1<<j;
				int d1=distance(0,i)+distance(i,j)+distance(j,0);
				int d2=distance(0,j)+distance(j,i)+distance(i,0);
				if(dp(msk)== dp(newM)+Math.min(d1,d2));
				{

					if(i==j)
					{
						sb.append("0 "+i+" ");
					}
					else if(d1<d2)
						sb.append("0 "+i+""+j+" ");
					else
						sb.append("0 "+j+""+i+" ");

					print(newM);
					return ;
				}
			}

}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int xS=sc.nextInt(),yS=sc.nextInt();
		n=sc.nextInt();
		x=new int [n+1];
		y=new int [n+1];
		x[0]=xS;y[0]=yS;
		for(int i=1;i<=n;i++)
		{
			x[i]=sc.nextInt();
			y[i]=sc.nextInt();

		}
		memo=new int [1<<(n+1)];
		Arrays.fill(memo,-1);
		sb=new StringBuilder();

		sb.append(dp(0)+"\n");
		print(0);
		sb.append("0");
		System.out.println(sb);
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		public Scanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());

		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class B {
    static int[][] dist;
    static int [] dp;
    static int [] path;
    static int end,x,y;
    static Point[] a;
    public static int doit(int mask) {
        if(mask==end) return 0;
        if(dp[mask]!=-1) return dp[mask];
        int min=Integer.MAX_VALUE;
        boolean found=false;
        int t;
        for(int i=0;i<dist.length;i++) {
            if(((1<<i)|mask)==mask) continue;
            for(int j=i+1;j<dist.length;j++) {
                if(((1<<j)|mask)==mask) continue;
                found=true;
                t=dist[i][j]+doit(mask|(1<<i)|(1<<j));
                if(t<min) {
                    min=t;
                    path[mask]=(1<<i)|(1<<j);
                }
            }
            if(!found) {
                path[mask]=1<<i;
                return dp[mask]=2*((a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y));
            }
        }
        return dp[mask]=min;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
         x=sc.nextInt();y=sc.nextInt();
         a=new Point[sc.nextInt()];
        for(int i=0;i<a.length;i++) {
            a[i]=new Point(sc.nextInt(), sc.nextInt());
        }
        end=(1<<a.length)-1;
        dp=new int[1<<a.length];
        Arrays.fill(dp, -1);
        dist=new int[a.length][a.length];
        for(int i=0;i<a.length;i++) {
            for(int j=i+1;j<a.length;j++) {
                dist[i][j]=(a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y) +
                (a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+
                (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                //System.out.println(dist[i][j]);
            }
        }
        path=new int[dp.length];
        System.out.println(doit(0));
        int e=(int) Math.ceil(a.length/2.0);
        int cur=path[0];
        StringBuffer bf=new StringBuffer();
        bf.append(0+" ");
        for(int i=0;i<e;i++) {
            //System.out.println(Integer.toBinaryString(cur));
            for(int j=0;j<a.length;j++) {
                if(((1<<j)|cur)==cur) {
                    bf.append((j+1)+" ");
                }
            }
            cur=path[cur];
            bf.append(0+" ");
        }
        System.out.println(bf);
    }
}

import java.io.*;
import java.util.*;

public class Solution {
    BufferedReader in;
    StringTokenizer st;
    PrintWriter out;

    public Solution() throws Exception {
	in = new BufferedReader(new InputStreamReader(System.in));
	out = new PrintWriter(System.out);
    }

    public String next() throws Exception {
	if (st == null || !st.hasMoreTokens()) {
	    st = new StringTokenizer(in.readLine());
	}
	return st.nextToken();
    }

    public int nextInt() throws Exception {
	return Integer.parseInt(next());
    }

    public long nextLong() throws Exception {
	return Long.parseLong(next());

    }

    public double nextDouble() throws Exception {
	return Double.parseDouble(next());
    }

    public static void main(String[] args) throws Exception {
	new Solution().run(args);
    }

    public int dist(int x0, int y0, int x1, int y1) {
	return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
    }

    public void run(String[] args) throws Exception {
	int x0 = nextInt();
	int y0 = nextInt();
	int n = nextInt();
	int[] x = new int[n];
	int[] y = new int[n];
	int[][] d = new int[n + 1][n + 1];
	for (int i = 0; i < n; ++i) {
	    x[i] = nextInt();
	    y[i] = nextInt();
	}

	for (int i = 0; i < n; ++i) {
	    for (int j = i + 1; j < n; ++j) {
	    	d[i + 1][j + 1] = d[j + 1][i + 1] = dist(x[i], y[i], x[j], y[j]);
		d[i + 1][0] = d[0][i + 1] = dist(x0, y0, x[i], y[i]);
	    	d[0][j + 1] = d[j + 1][0] = dist(x0, y0, x[j], y[j]);
	    }
	}

	int[] s = new int[(1 << n)];
	int[] path = new int[(1 << n)];
	Arrays.fill(s, Integer.MAX_VALUE / 2);
	s[0] = 0;
	for (int mask = 0; mask < (1 << n); ++mask) {
	    for (int i = 0; i < n; ++i) {
		if ((mask & (1 << i)) == 0) {
		    for (int j = i; j < n; ++j) {
			if ((mask & (1 << j)) == 0) {
			    int newmask = mask | (1 << i) | (1 << j);
			    if (s[newmask] > s[mask] + d[0][i + 1] + d[i + 1][j + 1] + d[0][j + 1]) {
				s[newmask] = s[mask] + d[0][i + 1] + d[i + 1][j + 1] + d[0][j + 1];
				path[newmask] = mask;
			    }
			}
		    }
		}
	    }
	}
	int f = (1 << n) - 1;
	out.println(s[f]);
	LinkedList<Integer> p = new LinkedList<Integer>();
	p.add(0);
	while(f != 0) {
	    int pf = f ^ path[f];
	    for (int i = 0; i < n; ++i) {
		if (((pf >> (i)) & 1) == 1) {
		    p.add(i + 1);
		}
	    }
	    p.add(0);
	    f = path[f];
	}
	out.print(p.pollLast());
	while(!p.isEmpty()) {
	    out.print(" " + p.pollLast());
	}
	out.println();
	in.close();
	out.close();
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Task8C {

	private static int n;
	// private static Stack<Integer> stack = new Stack<>();
	private static int[][] timeTable;
	private static boolean[] mask;

	public static void main(String[] args) {
		go(System.in);
	}

	public static void go(InputStream is) {
		XY bag = null;
		XY[] things;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			bag = new XY(br.readLine());
			n = Integer.parseInt(br.readLine());
			things = new XY[n + 1];
			timeTable = new int[n + 1][n + 1];
			mask = new boolean[n + 1];
			for (int i = 1; i <= n; i++) {
				things[i] = new XY(br.readLine());
				// stack.push(i);
			}
		} catch (IOException e) {
			System.out.println(e);
			return;
		}
		for (int i = 1; i <= n; i++) {
			int time = (bag.x - things[i].x) * (bag.x - things[i].x) + (bag.y - things[i].y) * (bag.y - things[i].y);
			timeTable[0][i] = time;
		}
		for (int i = 1; i < n; i++) {
			for (int j = i + 1; j <= n; j++) {
				int time = (things[j].x - things[i].x) * (things[j].x - things[i].x)
						+ (things[j].y - things[i].y) * (things[j].y - things[i].y);
				timeTable[i][j] = time + timeTable[0][i] + timeTable[0][j];
				// timeTable[j][i] = time + timeTable[0][i] + timeTable[0][j];
			}
		}
		Result res = find(0);
		System.out.println(res.time);
		System.out.print("0");
		for (XY xy : res.path) {
			System.out.print(" " + (xy.x != 0 ? xy.x + " " : "") + xy.y + " 0");
		}
		System.out.println();
	}

	private static Result find(int index) {
		//System.out.println("find " + index);
		Result result = new Result();
		int index1 = index + 1;
		while (index1 < n && mask[index1]) {
			index1++;
		}
		if (index1 == n) {
			result.path.add((new XY(0, index1)));
			result.time = timeTable[0][index1] << 1;
			//System.out.println("push 0, " + index1);
			return result;
		}
		if (index1 == n - 1) {
			result.path.add((new XY(index1, index1 + 1)));
			result.time = timeTable[index1][index1 + 1];
			//System.out.println("push " + index1 + ", " + (index1 + 1));
			return result;
		}
		mask[index1] = true;

		Result best = find(index1);
		best.time = (timeTable[0][index1] << 1) + best.time;
		best.path.add(new XY(0, index1));

		int index2 = index1 + 1;

		while (index2 < n) {

			while (index2 < n && mask[index2]) {
				index2++;
			}

			mask[index2] = true;
			Result newRes = find(index1);
			newRes.time = timeTable[index1][index2] + newRes.time;
			if (newRes.time < best.time) {
				best = newRes;
				best.path.add(new XY(index1, index2));
			}
			mask[index2] = false;
			index2++;
		}
		//System.out.println("push " + minIndex1 + ", " + minIndex2);
		return best;

	}

	static class Result {
		List<XY> path = new ArrayList<>();
		int time = 0;
	}

	static class XY {
		int x;
		int y;

		public XY() {

		}

		public XY(int x, int y) {
			this.x = x;
			this.y = y;
		}

		public XY(String str) {
			String[] strs = str.split(" ");
			x = Integer.parseInt(strs[0]);
			y = Integer.parseInt(strs[1]);
		}
	}
}

import java.util.*;

/**
 * @author vstepanov on 3/29/2017.
 */
public class Main {
    static int[][] xy;
    static int bx;
    static int by;
    static boolean[] gathered;
    static double minTime = Integer.MAX_VALUE;
    static List<Integer> minPath = new ArrayList<>();

    public static void main(String[] args) {
        try(Scanner in = new Scanner(System.in)) {
            bx = in.nextInt();
            by = in.nextInt();
            int n = in.nextInt();
            xy = new int[n][2];
            Map<Integer, Double> time = new HashMap<>();
            for (int i = 0; i < n; i++) {
                xy[i] = new int[]{in.nextInt(), in.nextInt()};
            }
            gathered = new boolean[n];
            recv(0, 0, bx, by, n, new LinkedList<>());
            System.out.println(minTime);
            for (Integer integer : minPath) {
                System.out.print(integer + " ");
            }
            System.out.println();
        }
    }

    static void recv(double time, int taken, int x, int y, int left, LinkedList<Integer> path) {
        if (taken == 2 || left == 0) {
            time += time(x, y, bx, by);
            taken = 0;
            x = bx;
            y = by;
            path.add(0);
        }
        if (left == 0 && minTime > time) {
            minTime = time;
            minPath = new ArrayList<>(xy.length);
            minPath.add(0);
            minPath.addAll(path);
        }
        for (int i = 0; i < xy.length; i++) {
            if (!gathered[i]) {
                gathered[i] = true;
                path.add(i + 1);
                recv(time + time(x, y, xy[i][0], xy[i][1]), taken + 1, xy[i][0], xy[i][1], left - 1, path);
                gathered[i] = false;
                path.removeLast();
            }
        }
    }

    static int take(int i) {
        return 1 << i;
    }

    static double time(double x, double y, double x1, double y1) {
        return (x - x1)*(x - x1) + (y - y1)*(y - y1);
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	static int[][] pos;
	static int[] dp;
	static int[] nextstate;
	static int[][] dist;
	static int r;
	static int v;

	static void print(int mask) {
		if (mask < v) {
			int c = 0;
			int x = mask ^ nextstate[mask];
			for (int i = 0; i < dist.length - 1; i++) {
				if((x & (1<<i))>0) {
					System.out.print(i+1 + " ");
					c++;
				}
			}
			if(c == 1)System.out.print("0 ");
			print(nextstate[mask]);
		}
	}

	static int distace(int x1, int x2, int y1, int y2) {
		return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
	}

	static int solve(int mask) {
		if (mask == v) {
			nextstate[mask] = r;

			return 0;
		}
		if (nextstate[mask] != 0) {
			return dp[mask];
		}

		dp[mask] = (int) 1e9;
		for (int i = 1; i < pos.length; i++) {
			int u = (1 << (i - 1));
			int z = mask | u;
			if ((mask & u) == 0) {
				int x = 2 * dist[i][0] + solve(z);
				if (dp[mask] > x) {
					dp[mask] = x;
					nextstate[mask] = z;
				}

				for (int j = 1; j < pos.length; j++) {
					int m = (1 << j - 1);
					int y = z | m;
					if ((z & m) == 0) {
						x = dist[i][0] + solve(y) + dist[i][j] + dist[j][0];

						if (dp[mask] > x) {
							dp[mask] = x;
							nextstate[mask]= y;
						}

					}
				}
				break;
			}
		}
		return dp[mask];
	}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(), y = in.nextInt();
		int n = in.nextInt();
		r = 1 << n;
		v = r - 1;
		dp = new int[r];
		nextstate = new int[r];
		pos = new int[n + 1][2];
		pos[0][0] = x;
		pos[0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos[i][0] = in.nextInt();
			pos[i][1] = in.nextInt();
		}
		dist = new int[n + 1][n + 1];
		for (int i = 0; i < dist.length; i++) {
			for (int j = i + 1; j < dist.length; j++) {
				dist[i][j] = dist[j][i] = distace(pos[i][0], pos[j][0], pos[i][1], pos[j][1]);
			}
		}

		System.out.println(solve(0));
		System.out.print("0 ");
		print(0);
	}

}

class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.awt.*;
import java.io.*;
import java.util.*;

public class Abc {
    static Point p[];
    static int dp[];
    static int n;
    static Point s;
    static int ans[];
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        s=new Point(sc.nextInt(),sc.nextInt());
        n=sc.nextInt();
        p=new Point[n];
        for (int i=0;i<n;i++){
            p[i]=new Point(sc.nextInt(),sc.nextInt());
        }
        dp=new int[1<<n];
        ans=new int[1<<n];
        Arrays.fill(dp,-1);
        System.out.println(dp(0));
        int i=0;
        StringBuilder sb=new StringBuilder();
        sb.append(0+" ");
        while (i!=(1<<n)-1){
            int x=ans[i];
            for (int j=0;j<n;j++){
                if ((x&(1<<j))!=0){
                    sb.append((j+1)+" ");
                }
            }
            i=(i|x);
            sb.append(0+" ");
        }
        System.out.println(sb);
    }
    static int dp(int mask){
        if (mask==(1<<n)-1)return 0;
        if (dp[mask]!=-1)return dp[mask];
        int i=-1,j=-1;
        for (int k=0;k<n;k++){
            if ((mask&(1<<k))==0){
                if (i==-1 || j==-1){
                    j=i;
                    i=k;
                }else break;
            }
        }
        int a=Integer.MAX_VALUE;
        if (i!=-1 && j!=-1){
            int a1=dp(mask|(1<<i))+2*dist(p[i],s);
            int a2=dp(mask|(1<<j))+2*dist(p[j],s);
            int a3=dp(mask+(1<<i)+(1<<j))+dist(p[i],p[j])+2*dist(s,p[i]);
            if (a>a1){
                a=a1;
                ans[mask]=(1<<i);
            }
            if (a>a2){
                a=a2;
                ans[mask]=(1<<j);
            }
            if (a>a3){
                a=a3;
                ans[mask]=(1<<i)+(1<<j);
            }
        }else {
            int a1=dp(mask|(1<<i))+2*dist(p[i],s);
            if (a>a1){
                a=a1;
                ans[mask]=(1<<i);
            }
        }
        return dp[mask]=a;
    }
    static int dist(Point p1,Point p2){
        return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
    }
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

import java.io.*;
import java.util.*;

public class CF8A {
	FastScanner in;
	PrintWriter out;

	int[] x, y;

	int dist(int v, int u) {
		return (x[v] - x[u]) * (x[v] - x[u]) + (y[v] - y[u]) * (y[v] - y[u]);
	}

	void solve() {
		int x1 = in.nextInt();
		int y1 = in.nextInt();
		int n = in.nextInt();

		x = new int[n + 1];
		y = new int[n + 1];
		for (int i = 1; i <= n; i++) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
		}
		x[0] = x1;
		y[0] = y1;
		long[][] dp = new long[(1 << n)][n + 1];
		int[][][] dpFrom = new int[1 << n][n + 1][3];
		for (int st = 0; st < (1 << n); st++)
			for (int pos = 0; pos < n + 1; pos++)
				dp[st][pos] = Long.MAX_VALUE;
		dp[0][0] = 0;
		for (int st = 0; st < (1 << n); st++)
			for (int pos = 0; pos < n + 1; pos++)
				if (dp[st][pos] != Long.MAX_VALUE)
					for (int next = 0; next <= n; next++)
						if (next == 0) {
							if (pos != 0) {
								long val = dp[st][pos] + dist(pos, next);
								if (dp[st][0] > val) {
									dp[st][0] = val;
									dpFrom[st][0][0] = st;
									dpFrom[st][0][1] = pos;
									dpFrom[st][0][2] = -1;
								}
							}
						} else {
							if (((1 << (next - 1)) & st) != (1 << (next - 1))) {
								long val = dp[st][pos] + dist(pos, next);
								if (pos != 0) {
									val += dist(0, next);
									if (dp[st | (1 << (next - 1))][0] > val) {
										dp[st | (1 << (next - 1))][0] = val;
										dpFrom[st | (1 << (next - 1))][0][0] = st;
										dpFrom[st | (1 << (next - 1))][0][1] = pos;
										dpFrom[st | (1 << (next - 1))][0][2] = next;
									}
								} else {
									if (dp[st | (1 << (next - 1))][next] > val) {
										dp[st | (1 << (next - 1))][next] = val;
										dpFrom[st | (1 << (next - 1))][next][0] = st;
										dpFrom[st | (1 << (next - 1))][next][1] = pos;
										dpFrom[st | (1 << (next - 1))][next][2] = -1;
									}
								}
							}
						}
		out.println(dp[(1 << n) - 1][0]);
		int nowSt = (1 << n) - 1;
		int nowPos = 0;
		ArrayList<Integer> ans = new ArrayList<Integer>();
		while (nowSt != 0 || nowPos != 0) {
			ans.add(nowPos);
			int newSt = dpFrom[nowSt][nowPos][0];
			int newPos = dpFrom[nowSt][nowPos][1];
			if (dpFrom[nowSt][nowPos][2] != -1)
				ans.add(dpFrom[nowSt][nowPos][2]);
			nowPos = newPos;
			nowSt = newSt;
		}
		out.print("0 ");
		for (int i = ans.size() - 1; i >= 0; i--)
			out.print(ans.get(i) + " ");
	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}
	}

	public static void main(String[] args) {
		new CF8A().runIO();
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	int [][] pos;
	int [] dp;
	int [][]nextstate;

	public LookingForOrder(int[][] pos, int[] dp, int[][]nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.nextstate = nextstate;
	}
	void print(int mask) {
		if(mask < (1<<pos.length - 1) - 1 ) {
			if (nextstate[mask][2] != 0) {
				System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" "+ 0+" ");
			}
			else
			System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" ");
			print(nextstate[mask][1]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask) {
		if(mask == (1<<pos.length - 1) - 1 ) {
			nextstate [mask][0] = 0;
			nextstate[mask][1] = 1<<pos.length;

			return	0 ;
		}
		if (dp [mask]!= 0) {
			return dp[mask];
		}

			dp[mask] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i - 1)) == 0) {
					int x = 2 * distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<(i - 1))));
					if(dp[mask] > x) {
						dp[mask] = x;
						nextstate[mask][0] = i;
						nextstate[mask][1]= (mask | (1<<i - 1));
						nextstate[mask][2] = 0;

					for (int j = i + 1; j < pos.length; j++) {
						if (((mask | (1<<i - 1)) & (1<<j - 1)) == 0) {
							x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve(((mask | (1<<i - 1)) | (1<<j - 1)))
							+ distace(pos[j][0], pos[i][0], pos[j][1], pos[i][1])+distace(pos[0][0], pos[j][0], pos[0][1], pos[j][1]) ;

							if(dp[mask] > x) {
								dp[mask] = x;
								nextstate[mask][0] = i;
								nextstate[mask][1]= (mask | (1<<i - 1)) | (1<<j - 1);
								nextstate[mask][2] = j;
							}
							break;
						}
					}}
				}
			}
			return dp[mask];
		}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n)],  new int[1<<(n)][3]);
		System.out.println(z.solve(0));
		System.out.print(0+" ");
		z.print(0);
	}

}
class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
*/
import java.util.*;
import java.io.*;

   public class x8C
   {
      public static void main(String args[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int Xs = Integer.parseInt(st.nextToken());
         int Ys = Integer.parseInt(st.nextToken());
         int N = Integer.parseInt(infile.readLine());
         int[] x = new int[N];
         int[] y = new int[N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            x[i] = Integer.parseInt(st.nextToken());
            y[i] = Integer.parseInt(st.nextToken());
         }
         //precompute
         int[] purse = new int[N];
         int[][] grid = new int[N][N];
         for(int i=0; i < N; i++)
            purse[i] = dist(Xs, Ys, x[i], y[i]);
         for(int a=0; a < N; a++)
            for(int b=a; b < N; b++)
            {
               grid[a][b] = dist(x[a], y[a], x[b], y[b]);
               grid[b][a] = grid[a][b];
            }
         //solve
         //always best to pick 2 items then return (vector shit)
         int[] parent = new int[1 << N];
         parent[0] = -1;
         int[] dp = new int[1 << N];
         Arrays.fill(dp, Integer.MAX_VALUE);
         dp[0] = 0;
         for(int mask=0; mask < dp.length-1; mask++)
         {
            int bc = Integer.bitCount(mask);
            int a = 100;
            for(int i=0; i < N; i++)
               if((mask & (1 << i)) == 0)
               {
                  int submask2 = mask|(1 << i);
                  int addon2 = purse[i] << 1;
                  if(dp[submask2] > dp[mask]+addon2)
                  {
                     dp[submask2] = dp[mask]+addon2;
                     parent[submask2] = mask;
                  }
                  a = Math.min(a, i);
               }
            //first item
            for(int i=0; i < N; i++)
            {
               int submask = mask|(1 << a);
               submask |= 1 << i;
               int addon = purse[a]+purse[i]+grid[a][i];
               if(dp[submask] > dp[mask]+addon)
               {
                  dp[submask] = dp[mask]+addon;
                  parent[submask] = mask;
               }
            }
         }
         StringBuilder sb = new StringBuilder();
         sb.append(dp[dp.length-1]+"\n");
         //process dp path
         Stack<Integer> stack = new Stack<Integer>();
         int curr = dp.length-1;
         while(parent[curr] != -1)
         {
            stack.push(curr);
            curr = parent[curr];
         }
         stack.push(curr);
         ArrayList<Integer> path = new ArrayList<Integer>();
         int a = stack.pop();
         int lol = stack.size();
         for(int qw=0; qw < lol; qw++)
         {
            path.add(0);
            int b = stack.pop();
            int c = a^b;
            for(int i=0; i < N; i++)
               if((c & (1 << i)) > 0)
                  path.add(i+1);
            a = b;
         }
         path.add(0);
         for(int x1: path)
            sb.append(x1+" ");
         System.out.println(sb.toString());
      }
      public static int dist(int a, int b, int c, int d)
      {
         return (a-c)*(a-c)+(b-d)*(b-d);
      }
   }

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;
/**
 * 9:50 ~
 *
 */
public class Main {
	public static int n, x, y;
	public static int[] a,b;
	public static int dp[];
	public static final int INF = 24 * 201 * 201;
	public static void main(String[] argv) {
		FastScanner scan = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		x = scan.nextInt();
		y = scan.nextInt();

		n = scan.nextInt();

		a = new int[n+1];
		b = new int[n+1];

		for(int i = 0; i < n; ++i){
			a[i] = scan.nextInt();
			b[i] = scan.nextInt();
		}

		dp = new int[1 << n];
		Arrays.fill(dp, INF);
		dp[0] = 0;
		for(int state = 0; state < (1<<n); state++){
			for(int i = 0; i < n; ++i){
				if((state & (1 << i)) > 0){
					dp[state] = Math.min(dp[state], dp[state - (1<<i)] + dist(i) + dist(i));
				} else continue;

				for(int j = 0; j < n; ++j){
					if(i == j) continue;
					if((state & (1 << j)) > 0){
						dp[state] = Math.min(dp[state], dp[state - (1<<i) - (1<<j)] + dist(i) + dist(i, j) + dist(j));
					}
				}
			}
		}

		int state = (1<<n) - 1;
		String ret = "";
		while(state > 0){
			int min = INF, ret1 = -1, ret2 = -1, nstate = state;
			for(int i = 0; i < n; ++i){
				if((state & (1 << i)) > 0){
					if(min > dp[state - (1 << i)]){
						min = dp[state - (1<<i)];
						ret1 = i;
						nstate = state - (1<<i);
					}
				} else continue;

				for(int j = 0; j < n; ++j){
					if(i == j) continue;
					if((state & (1<<j)) > 0){
						if(min > dp[state - (1<<i) - (1<<j)]){
							min = dp[state - (1<<i) - (1<<j)];
							ret1 = i;
							ret2 = j;
							nstate = state - (1<<i) - (1<<j);
						}
					}
				}
			}
			state = nstate;
			ret = (ret1+1) + " 0 " + ret;
			if(ret2 != -1) ret = (ret2+1) + " " + ret;
		}
		out.println(dp[(1<<n)-1]);
		out.println("0 " + ret);
		out.close();
	}
	public static int dist(int to){
		return Math.abs(a[to] - x) * Math.abs(a[to] - x) + Math.abs(b[to] - y) * Math.abs(b[to] - y);
	}
	public static int dist(int from, int to){
		return Math.abs(a[from]-a[to]) * Math.abs(a[from]-a[to]) + Math.abs(b[from]-b[to]) * Math.abs(b[from]-b[to]);
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(InputStream is) {
			try {
				br = new BufferedReader(new InputStreamReader(is));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					return null;
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.valueOf(next());
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	int [][] pos;
	int [] dp;
	int [][]nextstate;

	public LookingForOrder(int[][] pos, int[] dp, int[][]nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.nextstate = nextstate;
	}
	void print(int mask) {
		if(mask < (1<<pos.length - 1) - 1 ) {
			if (nextstate[mask][2] != 0) {
				System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" "+ 0+" ");
			}
			else
			System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" ");
			print(nextstate[mask][1]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask) {
		if(mask == (1<<pos.length - 1) - 1 ) {
			nextstate [mask][0] = 0;
			nextstate[mask][1] = 1<<pos.length;

			return	0 ;
		}
		if (dp [mask]!= 0) {
			return dp[mask];
		}

			dp[mask] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i - 1)) == 0) {
					int x = 2 * distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<(i - 1))));
					if(dp[mask] > x) {
						dp[mask] = x;
						nextstate[mask][0] = i;
						nextstate[mask][1]= (mask | (1<<i - 1));
						nextstate[mask][2] = 0;}

					for (int j = i + 1; j < pos.length; j++) {
						if (((mask | (1<<i - 1)) & (1<<j - 1)) == 0) {
							x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve(((mask | (1<<i - 1)) | (1<<j - 1)))
							+ distace(pos[j][0], pos[i][0], pos[j][1], pos[i][1])+distace(pos[0][0], pos[j][0], pos[0][1], pos[j][1]) ;

							if(dp[mask] > x) {
								dp[mask] = x;
								nextstate[mask][0] = i;
								nextstate[mask][1]= (mask | (1<<i - 1)) | (1<<j - 1);
								nextstate[mask][2] = j;
							}
							break;
						}
					}
				}
			}
			return dp[mask];
		}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n)],  new int[1<<(n)][3]);
		System.out.println(z.solve(0));
		System.out.print(0+" ");
		z.print(0);
	}

}
class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class CF008C {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int x = s.nextInt();
        int y = s.nextInt();
        int n = s.nextInt();
        int[] xCoord = new int[n];
        int[] yCoord = new int[n];
        for(int i = 0;i<n;i++){
            xCoord[i] = s.nextInt();
            yCoord[i] = s.nextInt();
        }
        int[][] dp = new int[n][n];
        for(int i = 0;i<n;i++){
            Arrays.fill(dp[i],-1);
        }
        for(int i = 0;i<n;i++){
            dp[i][i] = 0;
            for(int j = 0;j<i;j++){
                dp[i][j] = calculateDistanceBetweenIandJ(xCoord,yCoord,i,j);
                dp[j][i] = dp[i][j];
            }
        }
        int[] distFromOrigin = new int[n];
        HashMap<Integer,Boolean> map = new HashMap<>();
        for(int i=0;i<n;i++){
            distFromOrigin[i] = (int) (Math.pow((xCoord[i] - x),2) + Math.pow(yCoord[i] - y,2));
            map.put(i,true);
        }
//        System.out.println(0);
        long sum = 0;
        String str = "0 ";

        while(!map.isEmpty()){
            int first = 0;
            int second = Integer.MIN_VALUE;
            if(map.size() == 1){
                first = new ArrayList<Integer>(map.keySet()).get(0) + 1;
                map.remove(first - 1);
            }else {
                int min = Integer.MAX_VALUE;

                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < i; j++) {
                        if (map.containsKey(i) && map.containsKey(j) && distFromOrigin[i] + distFromOrigin[j] + dp[i][j] < min) {
                            min = distFromOrigin[i] + distFromOrigin[j] + dp[i][j];
                            first = i + 1;
                            second = j + 1;
                        }
                    }
                }
                sum += min;
                map.remove(first - 1);
                map.remove(second - 1);
            }
            if(second == Integer.MIN_VALUE){
                str = str + first + " ";
            }else{
                if(map.size() == 0) {
                    str = str + first + " " + second + " ";
                }else{
                    str = str + first + " " + second + " 0 ";
                }
            }
//            System.out.print(first + " " + second + " ");
        }
        System.out.println(sum);
        System.out.println(str + "0");

//        System.out.print(sum);
//        System.out.print(0);
    }

    private static int calculateDistanceBetweenIandJ(int[] xCoord, int[] yCoord, int i, int j) {
        int length = (int) (Math.pow((xCoord[i] - xCoord[j]),2) + Math.pow(yCoord[i] - yCoord[j], 2));
        return length;
    }
}

import java.awt.Point;
import java.util.Scanner;

public class LookingForOrder {
	int [][] pos;
	int [][][] dp;
	boolean [][][]visited;
	int [][][]nextstate;

	public LookingForOrder(int[][] pos, int[][][] dp, boolean[][][] visited, int[][][] nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.visited = visited;
		this.nextstate = nextstate;
	}
	void print(int mask,int n) {
		if(mask <= (1<<pos.length) - 1 ) {
			System.out.print(nextstate[mask][n][0] + " ");
			print(nextstate[mask][n][1], nextstate[mask][n][2]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask,int idx,int n) {
		if(mask == (1<<pos.length) - 1 ) {
			nextstate [mask][n][0] = 0;
			nextstate[mask][n][1] = 1<<pos.length;
			nextstate[mask][n][2] = 1;

			return	distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) ;
		}
		if (visited [mask][n][idx]) {
			return dp[mask][n][idx];
		}
		visited [mask][n][idx] = true;
		if(idx == 0) {
			dp[mask][n][idx] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i)) == 0) {
					int x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<i)), i, 1);
					if(dp[mask][n][idx] > x) {
						dp[mask][n][idx] = x;
						nextstate[mask][n][0] = i;
						nextstate[mask][n][1] = (mask | (1<<i));
						nextstate[mask][n][2] = 1;
					}
				}
			}
			return dp[mask][n][idx];
		}
		if(n == 2) {
			nextstate[mask][n][0] = 0;
			nextstate[mask][n][1] = mask;
			nextstate[mask][n][2] = 0;
			return dp[mask][n][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		}
		dp[mask][n][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		nextstate[mask][n][0] = 0;
		nextstate[mask][n][1] = mask ;
		nextstate[mask][n][2] = 0;
		for (int i = 1; i < pos.length; i++) {
			if ((mask & (1<<i)) == 0) {
				int x = distace(pos[idx][0], pos[i][0], pos[idx][1], pos[i][1]) + solve((mask | (1<<i)), i, 2);
				if(dp[mask][n][idx] > x) {
					dp[mask][n][idx] = x;
					nextstate[mask][n][0] = i;
					nextstate[mask][n][1] = (mask | (1<<i));
					nextstate[mask][n][2] = 2;
				}

			}
		}
		return dp[mask][n][idx];
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n + 1)][3][n+1], new boolean[1<<(n + 1)][3][n+1], new int[1<<(n + 1)][3][3]);
		System.out.println(z.solve(1, 0, 0));
		System.out.print(0+" ");
		z.print(1, 0);
	}

}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 111118315581
 *
 * @author pttrung
 */
public class C {

    static Point hand;
    static int n;
    static Point[] data;
    static int[] next;
    static int[] dp;
    static int[][] pre;

    public static void main(String[] args) {
        Scanner in = new Scanner();
        PrintWriter out = new PrintWriter(System.out);
        // System.out.println(1 << 24);
        hand = new Point(in.nextInt(), in.nextInt());
        n = in.nextInt();
        data = new Point[n];
        for (int i = 0; i < n; i++) {
            data[i] = new Point(in.nextInt(), in.nextInt());
        }
        pre = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                pre[i][j] = distance(data[i], data[j]);
            }
        }

        next = new int[1 << n];
        dp = new int[1 << n];
        Arrays.fill(dp, -1);

        out.println(cal(0));

        int start = 0;

        do {
            int m = next[start];
            int val = m - start;
            out.print(0 + " ");
            for (int i = 0; i < n; i++) {
                if (((1 << i) & val) != 0) {
                    out.print((i + 1) + " ");
                }
            }
            // out.print(0 + " ")  ;
            start = m;
        } while (start != (1 << n) - 1);
        out.println(0);
        out.close();
    }

    public static int cal(int mask) {
        if ((1 << n) - 1 == mask) {
            //  System.out.println(mask);
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (((1 << i) & mask) == 0) {
                int dist = distance(hand, data[i]);
                boolean found = false;
                for (int j = i + 1; j < n; j++) {
                    if (((1 << j) & mask) == 0 && pre[i][j] < dist + distance(hand, data[j])) {
                        //System.out.println(i + " " + j);
                        int temp = dist + distance(hand, data[j]) + pre[i][j] + cal(mask | (1 << i) | (1 << j));
                        //System.out.println(temp);
                        if (temp < result) {
                            result = temp;
                            next[mask] = (mask | (1 << i) | (1 << j));
                        }
                        found = true;
                    }
                }
                if (!found) {
                    int temp = 2 * dist + cal(mask | (1 << i));
                    if (temp < result) {
                        result = temp;
                        next[mask] = (mask | (1 << i));
                    }
                }
                break;
            }

        }
        dp[mask] = result;
        return result;
    }

    static int distance(Point a, Point b) {
        int total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return total;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main implements Runnable {

	// ////////////////////////////////////////////////////////////////////
	// Solution

	int[] use;
	int[] bestUse;
	int res;
	int[][] D;

	private void solve() throws Throwable {
		// init
		int xs = nextInt(), ys = nextInt();
		int n = nextInt();
		int[][] pts = new int[n + 1][2];
		pts[0][0] = xs;
		pts[0][1] = ys;
		for (int i = 1; i <= n; i++) {
			pts[i][0] = nextInt();
			pts[i][1] = nextInt();
		}
		D = new int[n + 1][n + 1];
		for (int i = 1; i < n + 1; i++) {
			for (int j = 1; j < n + 1; j++) {
				if (i == j) {
					D[i][i] = sqr(pts[i][0] - pts[0][0])
					+ sqr(pts[i][1] - pts[0][1])
					+ sqr(pts[j][0] - pts[0][0])
					+ sqr(pts[j][1] - pts[0][1]);
				} else {
					D[i][j] = sqr(pts[i][0] - pts[j][0])
							+ sqr(pts[i][1] - pts[j][1])
							+ sqr(pts[i][0] - pts[0][0])
							+ sqr(pts[i][1] - pts[0][1])
							+ sqr(pts[j][0] - pts[0][0])
							+ sqr(pts[j][1] - pts[0][1]);
				}
			}
		}
		use = new int[n + 1];
		res = Integer.MAX_VALUE;
		solve(0, 0, 1);
		pw.println(res);
		use = bestUse;
		int mark = 1;
		while (true) {
			pw.print(0);
			pw.print(' ');
			boolean found = false;
			for (int i = 1; i < use.length; i++) {
				if (use[i] == mark) {
					found = true;
					pw.print(i);
					pw.print(' ');
				}
			}
			mark++;
			if (!found) break;
		}
		pw.println();
	}

	private void solve(int n, int csum, int mark) {
		if (use.length - 1 - n <= 1) {
			if (use.length % 2 == 0) {
				for (int i = 1; i < use.length; i++) {
					if (use[i] == 0) {
						use[i] = mark;
						csum += D[i][i];
						if (res > csum) {
							res = csum;
							bestUse = use.clone();
						}
						use[i] = 0;
						break;
					}
				}
			} else {
				if (res > csum) {
					res = csum;
					bestUse = use.clone();
				}
			}
			return;
		}
		for (int i = 1; i < use.length; i++) {
			if (use[i] != 0) continue;
			for (int j = i + 1; j < use.length; j++) {
				if (use[j] != 0) continue;
				if (csum + D[i][j] * (use.length - n - 1) / 2 < res) {
					use[i] = use[j] = mark;
					solve(n + 2, csum + D[i][j], mark + 1);
					use[i] = use[j] = 0;
				}
			}
		}
	}

	private int sqr(int i) {
		return i * i;
	}

	// ////////////////////////////////////////////////////////////////////
	// Utility functions

	PrintWriter pw;
	BufferedReader in;
	StringTokenizer st;

	void initStreams() throws FileNotFoundException {
		//System.setIn(new FileInputStream("1"));
		in = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(System.out);
	}

	String nextString() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextString());
	}

	long nextLong() throws NumberFormatException, IOException {
		return Long.parseLong(nextString());
	}

	double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(nextString());
	}

	static Throwable sError;

	public static void main(String[] args) throws Throwable {
		Thread t = new Thread(new Main());
		t.start();
		t.join();
		if (sError != null) {
			throw sError;
		}
	}

	public void run() {
		try {
			initStreams();
			solve();
		} catch (Throwable e) {
			sError = e;
		} finally {
			if (pw != null)
				pw.close();
		}
	}
}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class B {
    static int[][] dist;
    static int[] dist1;
    static int [] dp;
    static int [] path;
    static int end,x,y;
    static Point[] a;
    public static int doit(int mask) {
        if(mask==end) return 0;
        if(dp[mask]!=-1) return dp[mask];
        int min=Integer.MAX_VALUE;
        int t;
        for(int i=0;i<dist.length;i++) {
            if(((1<<i)|mask)==mask) continue;
            t=2*dist1[i]+doit(mask|(1<<i));
            if(t<min) {
                min=t;
                path[mask]=(1<<i);
            }
            for(int j=i+1;j<dist.length;j++) {
                if(((1<<j)|mask)==mask) continue;
                t=dist[i][j]+doit(mask|(1<<i)|(1<<j));
                if(t<min) {
                    min=t;
                    path[mask]=(1<<i)|(1<<j);
                }
            }
        }
        return dp[mask]=min;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
         x=sc.nextInt();y=sc.nextInt();
         a=new Point[sc.nextInt()];
        for(int i=0;i<a.length;i++) {
            a[i]=new Point(sc.nextInt(), sc.nextInt());
        }
        end=(1<<a.length)-1;
        dp=new int[1<<a.length];
        Arrays.fill(dp, -1);
        dist=new int[a.length][a.length];
        dist1=new int[a.length];
        for(int i=0;i<a.length;i++) {
            dist1[i]=(a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y);
            for(int j=i+1;j<a.length;j++) {

                dist[i][j]=dist1[i]+
                (a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+
                (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                //System.out.println(dist[i][j]);
            }
        }
        path=new int[dp.length];
        System.out.println(doit(0));
        int e=(int) Math.ceil(a.length/2.0);
        int cur=path[0];
        StringBuffer bf=new StringBuffer();
        bf.append(0+" ");
        int count=0;
        for(int i=0;count<a.length;i++) {
            //System.out.println(Integer.toBinaryString(cur)+" "+cur);
            for(int j=0;j<a.length;j++) {
                if(((1<<j)|cur)==cur) {
                    bf.append((j+1)+" "); count++;
                }
            }
            cur=path[cur];
            bf.append(0+" ");
        }
        System.out.println(bf);
    }
}

import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.HashSet;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alex
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
	    int handx = in.ri(), handy = in.ri();
	    int n = in.ri();
	    IntPair[] cords = new IntPair[n];
	    for(int i = 0; i < n; i++) {
		    int x = in.ri() - handx;
		    int y = in.ri() - handy;
		    cords[i] = new IntPair(x, y);
	    }
	    int[] perms = new int[n];
	    for(int i = 0; i < n; i++) perms[i] = i;
	    int ans = Integer.MAX_VALUE;
	    int[] ansarr = new int[1];
	    int[] bestnext = new int[1];
	    while(true){
		    int[] next = new int[n];
		    int best = dp(0, next, perms, cords);
		    if (best < ans){
			    ans = best;
			    ansarr = perms.clone();
			    bestnext = next;
		    }
		    if (!ArrayUtils.nextPermutation(perms)) break;
	    }
	    out.printLine(ans);
	    int cur = -1;
	    ArrayList<Integer> res = new ArrayList<>();
	    res.add(-1);
	    for(int i = 0; i < n; i++) {
			res.add(ansarr[i]);
		    if (bestnext[ansarr[i]] == -1) res.add(-1);
	    }
	    for(int i : res) out.print((i + 1) + " ");
}
	int dp(int cur, int[] next, int[] perms, IntPair[] cords){
		if (cur == perms.length) return 0;
		int takeone = 2 * cords[perms[cur]].first * cords[perms[cur]].first + 2 * cords[perms[cur]].second * cords[perms[cur]].second + dp(cur + 1, next, perms, cords);
		int taketwo = Integer.MAX_VALUE;
		if (cur < perms.length - 1){
			taketwo = cords[perms[cur]].first * cords[perms[cur]].first + cords[perms[cur]].second * cords[perms[cur]].second +
					(cords[perms[cur + 1]].first - cords[perms[cur]].first) * (cords[perms[cur + 1]].first - cords[perms[cur]].first) +
					(cords[perms[cur + 1]].second - cords[perms[cur]].second) * (cords[perms[cur + 1]].second - cords[perms[cur]].second) +
					cords[perms[cur + 1]].first * cords[perms[cur + 1]].first + cords[perms[cur + 1]].second * cords[perms[cur + 1]].second +
					dp(cur + 2, next, perms, cords);
		}
		if (takeone <= taketwo){
			next[perms[cur]] = -1;
			return takeone;
		}
		next[perms[cur]] = perms[cur + 1];
		next[perms[cur + 1]] = -1;
		return taketwo;
	}
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int ri(){
		return readInt();
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}
	public void close() {
		writer.close();
	}
	public void printLine(int i) {
		writer.println(i);
	}

}

class IntPair implements Comparable<IntPair> {
public int first, second;

	public IntPair(int first, int second) {
		this.first = first;
		this.second = second;
	}
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;

		IntPair intPair = (IntPair) o;

		return first == intPair.first && second == intPair.second;

	}

	public int hashCode() {
		int result = first;
		result = 31 * result + second;
		return result;
	}

	public int compareTo(IntPair o) {
		if (first < o.first)
			return -1;
		if (first > o.first)
			return 1;
		if (second < o.second)
			return -1;
		if (second > o.second)
			return 1;
		return 0;
	}
}

class ArrayUtils {
	public static boolean nextPermutation(int[] array) {
		return new IntArray(array).nextPermutation();
	}
}

abstract class IntCollection {
	public abstract int size();
}

interface IntIterator {
	public int value() throws NoSuchElementException;
	public void advance() throws NoSuchElementException;
	public boolean isValid();
}

interface IntComparator {
    public static final IntComparator DEFAULT = new IntComparator() {
        public int compare(int first, int second) {
            if (first < second)
                return -1;
            if (first > second)
                return 1;
            return 0;
        }
    };
	public int compare(int first, int second);
}

abstract class IntList extends IntCollection implements Comparable<IntList> {
	public abstract int get(int index);
	public abstract void set(int index, int value);

	public IntIterator iterator() {
		return new IntIterator() {
			private int size = size();
			private int index = 0;

			public int value() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				return get(index);
			}

			public void advance() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				index++;
			}

			public boolean isValid() {
				return index < size;
			}
		};
	}
	public boolean nextPermutation() {
		return nextPermutation(IntComparator.DEFAULT);
	}

	private boolean nextPermutation(IntComparator comparator) {
		int size = size();
		int last = get(size - 1);
		for (int i = size - 2; i >= 0; i--) {
			int current = get(i);
			if (comparator.compare(last, current) > 0) {
				for (int j = size - 1; j > i; j--) {
					if (comparator.compare(get(j), current) > 0) {
						swap(i, j);
						subList(i + 1, size).inPlaceReverse();
						return true;
					}
				}
			}
			last = current;
		}
		return false;
	}

	public void inPlaceReverse() {
		for (int i = 0, j = size() - 1; i < j; i++, j--)
			swap(i, j);
	}

	public IntList subList(final int from, final int to) {
		return new SubList(from, to);
	}

	private void swap(int first, int second) {
		if (first == second)
			return;
		int temp = get(first);
		set(first, get(second));
		set(second, temp);
	}
	public int hashCode() {
		int hashCode = 1;
		for (IntIterator i = iterator(); i.isValid(); i.advance())
			hashCode = 31 * hashCode + i.value();
		return hashCode;
	}

	public boolean equals(Object obj) {
		if (!(obj instanceof IntList))
			return false;
		IntList list = (IntList)obj;
		if (list.size() != size())
			return false;
		IntIterator i = iterator();
		IntIterator j = list.iterator();
		while (i.isValid()) {
			if (i.value() != j.value())
				return false;
			i.advance();
			j.advance();
		}
		return true;
	}

	public int compareTo(IntList o) {
		IntIterator i = iterator();
		IntIterator j = o.iterator();
		while (true) {
			if (i.isValid()) {
				if (j.isValid()) {
					if (i.value() != j.value()) {
						if (i.value() < j.value())
							return -1;
						else
							return 1;
					}
				} else
					return 1;
			} else {
				if (j.isValid())
					return -1;
				else
					return 0;
			}
			i.advance();
			j.advance();
		}
	}
	private class SubList extends IntList {
        private final int to;
        private final int from;
        private int size;

        public SubList(int from, int to) {
            this.to = to;
            this.from = from;
            size = to - from;
        }

        public int get(int index) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            return IntList.this.get(index + from);
        }

        public void set(int index, int value) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            IntList.this.set(index + from, value);
        }

        public int size() {
            return size;
        }
	}
}
class IntArray extends IntList {
	private final int[] array;

	public IntArray(int[] array) {
		this.array = array;
	}
	public int get(int index) {
		return array[index];
	}

	public void set(int index, int value) {
		array[index] = value;
	}

	public int size() {
		return array.length;
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class C8 {
	static int[] mem;
	static int[] bag;
	static int[][] items;
	static int[] close;
	static PrintWriter pw;
	static int n;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		pw = new PrintWriter(System.out);

		bag = new int[2];
		bag[0] = sc.nextInt();
		bag[1] = sc.nextInt();

		n = sc.nextInt();
		items = new int[n][2];

		for(int i = 0;i<n;i++)
		{
			items[i][0] = sc.nextInt();
			items[i][1] = sc.nextInt();
		}

		//System.out.println((items[0][1]-bag[1])*(items[0][1]-bag[1]));

		mem = new int[1<<n];

		Arrays.fill(mem, -1);

		pw.println(dp(0));
		trace(0);

		pw.flush();
	}
	static int dp(int mask){
		if(mask==(1<<n)-1)
			return 0;

		if(mem[mask]!=-1)
			return mem[mask];

		int ans = (int)1e9;
		for(int i = 0;i<n;i++)
			if((1<<i&mask)==0)
			{
				int dis = getDisBag(i);

				int j = getClosest(i, mask);
				int newMask = mask|(1<<i);
				if(j!=-1)
				{
					dis += getDis(i, j)+getDisBag(j);
					newMask |= (1<<j);
				}
				else
					dis += getDisBag(i);

				ans = Math.min(ans, dis+dp(newMask));
			}

		return mem[mask] = ans;
	}
	static int getDis(int i, int j){
		return (items[i][0]-items[j][0])*(items[i][0]-items[j][0])+(items[i][1]-items[j][1])*(items[i][1]-items[j][1]);
	}
	static int getDisBag(int i){
		return (items[i][0]-bag[0])*(items[i][0]-bag[0])+(items[i][1]-bag[1])*(items[i][1]-bag[1]);
	}
	static int getClosest(int i, int mask){
		int ret = -1;
		for(int j = 0;j<n;j++)
			if(i!=j&&(mask&1<<j)==0)
				if(ret==-1||getDis(i, j)<getDis(i, ret))
					ret = j;
		return ret;
	}
	static void trace(int mask){
		if(mask==(1<<n)-1)
			return;

		for(int i = 0;i<n;i++)
			if((1<<i&mask)==0)
			{
				int dis = getDisBag(i);

				int j = getClosest(i, mask);
				int newMask = mask|(1<<i);
				if(j!=-1)
				{
					dis += getDis(i, j)+getDisBag(j);
					newMask |= (1<<j);
				}
				else
					dis += getDisBag(i);

				if(mem[mask]==dis+dp(newMask))
				{
					if(mask==0)
						pw.print(0+" ");
					pw.print((i+1)+" "+(j!=-1?(j+1)+" 0 ":0));
					trace(newMask);
					return;
				}
			}

	}
	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}

	}
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C8
{

	public static long mod = 1000000007;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);
	static int n;
	static int x,y;
	static int[] xx;
	static int[] yy;
	static int[] dist;
	static int[][] g;
	static int[] dp;
	public static int square(int x)
	{
		return abs(x*x);
	}
	static class Pair
	{
		int x,y;
		Pair(int x,int y)
		{
			this.x=x;
			this.y=y;
		}
	}
	public static void main(String[] args)
	{

		x=in.nextInt();
		y=in.nextInt();
		n=in.nextInt();
		xx=new int[n];
		yy=new int[n];
		dp=new int[1<<n];
		for(int i=0;i<n;i++)
		{
			xx[i]=in.nextInt();
			yy[i]=in.nextInt();
		}
		dist=new int[n];
		g=new int[n][n];
		for(int i=0;i<n;i++)
		{
			dist[i]=square(abs(xx[i]-x))+square(abs(yy[i]-y));
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				g[i][j]=square(abs(xx[i]-xx[j]))+square(yy[i]-yy[j]);
				//System.out.println("i "+i+" j "+j+" "+g[i][j]);
			}
		}
		Arrays.fill(dp, Integer.MAX_VALUE/2);
		dp[0]=0;
		for(int i=0;i<(1<<n);i++)
		{
			//we have to find dp[i]
			for(int j=0;j<n;j++)
			{
				if((i&(1<<j))>0)   //not visited j
				continue;
				dp[i|(1<<j)]=min(dp[i|(1<<j)], dp[i]+2*dist[j]);
				for(int k=j+1;k<n;k++)
				{
					if((i&(1<<k))>0)
						continue;
					dp[i|(1<<j)|(1<<k)]=min(dp[i|(1<<j)|(1<<k)], dp[i]+dist[j]+dist[k]+g[j][k]);
				}
				break;
			}
		}
		out.println(dp[(1<<n)-1]);
		Stack<Integer> stack=new Stack<>();
		stack.push(0);
		int i=(1<<n)-1;
		while(i>0)
		{
			boolean tocontinue=false;
			for(int a=0;a<n;a++)
			{
				if((i&(1<<a))==0)
					continue;
				if(dp[i]==(dp[i^(1<<a)]+2*dist[a]))
				{
					stack.push(a+1);
					stack.push(0);
					i-=(1<<a);
					tocontinue=true;
				}
				if(tocontinue)
					continue;
				for(int b=a+1;b<n;b++)
				{
					if((i & (1<<b)) == 0) continue;
					if(dp[i]==(dp[i^(1<<a)^(1<<b)]+dist[a]+dist[b]+g[a][b]))
					{
						i-=(1<<a);
						i-=(1<<b);
						stack.push(a+1);
						stack.push(0);
						stack.push(b+1);
						stack.push(0);
						tocontinue=true;
					}
					if(tocontinue)
						break;
				}
				if(tocontinue)
					break;
			}

		}
		for(int ii : stack)
			out.print(ii+" ");
		out.close();

	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

		public int read()
		{
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars)
			{
				curChar = 0;
				try
				{
					snumChars = System.in.read(buf);
				} catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

	static class InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream inputstream)
		{
			reader = new BufferedReader(new InputStreamReader(inputstream));
			tokenizer = null;
		}

		public String nextLine()
		{
			String fullLine = null;
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					fullLine = reader.readLine();
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
				return fullLine;
			}
			return fullLine;
		}

		public String next()
		{
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public long nextLong()
		{
			return Long.parseLong(next());
		}

		public int[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

		public int nextInt()
		{
			return Integer.parseInt(next());
		}
	}

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
		}

		public OutputWriter(Writer writer)
		{
			this.writer = new PrintWriter(writer);
		}

		public void print(Object... objects)
		{
			for (int i = 0; i < objects.length; i++)
			{
				if (i != 0)
					writer.print(' ');
				writer.print(objects[i]);
			}
		}

		public void println(Object... objects)
		{
			print(objects);
			writer.println();
		}

		public void close()
		{
			writer.close();
		}

		public void flush()
		{
			writer.flush();
		}
	}

}

import java.awt.*;
import java.io.*;
import java.util.*;

public class Abc {
    static Point p[];
    static int dp[];
    static int n;
    static Point s;
    static int ans[];
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        s=new Point(sc.nextInt(),sc.nextInt());
        n=sc.nextInt();
        p=new Point[n];
        for (int i=0;i<n;i++){
            p[i]=new Point(sc.nextInt(),sc.nextInt());
        }
        dp=new int[1<<n];
        ans=new int[1<<n];
        Arrays.fill(dp,-1);
        System.out.println(dp(0));
        int i=0;
        StringBuilder sb=new StringBuilder();
        sb.append(0+" ");
        while (i!=(1<<n)-1){
            int x=ans[i];
            for (int j=0;j<n;j++){
                if ((x&(1<<j))!=0){
                    sb.append((j+1)+" ");
                }
            }
            i=(i|x);
            sb.append(0+" ");
        }
        System.out.println(sb);
    }
    static int dp(int mask){
        if (mask==(1<<n)-1)return 0;
        if (dp[mask]!=-1)return dp[mask];
        int i=-1,j=-1;
        for (int k=0;k<n;k++){
            if ((mask&(1<<k))==0){
                if (i==-1 || j==-1){
                    j=i;
                    i=k;
                }else break;
            }
        }
        int a=Integer.MAX_VALUE;
        if (i!=-1 && j!=-1){
            int a1=dp(mask|(1<<i))+2*dist(p[i],s);
            int a2=dp(mask|(1<<j))+2*dist(p[j],s);
            int a3=dp(mask+(1<<i)+(1<<j))+dist(p[i],p[j])+dist(s,p[i])+dist(p[j],s);
            if (a>a1){
                a=a1;
                ans[mask]=(1<<i);
            }
            if (a>a2){
                a=a2;
                ans[mask]=(1<<j);
            }
            if (a>a3){
                a=a3;
                ans[mask]=(1<<i)+(1<<j);
            }
        }else {
            int a1=dp(mask|(1<<i))+2*dist(p[i],s);
            if (a>a1){
                a=a1;
                ans[mask]=(1<<i);
            }
        }
        return dp[mask]=a;
    }
    static int dist(Point p1,Point p2){
        return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
    }
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
static int n;
static int []x,y,memo;
static StringBuilder sb;
static int distance(int i,int j)
{
	int dx=x[i]-x[j];
	int dy=y[i]-y[j];
	return dx*dx+dy*dy;
}
public static int dp(int msk)
{
	if(msk==(1<<(n+1))-2)
		return 0;
	if(memo[msk]!=-1)
		return memo[msk];
	int ans=100000;
	boolean found=false;
	for(int i=1;i<=n && !found;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				found=true;
				int newM=msk|1<<i;
				newM|=1<<j;
				ans=Math.min(ans, dp(newM)+Math.min(distance(0,i)+distance(i,j)+distance(j,0), distance(0,j)+distance(j,i)+distance(i,0)));
			}
	return memo[msk]=ans;

}
public static void print(int msk)
{
	if(msk==(1<<(n+1))-2)
		return ;

	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{

				int newM=msk|1<<i;
				newM|=1<<j;
				int d1=distance(0,i)+distance(i,j)+distance(j,0);
				int d2=distance(0,j)+distance(j,i)+distance(i,0);
				if(dp(msk)== dp(newM)+Math.min(d1,d2))
				{

					if(i==j)

						sb.append("0 "+i+" ");

					else if(d1<d2)
						sb.append("0 "+i+" "+j+" ");
					else
						sb.append("0 "+j+" "+i+" ");

					print(newM);
					return ;
				}
			}

}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int xS=sc.nextInt(),yS=sc.nextInt();
		n=sc.nextInt();
		x=new int [n+1];
		y=new int [n+1];
		x[0]=xS;y[0]=yS;
		for(int i=1;i<=n;i++)
		{
			x[i]=sc.nextInt();
			y[i]=sc.nextInt();

		}
		memo=new int [1<<(n+1)];
		Arrays.fill(memo,-1);
		sb=new StringBuilder();

		sb.append(dp(0)+"\n");
		print(0);
		sb.append("0");
		System.out.println(sb);
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		public Scanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());

		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	static int[][] pos;
	static int[] dp;
	static int[] nextstate;
	static int[][] dist;
	static int r;
	static int v;

	static void print(int mask) {
		if (mask < v) {
			int c = 0;
			int x = mask ^ nextstate[mask];
			for (int i = 0; i < dist.length - 1; i++) {
				if((x & (1<<i))>0) {
					System.out.print(i+1 + " ");
					c++;
				}
			}
			if(c == 1)System.out.print("0 ");
			print(nextstate[mask]);
		}
	}

	static int distace(int x1, int x2, int y1, int y2) {
		return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
	}

	static int solve(int mask) {
		if (mask == v) {
			nextstate[mask] = r;

			return 0;
		}
		if (nextstate[mask] != 0) {
			return dp[mask];
		}

		dp[mask] = (int) 1e9;
		for (int i = 1; i < pos.length; i++) {
			int u = (1 << (i - 1));
			int z = mask | u;
			if ((mask & u) == 0) {
				int x = 2 * dist[i][0] + solve(z);
				if (dp[mask] > x) {
					dp[mask] = x;
					nextstate[mask] = z;
				}

				for (int j = 1; j < pos.length; j++) {
					int m = (1 << j - 1);
					int y = z | m;
					if ((z & m) == 0) {
						x = dist[i][0] + solve(y) + dist[i][j] + dist[j][0];

						if (dp[mask] > x) {
							dp[mask] = x;
							nextstate[mask]= y;
						}

					}
				}
				break;
			}
		}
		return dp[mask];
	}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(), y = in.nextInt();
		int n = in.nextInt();
		r = 1 << n;
		v = r - 1;
		dp = new int[r];
		nextstate = new int[r];
		pos = new int[n + 1][2];
		pos[0][0] = x;
		pos[0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos[i][0] = in.nextInt();
			pos[i][1] = in.nextInt();
		}
		dist = new int[n + 1][n + 1];
		for (int i = 0; i < dist.length; i++) {
			for (int j = i + 1; j < dist.length; j++) {
				dist[i][j] = dist[j][i] = distace(pos[i][0], pos[j][0], pos[i][1], pos[j][1]);
			}
		}

		System.out.println(solve(0));
		System.out.print("0 ");
		print(0);
	}

}

class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.io.*;
import java.util.*;

public class Solution {
    BufferedReader in;
    StringTokenizer st;
    PrintWriter out;

    public Solution() throws Exception {
	in = new BufferedReader(new InputStreamReader(System.in));
	out = new PrintWriter(System.out);
    }

    public String next() throws Exception {
	if (st == null || !st.hasMoreTokens()) {
	    st = new StringTokenizer(in.readLine());
	}
	return st.nextToken();
    }

    public int nextInt() throws Exception {
	return Integer.parseInt(next());
    }

    public long nextLong() throws Exception {
	return Long.parseLong(next());

    }

    public double nextDouble() throws Exception {
	return Double.parseDouble(next());
    }

    public static void main(String[] args) throws Exception {
	new Solution().run(args);
    }

    public int dist(int x0, int y0, int x1, int y1) {
	return (x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1);
    }

    public void run(String[] args) throws Exception {
	int x0 = nextInt();
	int y0 = nextInt();
	int n = nextInt();
	int[] x = new int[n];
	int[] y = new int[n];
	for (int i = 0; i < n; ++i) {
	    x[i] = nextInt();
	    y[i] = nextInt();
	}
	if (n == 1) {
	    int d = dist(x0, y0, x[0], y[0]);
	    out.println(d * 2);
	    out.println("0 1 0");
	    out.close();
	    return;
 	}
	if (n == 2) {
	    int d1 = dist(x0, y0, x[0], y[0]);
	    int d2 = dist(x0, y0, x[1], y[1]);
	    int d3 = dist(x[0], y[0], x[1], y[1]);
	    out.println(d1 + d2 + d3);
	    out.println("0 1 2 0");
	    out.close();
	    return;
 	}

	Queue<State> q = new LinkedList<State>();
	State[] states = new State[(1 << (n + 1))];
	for (int i = 0; i < n; ++i) {
	    for (int j = i + 1; j < n; ++j) {
		int v = (1 << i) | (1 << j);
		LinkedList<Integer> path = new LinkedList<Integer>();
		path.add(0);
		path.add(i + 1);
		path.add(j + 1);
		path.add(0);
		int d1 = dist(x0, y0, x[i], y[i]);
		int d2 = dist(x0, y0, x[j], y[j]);
		int d3 = dist(x[i], y[i], x[j], y[j]);
		State st = new State(v, path, d1 + d2 + d3);
		states[v] = st;
		q.add(st);
	    }
	}

	while(!q.isEmpty()) {
	    State st = q.poll();
	    boolean pairs = false;
	    for (int i = 0; i < n; ++i) {
		for (int j = i + 1; j < n; ++j) {
		    if ((st.v & (1 << i)) == 0 && (st.v & (1 << j)) == 0) {
			pairs = true;
			int v = st.v | (1 << i) | (1 << j);
			int d1 = dist(x0, y0, x[i], y[i]);
			int d2 = dist(x0, y0, x[j], y[j]);
			int d3 = dist(x[i], y[i], x[j], y[j]);
			int c = st.c + d1 + d2 + d3;
			if (states[v] == null || states[v].c > c) {
			    LinkedList<Integer> path = new LinkedList(st.path);
			    path.add(i + 1);
			    path.add(j + 1);
			    path.add(0);
			    State newState = new State(v, path, c);
			    states[v] = newState;
			    q.add(newState);
			}
		    }
		}
	    }

	    if (!pairs) {
		for (int i = 0; i < n; ++i) {
		    if ((st.v & (1 << i)) == 0) {
			int v = st.v | (1 << i);
			int d = dist(x0, y0, x[i], y[i]);
			int c = st.c + d * 2;
			if (states[v] == null || states[v].c > c) {
			    LinkedList<Integer> path = new LinkedList(st.path);
			    path.add(i + 1);
			    path.add(0);
			    State newState = new State(v, path, c);
			    states[v] = newState;
			}
		    }
		}
	    }
	}
	int v = (1 << n) - 1;
	out.println(states[v].c);
	out.print(states[v].path.pollFirst());
	while(!states[v].path.isEmpty()) {
	    out.print(" " + states[v].path.pollFirst());
	}
	in.close();
	out.close();
    }

    class State {
	int v;
	LinkedList<Integer> path;
	int c;

	public State(int v, LinkedList<Integer> path, int c) {
	    this.v = v;
	    this.path = path;
	    this.c = c;
	}
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] x, y;
	static int[] dp, p;
	static int n;

	static int dist(int i, int j) {
		return ((x[i] - x[j]) * (x[i] - x[j]))
				+ ((y[i] - y[j]) * (y[i] - y[j]));
	}

	static int solve(int mask) {
		if (mask == (1 << n) - 1)
			return 0;
		if (dp[mask] != -1)
			return dp[mask];
		int ans = 99999999;
		for (int i = 1; i < n; i++)
			if ((mask & (1 << i)) == 0) {
				int tmp = 2 * dist(0, i) + solve(mask | (1 << i));
				if (tmp < ans) {
					ans = tmp;
					p[mask] = -i;
				}
				for (int j = 1; j < n; j++)
					if (i != j && (mask & (1 << j)) == 0) {
						tmp = dist(0, i) + dist(i, j) + dist(j, 0)
								+ solve(mask | (1 << i) | (1 << j));
						if (tmp < ans) {
							ans = tmp;
							p[mask] = i;
							p[mask | (1 << i)] = -j;
						}
					}
			}
		return dp[mask] = ans;
	}

	public static void main(String[] args) throws IOException {
		PrintWriter out = new PrintWriter(System.out);
		sc = new StringTokenizer(br.readLine());
		int a = nxtInt();
		int b = nxtInt();
		n = nxtInt() + 1;
		x = new int[n];
		y = new int[n];
		dp = new int[1 << n];
		p = new int[1 << n];
		Arrays.fill(dp, -1);
		x[0] = a;
		y[0] = b;
		for (int i = 1; i < n; i++) {
			x[i] = nxtInt();
			y[i] = nxtInt();
		}
		out.println(solve(1 << 0));
		int mask = 1 << 0;
		out.print(0);
		while (mask != (1 << n) - 1) {
			out.print(" " + Math.abs(p[mask]));
			if (p[mask] < 0)
				out.print(" 0");
			mask |= (1 << Math.abs(p[mask]));
		}
		out.println();
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens())
			sc = new StringTokenizer(br.readLine());
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {
static int n;
static int []x,y,memo;
static StringBuilder sb;
static int distance(int i,int j)
{
	int dx=x[i]-x[j];
	int dy=y[i]-y[j];
	return dx*dx+dy*dy;
}
public static int dp(int msk)
{
	if(msk==(1<<(n+1))-2)
		return 0;
	if(memo[msk]!=-1)
		return memo[msk];
	int ans=100000;
	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{
				int newM=msk|1<<i;
				newM|=1<<j;
				ans=Math.min(ans, dp(newM)+Math.min(distance(0,i)+distance(i,j)+distance(j,0), distance(0,j)+distance(j,i)+distance(i,0)));
			}
		return memo[msk]=ans;

}
public static void print(int msk)
{
	if(msk==(1<<(n+1))-2)
		return ;

	for(int i=1;i<=n;i++)

		for(int j=i;j<=n && (msk&1<<i)==0;j++)
			if((msk&1<<j)==0)
			{
				int newM=msk|1<<i;
				newM|=1<<j;
				int d1=distance(0,i)+distance(i,j)+distance(j,0);
				int d2=distance(0,j)+distance(j,i)+distance(i,0);
				if(dp(msk)== dp(newM)+Math.min(d1,d2));
				{

					if(i==j)
					{
						sb.append("0 "+i+" ");
					}
					else if(d1<d2)
						sb.append("0 "+i+""+j+" ");
					else
						sb.append("0 "+j+""+i+" ");

					print(newM);
					return ;
				}
			}

}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		int xS=sc.nextInt(),yS=sc.nextInt();
		n=sc.nextInt();
		x=new int [n+1];
		y=new int [n+1];
		x[0]=xS;y[0]=yS;
		for(int i=1;i<=n;i++)
		{
			x[i]=sc.nextInt();
			y[i]=sc.nextInt();

		}
		memo=new int [1<<(n+1)];
		Arrays.fill(memo,-1);
		sb=new StringBuilder();

		sb.append(dp(0)+"\n");
		print(0);
		sb.append("0");
		System.out.println(sb);
	}
	static class Scanner
	{
		BufferedReader br;
		StringTokenizer st;
		public Scanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());

		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// Jonathan
// cpt_fwiffo

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] line = in.readLine().split(" ");
        int Xs = Integer.parseInt(line[0]);
        int Ys = Integer.parseInt(line[1]);
        int n = Integer.parseInt(in.readLine());

        int[][] points = new int[n+1][2];
        points[n][0] = Xs;//set starting point as last point for finding distances
        points[n][1] = Ys;

        for(int i=0; i< n ; i++)
        {
            line = in.readLine().split(" ");
            points[i][0] = Integer.parseInt(line[0]);
            points[i][1] = Integer.parseInt(line[1]);
        }

        int[][] distances = new int[n+1][n+1];
        ComputeDistances(points, distances, n);

        int[] dp = new int[1<<n];
        int[] path = new int[1<<n];
        ComputeLowestPath(dp, path, distances, n);
        OutputLowestAndPath(dp, path, n);

    }

    private static void ComputeLowestPath(int[] dp, int[] path, int[][] distances, int n)
    {
        for(int i = 1; i < 1<<n; i++)
        {
            int j = 0;
            while(true) //find first 1 (LSB)
            {
                if((i&(1<<j))!=0) //check for a bit equal to 1 in location j
                {
                    break;
                }
                j++;
            }

            int pastEntry = i & ~(1<<j); //remove first 1 from i
            path[i] = pastEntry; //set the path we came from to trace later
            int distance = distances[j][n] * 2; //distance from origin to the point being removed, and back
            dp[i] = dp[pastEntry] + distance; //set minimum distance if just this point is added to the collection

            for(int m = j +1; m < n; m++)
            {
                if((i & (1<<m))!=0)
                {
                    int entry = i & ~((1<<j)|(1<<m)); //remove both 1 at position j and 1 at position m from i
                    distance = distances[j][n] + distances[j][m] + distances[m][n]; //calculate round-trip distance to grab 2 points

                    if(dp[i] > dp[entry] + distance) // check if this new option is a better choice.  If it is, update our value and our path.
                    {
                        dp[i] = dp[entry] + distance;
                        path[i] = entry;
                    }
                }
            }

        }
    }

    private static void OutputLowestAndPath(int[] dp, int[] path, int n)
    {

        StringBuilder out = new StringBuilder();
        out.append(dp[(1<<n)-1]);//output min value of traversal
        out.append("\n");
        out.append("0 ");
        int index = (1<<n)-1; //start at our min value
        while(index != 0)
        {
            int j = path[index];
            int k = index ^ j; //find the one or two values that were added at this step
            for(int m = 0; m < n; m++)
            {
                if((k & (1 << m)) != 0)
                {
                    out.append(m+1);
                    out.append(" ");
                }
            }
            out.append("0 ");
            index = j;
        }
        System.out.println(out.toString());
    }

    private static void ComputeDistances(int[][] points, int[][] distances, int n)
    {
        for(int i = 0; i <= n; i++) //calculate distances between all points so that we don't have to compute later
        {
            for(int j=i+1; j<n; j++)
            {
                int x= points[i][0] - points[j][0];
                int y= points[i][1] - points[j][1];
                distances[i][j] = x*x + y*y;
            }
        }
    }

}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class B {
    static int[][] dist;
    static int [] dp;
    static int [] path;
    static int end,x,y;
    static Point[] a;
    public static int doit(int mask) {
        if(mask==end) return 0;
        if(dp[mask]!=-1) return dp[mask];
        int min=Integer.MAX_VALUE;
        boolean found=false;
        int t;
        for(int i=0;i<dist.length;i++) {
            if(((1<<i)|mask)==mask) continue;
            for(int j=i+1;j<dist.length;j++) {
                if(((1<<j)|mask)==mask) continue;
                found=true;
                t=dist[i][j]+doit(mask|(1<<i)|(1<<j));
                if(t<min) {
                    min=t;
                    path[mask]=(1<<i)|(1<<j);
                }
            }
            if(!found) {
                path[mask]=1<<i;
                return dp[mask]=2*((a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y));
            }
        }
        return dp[mask]=min;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
         x=sc.nextInt();y=sc.nextInt();
         a=new Point[sc.nextInt()];
        for(int i=0;i<a.length;i++) {
            a[i]=new Point(sc.nextInt(), sc.nextInt());
        }
        end=(1<<a.length)-1;
        dp=new int[1<<a.length];
        Arrays.fill(dp, -1);
        dist=new int[a.length][a.length];
        for(int i=0;i<a.length;i++) {
            for(int j=i+1;j<a.length;j++) {
                dist[i][j]=(a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y) +
                (a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+
                (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                //System.out.println(dist[i][j]);
            }
        }
        path=new int[dp.length];
        System.out.println(doit(0));
        int e=(int) Math.ceil(a.length/2.0);
        int cur=path[0];
        StringBuffer bf=new StringBuffer();
        bf.append(0+" ");
        for(int i=0;i<e;i++) {
            //System.out.println(Integer.toBinaryString(cur));
            for(int j=0;j<a.length;j++) {
                if(((1<<j)|cur)==cur) {
                    bf.append((j+1)+" ");
                }
            }
            cur=path[cur];
            bf.append(0+" ");
        }
        System.out.println(bf);
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

public class Handbag
{
	// http://codeforces.com/problemset/problem/8/C

	public static class Item{
		int x;
		int y;
		int norm;

		Item(int x, int y){
			this.x = x;
			this.y = y;
			this.norm = x*x + y*y;
		}

		public int dist(Item i){
			int dx = x - i.x;
			int dy = y - i.y;
			return dx*dx + dy*dy;
		}
	}

	public static int solve(int bitNum){

		if(bitNum == (1 << N) - 1) // If bitNum is too big for the array
			return 0;

		if(bits[bitNum] != -1) // If bit value has already been calculated
			return bits[bitNum];

		int ans = Integer.MAX_VALUE;
		int j = 0;
		for(int i = 1; i < N; i++){

			if((bitNum & (1 << i)) == 0){ // Performs bitwise AND operation to see if bitNum and i have no bits in common

				if(j == 0){ // Only happens on the first time in IF statement
					ans = 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i)); // Performs bitwise exclusive OR operation
					j = i; // Change value so this case isn't ever hit again && to store value to use in else statement
				}
				else{
					// Find the distance between the handbag and the two items
					int dist1 = items[0].dist(items[i]);
					int dist2 = items[i].dist(items[j]);
					int dist3 = items[j].dist(items[0]);
					ans = Math.min(ans, dist1 + dist2 + dist3 + solve(bitNum | (1 << i) | (1 << j))); // Performs bitwise exclusive OR operation
				}
			}
		}
		return bits[bitNum] = ans;
	}

	static String printOpt(int bitNum) {
		String output = "";
		if (bitNum == (1 << N) - 1)
			return output;
		int j = 0;
		for (int i = 1; i < N; i++)
			if ((bitNum & (1 << i)) == 0) {
				if (j == 0) {
					j = i;
					if (bits[bitNum] == 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i))) {
						output += " " + i + " 0";
						output += printOpt(bitNum | (1 << i));
						return output;
					}
				} else if (bits[bitNum] ==
									items[0].dist(items[i]) + items[i].dist(items[j]) + items[j].dist(items[0])
									+ solve(bitNum | (1 << i) | (1 << j))) {

					output += " " + i + " " + j + " 0";
					output += printOpt(bitNum | (1 << i) | (1 << j));
					return output;
				}
			}
		return output;
	}

	static int N = 0;
	static Item[] items;
	static int[] bits;

	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);

		String[] input = br.readLine().split(" ");
		Item handbag = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));

		N = Integer.parseInt(br.readLine()) + 1;
		items = new Item[N];
		for(int n = 1; n < N; n++){
			input = br.readLine().split(" ");
			items[n] = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));
		}
		items[0] = handbag;

		// x << n is a right shift operator
		// which will remove the last n bits from x
		// and fill in any new values needed with 1
		// Ex 1 << 2 => 4
		bits = new int[1 << N]; // Ex: 1 << 3 = 8; 1 << 5 = 64
		Arrays.fill(bits, -1); // Init bits array to hold -1 values

		int ans = solve(1 << 0); // Start solving with bit #1
		pw.println(ans);
		pw.println(printOpt(1 << 0));
		pw.close();
	}
}

//8C
//LookingForOrder

import java.io.PrintWriter;
import java.util.*;

public class LookingForOrder
{

    static int n;
    static int[] memo;
    static Pair start;
    static Pair[] coordinates;
    static PrintWriter pw = new PrintWriter(System.out);

    public static boolean isVisited(int msk, int x)
    {
        return ((1 << x) & msk) == (1 << x);
    }

    public static int dist(Pair fir, Pair sec)
    {
        int x = fir.x - sec.x;
        int y = fir.y - sec.y;
        return (x * x) + (y * y);
    }

    public static int dp(int msk)
    {
        if(n == Integer.bitCount(msk))
            return 0;

        if(memo[msk] != -1) return memo[msk];

        int min = Integer.MAX_VALUE;
        for(int i = 0; i < n; i++)
        {
            if(!isVisited(msk, i) && Integer.bitCount(msk) == n - 1)
                min = Math.min(min, dist(start, coordinates[i]) + dist(coordinates[i], start) + dp(msk | 1 << i));
            else
            {
                for(int j = 0; j < n && !isVisited(msk, i); j++)
                {
                    if(i != j && !isVisited(msk, j))
                        min = Math.min(min, dist(start, coordinates[i]) + dist(coordinates[i], coordinates[j]) + dist(coordinates[j], start) + dp(msk | 1 << i | 1 << j));
                    else if(i == j)
                        min = Math.min(min, dist(start, coordinates[i]) + dist(coordinates[i], start) + dp(msk | 1 << i));
                }
            }
        }

        return memo[msk] = min;
    }

    public static void trace(int msk)
    {
        if(n == Integer.bitCount(msk))
        {
            pw.println("0");
            return;
        }

        for(int i = 0; i < n; i++)
        {
            if(!isVisited(msk, i) && Integer.bitCount(msk) == n - 1)
            {
                pw.print(0 + " " + (i + 1) + " ");
                trace(msk | 1 << i);
                return;
            }
            for(int j = 0; j < n && !isVisited(msk, i); j++)
            {
                if(i != j && !isVisited(msk, j) && dist(start, coordinates[i]) + dist(coordinates[i], coordinates[j]) + dist(coordinates[j], start) + dp(msk | 1 << i | 1 << j) == memo[msk])
                {
                    pw.print(0 + " " + (i + 1) + " " + (j + 1) + " ");
                    trace(msk | 1 << i | 1 << j);
                    return;
                }
            }
        }
    }
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);

        start = new Pair(sc.nextInt(), sc.nextInt());

        n = sc.nextInt();
        coordinates = new Pair[n];
        for(int i = 0; i < n; i++)
            coordinates[i] = new Pair(sc.nextInt(), sc.nextInt());

        memo = new int[1 << (n + 1)];
        Arrays.fill(memo, -1);

        pw.println(dp(0));
        trace(0);
        pw.flush();
        pw.close();
    }

    static class Pair
    {
        int x, y;

        public Pair(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
}

import java.awt.Point;
import java.util.Arrays;
import java.util.Scanner;

public class B {
    static int[][] dist;
    static int[] dist1;
    static int [] dp;
    static int [] path;
    static int end,x,y;
    static Point[] a;
    public static int doit(int mask) {
        if(mask==end) return 0;
        if(dp[mask]!=-1) return dp[mask];
        int min=Integer.MAX_VALUE;
        int t;
        for(int i=0;i<dist.length;i++) {
            if(((1<<i)|mask)==mask) continue;
            t=2*dist1[i]+doit(mask|(1<<i));
            if(t<min) {
                min=t;
                path[mask]=(1<<i);
            }
            for(int j=i+1;j<dist.length;j++) {
                if(((1<<j)|mask)==mask) continue;
                t=dist[i][j]+doit(mask|(1<<i)|(1<<j));
                if(t<min) {
                    min=t;
                    path[mask]=(1<<i)|(1<<j);
                }
            }
        }
        return dp[mask]=min;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
         x=sc.nextInt();y=sc.nextInt();
         a=new Point[sc.nextInt()];
        for(int i=0;i<a.length;i++) {
            a[i]=new Point(sc.nextInt(), sc.nextInt());
        }
        end=(1<<a.length)-1;
        dp=new int[1<<a.length];
        Arrays.fill(dp, -1);
        dist=new int[a.length][a.length];
        dist1=new int[a.length];
        for(int i=0;i<a.length;i++) {
            dist1[i]=(a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y);
            for(int j=i+1;j<a.length;j++) {

                dist[i][j]=dist1[i]+
                (a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y)+
                (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                //System.out.println(dist[i][j]);
            }
        }
        path=new int[dp.length];
        System.out.println(doit(0));
        int e=(int) Math.ceil(a.length/2.0);
        int cur=path[0];
        StringBuffer bf=new StringBuffer();
        bf.append(0+" ");
        int count=0;
        for(int i=0;count<a.length;i++) {
            //System.out.println(Integer.toBinaryString(cur)+" "+cur);
            for(int j=0;j<a.length;j++) {
                if(((1<<j)|cur)==cur) {
                    bf.append((j+1)+" "); count++;
                }
            }
            cur=path[cur];
            bf.append(0+" ");
        }
        System.out.println(bf);
    }
}

import java.io.*;
import java.util.*;
//import java.lang.*;

public class Main {

	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		String input[] = kek.readLine().split(" ");
		int xH = Integer.parseInt(input[0]);
		int yH = Integer.parseInt(input[1]);
		int N = Integer.parseInt(kek.readLine());
		int xcoords[] = new int[N + 1];
		int ycoords[] = new int[N + 1];
		int dFromStart[] = new int[N + 1];
		int dFromEachOther[][] = new int[N + 1][N + 1];
		boolean taken[] = new boolean[N + 1];
		List<Integer> finalPath = new ArrayList<>();
		int minFromStart = 1;
		int mini = 0;
		int minj = 0;
		int objTrack = N;

		for(int i = 1; i <= N; i++){
			input = kek.readLine().split(" ");
			int x = Integer.parseInt(input[0]);
			int y = Integer.parseInt(input[1]);
			xcoords[i] = x;
			ycoords[i] = y;
			dFromStart[i] = getTime(xH, yH, x, y);
			minFromStart = dFromStart[minFromStart] > dFromStart[i] ? i : minFromStart;
			taken[i] = false;
		}
		int tempMin = 100000;
		for(int i = 1; i <= N; i++){
			int x = xcoords[i];
			int y = ycoords[i];
			for(int j = 1; j <= N; j++){
				int x2 = xcoords[j];
				int y2 = ycoords[j];
				if(j != i){
					dFromEachOther[i][j] = getTime(x, y, x2, y2);
					if(tempMin > dFromEachOther[i][j]){
						tempMin = dFromEachOther[i][j];
						mini = i;
						minj = j;
					}
				} else {
					dFromEachOther[i][j] = 10000;
				}
			}
		}
		int res = 0;
		if(objTrack >= 2){
			finalPath.add(0);
			finalPath.add(mini);
			finalPath.add(minj);
			finalPath.add(0);
			objTrack -= 2;
			taken[mini] = true;
			taken[minj] = true;
			res = dFromStart[mini];
			res += tempMin;
			res += dFromStart[minj]; //I left a system out in the last submission gah
		} else {
			finalPath.add(0);
		}

		if(objTrack % 2 == 0){
			while(objTrack > 0){
				int coords[] = shortPath(dFromEachOther, taken, N);
				mini = coords[0];
				minj = coords[1];
				if(mini != -1 || minj != -1){
					finalPath.add(mini);
					finalPath.add(minj);
					finalPath.add(0);
					objTrack -= 2;
					taken[mini] = true;
					taken[minj] = true;
					res += dFromStart[mini];
					res += dFromEachOther[mini][minj];
					res += dFromStart[minj];
				}
			}
		} else {
			if(objTrack > 2){
				while(objTrack > 2){
					int coords[] = shortPath(dFromEachOther, taken, N);
					mini = coords[0];
					minj = coords[1];
					if(mini != -1 || minj != -1){
						finalPath.add(mini);
						finalPath.add(minj);
						finalPath.add(0);
						objTrack -= 2;
						taken[mini] = true;
						taken[minj] = true;
						res += dFromStart[mini];
						res += dFromEachOther[mini][minj];
						res += dFromStart[minj];
					}
				}
			}

			for(int c = 1; c <= N; c++){
				if(taken[c] == false){
					finalPath.add(c);
					finalPath.add(0);
					objTrack--;
					taken[c] = true;
					res += 2 * dFromStart[c];
				}
			}

		}

		System.out.println(res);
		for(int i : finalPath){
			System.out.print(i + " ");
		}

	}

	static int getTime(int x1, int y1, int x2, int y2){
		int x = (x2 - x1);
		int fx = x * x;
		int y = (y2 - y1);
		int fy = y * y;
		int result = fx + fy;
		return result;
	}

	static int[] shortPath(int[][] paths, boolean[] taken, int N){
		int coords[] = new int[2];
		int min = 10000;
		int m1 = -1;
		int m2 = -1;
		for(int i = 1; i <= N; i++){
			if(taken[i] == true){
				continue;
			}
			for(int j = 1; j <= N; j++){
				if(taken[j] == true){
					continue;
				} else {
					if(min > paths[i][j]){
						min = paths[i][j];
						m1 = i;
						m2 = j;
					}
				}
			}
		}

		coords[0] = m1;
		coords[1] = m2;

		return coords;
	}

}

import java.awt.Point;
import java.util.Scanner;

public class LookingForOrder {
	int [][] pos;
	int [][][] dp;
	boolean [][][]visited;
	int [][][]nextstate;

	public LookingForOrder(int[][] pos, int[][][] dp, boolean[][][] visited, int[][][] nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.visited = visited;
		this.nextstate = nextstate;
	}
	void print(int mask,int n) {
		if(mask <= (1<<pos.length) - 2 ) {
			System.out.print(nextstate[mask][n][0] + " ");
			print(nextstate[mask][n][1], nextstate[mask][n][2]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask,int idx,int n) {
		if(mask == (1<<pos.length) - 1 ) {
			nextstate [mask][n][0] = 0;
			nextstate[mask][n][1] = 1<<pos.length;
			nextstate[mask][n][2] = 1;

			return	distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) ;
		}
		if (visited [mask][n][idx]) {
			return dp[mask][n][idx];
		}
		visited [mask][n][idx] = true;
		if(idx == 0) {
			dp[mask][n][idx] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i)) == 0) {
					int x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<i)), i, 1);
					if(dp[mask][n][idx] > x) {
						dp[mask][n][idx] = x;
						nextstate[mask][n][0] = i;
						nextstate[mask][n][1] = (mask | (1<<i));
						nextstate[mask][n][2] = 1;
					}
				}
			}
			return dp[mask][n][idx];
		}
		if(n == 2) {
			nextstate[mask][n][0] = 0;
			nextstate[mask][n][1] = mask;
			nextstate[mask][n][2] = 0;
			return dp[mask][n][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		}
		dp[mask][n][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		nextstate[mask][n][0] = 0;
		nextstate[mask][n][1] = mask ;
		nextstate[mask][n][2] = 0;
		for (int i = 1; i < pos.length; i++) {
			if ((mask & (1<<i)) == 0) {
				int x = distace(pos[idx][0], pos[i][0], pos[idx][1], pos[i][1]) + solve((mask | (1<<i)), i, 2);
				if(dp[mask][n][idx] > x) {
					dp[mask][n][idx] = x;
					nextstate[mask][n][0] = i;
					nextstate[mask][n][1] = (mask | (1<<i));
					nextstate[mask][n][2] = 2;
				}

			}
		}
		return dp[mask][n][idx];
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n + 1)][3][n+1], new boolean[1<<(n + 1)][3][n+1], new int[1<<(n + 1)][3][3]);
		System.out.println(z.solve(1, 0, 0));
		System.out.print(0+" ");
		z.print(1, 0);
	}

}

import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

	static int n, memo[], dS[], dd[][];

	static int dp(int idx, int msk)
	{
		if(msk == (1 << n) - 1)
			return 0;
		if(memo[msk] != -1)
			return memo[msk];
		while((msk & 1 << idx) != 0)
			++idx;
		int ret = dS[idx] * 2 + dp(idx + 1, msk | 1 << idx);
		for(int i = 0; i < n; ++i)
			if((msk & 1 << i) == 0)
				ret = Math.min(ret, dS[i] + dS[idx] + dd[i][idx] + dp(idx + 1, msk | 1 << i | 1 << idx));
		return memo[msk] = ret;
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Point s = new Point(sc.nextInt(), sc.nextInt());
		n = sc.nextInt();
		Point[] a = new Point[n];
		for(int i = 0; i < n; ++i)
			a[i] = new Point(sc.nextInt(), sc.nextInt());
		dS = new int[n];
		dd = new int[n][n];
		for(int i = 0; i < n; ++i)
		{
			dS[i] = dist2(s, a[i]);
			for(int j = 0; j < n; ++j)
				dd[i][j] = dist2(a[i], a[j]);
		}

		memo = new int[1 << n];
		Arrays.fill(memo, -1);
		out.println(dp(0, 0));
		out.flush();
		out.close();
	}

	static int dist2(Point a, Point b) { return sq(a.x - b.x) + sq(a.y - b.y); }

	static int sq(int x) { return x * x; }

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}
	}
}

import java.util.*;
import java.io.*;

public class C0008 {

    public static void main(String args[]) throws Exception {
        new C0008();
    }

    int n;
    int target;
    int dp[];
    int next[];
    int dist[][];

    C0008() throws Exception {
        PandaScanner sc = null;
        PrintWriter out = null;
        try {
            sc = new PandaScanner(System.in);
            out = new PrintWriter(System.out);
        } catch (Exception ignored) {
        }

        dist = new int[26][26];
        int[][] p = new int[26][];
        p[25] = new int[] {sc.nextInt(), sc.nextInt()};
        n = sc.nextInt();
        target = (1 << n) - 1;

        for (int i = 0; i < n; i++) {
            p[i] = new int[] {sc.nextInt(), sc.nextInt()};
            dist[i][25] = getDist(p[i], p[25]);
            for (int j = 0; j < i; j++) {
                dist[j][i] = getDist(p[j], p[i]);
            }
        }

        next = new int[1 << n];

        dp = new int[1 << n];
        Arrays.fill(dp, -1);

        out.println(go(0));

        ArrayList<Integer> paths = new ArrayList<Integer>();
        paths.add(0);
        int curr = 0;
        while (curr != target) {
            for (Integer i: getBits(next[curr], true)) {
                paths.add(i + 1);
            }
            paths.add(0);
            curr |= next[curr];
        }
        out.println(paths.toString().replaceAll("[^ 0-9]", ""));

        out.close();
        System.exit(0);
    }

    int go(int mask) {
        if (mask == target) {
            return 0;
        }
        if (dp[mask] != -1) {
            return dp[mask];
        }

        ArrayList<Integer> notDone = getBits(mask, false);

        dp[mask] = Integer.MAX_VALUE;

        for (Integer i: notDone) {
            if (dp[mask] > (dist[i][25] << 1) + go(mask | (1 << i))) {
                dp[mask] = (dist[i][25] << 1) + go(mask | (1 << i));
                next[mask] = 1 << i;
            }
            for (Integer j: notDone) {
                if (j == i) break;
                if (dp[mask] > (dist[j][25] + dist[j][i] + dist[i][25]) + go(mask | (1 << i) | (i << j))) {
                    dp[mask] = (dist[j][25] + dist[j][i] + dist[i][25]) + go(mask | (1 << i) | (i << j));
                    next[mask] = (1 << i) | (1 << j);
                }
            }
        }

        return dp[mask];
    }

    int getDist(int[] p1, int[] p2) {
        return sq(p1[0] - p2[0]) + sq(p1[1] - p2[1]);
    }

    int sq(int a) {
        return a * a;
    }

    ArrayList<Integer> getBits(int mask, boolean on) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            if (((mask & (1 << i)) == 0) ^ on) {
                res.add(i);
            }
        }
        return res;
    }

    //The PandaScanner class, for Panda fast scanning!
    public class PandaScanner {
        BufferedReader br;
        StringTokenizer st;
        InputStream in;

        PandaScanner(InputStream in) throws Exception {
            br = new BufferedReader(new InputStreamReader(this.in = in));
        }

        public String next() throws Exception {
            if (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(br.readLine().trim());
                return next();
            }
            return st.nextToken();
        }

        public boolean hasNext() throws Exception {
            return (st != null && st.hasMoreTokens()) || in.available() > 0;
        }

        public long nextLong() throws Exception {
            return Long.parseLong(next());
        }

        public int nextInt() throws Exception {
            return Integer.parseInt(next());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class LookingForOrder {
	int [][] pos;
	int [] dp;
	int [][]nextstate;

	public LookingForOrder(int[][] pos, int[] dp, int[][]nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.nextstate = nextstate;
	}
	void print(int mask) {
		if(mask < (1<<pos.length - 1) - 1 ) {
			if (nextstate[mask][2] != 0) {
				System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" "+ 0+" ");
			}
			else
			System.out.print(nextstate[mask][0] + " "+nextstate[mask][2]+" ");
			print(nextstate[mask][1]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask) {
		if(mask == (1<<pos.length - 1) - 1 ) {
			nextstate [mask][0] = 0;
			nextstate[mask][1] = 1<<pos.length;

			return	0 ;
		}
		if (dp [mask]!= 0) {
			return dp[mask];
		}

			dp[mask] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i - 1)) == 0) {
					int x = 2 * distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<(i - 1))));
					if(dp[mask] > x) {
						dp[mask] = x;
						nextstate[mask][0] = i;
						nextstate[mask][1]= (mask | (1<<i - 1));
						nextstate[mask][2] = 0;

					for (int j = i + 1; j < pos.length; j++) {
						if (((mask | (1<<i - 1)) & (1<<j - 1)) == 0) {
							x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve(((mask | (1<<i - 1)) | (1<<j - 1)))
							+ distace(pos[j][0], pos[i][0], pos[j][1], pos[i][1])+distace(pos[0][0], pos[j][0], pos[0][1], pos[j][1]) ;

							if(dp[mask] > x) {
								dp[mask] = x;
								nextstate[mask][0] = i;
								nextstate[mask][1]= (mask | (1<<i - 1)) | (1<<j - 1);
								nextstate[mask][2] = j;
							}
							break;
						}
					}}
				}
			}
			return dp[mask];
		}

	public static void main(String[] args) {
		InputReader0 in = new InputReader0(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n)],  new int[1<<(n)][3]);
		System.out.println(z.solve(0));
		System.out.print(0+" ");
		z.print(0);
	}

}
class InputReader0 {
	BufferedReader reader;
	StringTokenizer tokenizer;

	public InputReader0(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public long nextLong() {
		return Long.parseLong(next());
	}

	public int nextInt() {
		return Integer.parseInt(next());
	}

}

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

public class Newbie {

    static InputReader sc = new InputReader(System.in);
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {
        solver s = new solver();
        int t = 1;
        while (t > 0) {
            s.solve();
            t--;
        }
        out.close();
    }

    static class InputReader {

        public BufferedReader br;
        public StringTokenizer token;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream), 32768);
            token = null;
        }

        public String sn() {
            while (token == null || !token.hasMoreTokens()) {
                try {
                    token = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return token.nextToken();
        }

        public int ni() {
            return Integer.parseInt(sn());
        }

        public String snl() throws IOException {
            return br.readLine();
        }

        public long nlo() {
            return Long.parseLong(sn());
        }

        public double nd() {
            return Double.parseDouble(sn());
        }

        public int[] na(int n) {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = sc.ni();
            return a;
        }

        public long[] nal(int n) {
            long a[] = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = sc.nlo();
            return a;
        }
    }

    static int inf = 5000013;

    static class solver {
        DecimalFormat df = new DecimalFormat("0.00000000");
        int maxi = 200000000;
        int mod = (int) (1e9 + 7);

        long dis(int x1, int y1, int x2, int y2) {
            return Math.abs(x2 - x1) * Math.abs(x2 - x1) + Math.abs(y2 - y1) * Math.abs(y2 - y1);
        }

        void solve() {
            int hx = sc.ni();
            int hy = sc.ni();
            LinkedList<Integer> ans = new LinkedList<>();
            int n = sc.ni();
            int point[][] = new int[n + 1][2];
            point[0][0] = hx;
            point[0][1] = hy;
            for (int i = 1; i <= n; i++) {
                point[i][0] = sc.ni();
                point[i][1] = sc.ni();
            }
            long mat[][] = new long[n + 1][n + 1];
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= n; j++) {
                    mat[i][j] = dis(point[i][0], point[i][1], point[j][0], point[j][1]);
                }
            }
            int mask = (1 << n);
            long dp[] = new long[mask];
            Arrays.fill(dp, Integer.MAX_VALUE);
            dp[0] = 0;
            int parent[] = new int[mask];
            for (int i = 0; i < mask; i++) {
                int x = Integer.bitCount(i);
                int last = (int) (Math.log10(i ^ parent[i]) / Math.log10(2)) + 1;
                if (last < 0)
                    last = 0;
                if (x % 2 == 0) {
                    for (int j = 0; j < n; j++) {
                        if ((i & (1 << j)) == 0) {
                            long d = dp[i] + mat[last][0] + mat[0][j + 1];
                            if (dp[i | (1 << j)] > d) {
                                dp[i | (1 << j)] = d;
                                parent[i | (1 << j)] = i;
                            }
                        }
                    }
                } else {
                    for (int j = 0; j < n; j++) {
                        if ((i & (1 << j)) == 0) {
                            long d1 = dp[i] + mat[last][j + 1];
                            long d2 = dp[i] + mat[last][0] + mat[0][j + 1];
                            if (dp[i | (1 << j)] > d1) {
                                dp[i | (1 << j)] = d1;
                                parent[i | (1 << j)] = i;
                            }
                            if (dp[i | (1 << j)] > d2) {
                                dp[i | (1 << j)] = d2;
                                parent[i | (1 << j)] = i;
                            }
                        }
                    }
                }
            }
            int last = (int) (Math.log10((mask - 1) ^ parent[mask - 1]) / Math.log10(2)) + 1;
            if (last < 0)
                last = 0;
            long res = dp[mask - 1] + mat[last][0];
            out.println(res);
            int p = mask - 1;
            while (p > 0) {
                last = (int) (Math.log10(p ^ parent[p]) / Math.log10(2)) + 1;
                if (parent[p] == 0) {
                    ans.add(0, last);
                    ans.add(0, 0);
                    p = 0;
                } else {
                    int plast = (int) (Math.log10(parent[p] ^ parent[parent[p]]) / Math.log10(2)) + 1;
                    ans.add(0, last);
                    if (dp[p] != (dp[parent[p]] + mat[plast][last]))
                        ans.add(0, 0);
                }
                p = parent[p];
            }
            ans.add(0);
            for (int h : ans)
                out.print(h + " ");
            out.println();
        }
    }
}

import java.io.*;
import java.util.*;

public class CF8C {
	FastScanner in;
	PrintWriter out;

	int[] x, y;

	int dist(int v, int u) {
		return (x[v] - x[u]) * (x[v] - x[u]) + (y[v] - y[u]) * (y[v] - y[u]);
	}

	void solve() {
		int x1 = in.nextInt();
		int y1 = in.nextInt();
		int n = in.nextInt();

		x = new int[n + 1];
		y = new int[n + 1];
		for (int i = 1; i <= n; i++) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
		}
		x[0] = x1;
		y[0] = y1;
		int[] dp = new int[(1 << n)];
		int[][] dpFrom = new int[1 << n][2];
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0] = 0;
		for (int st = 0; st < (1 << n); st++) {
			if (dp[st] == Integer.MAX_VALUE)
				continue;
			ArrayList<Integer> available = new ArrayList<Integer>();
			for (int i = 0; i < n; i++)
				if ((st & (1 << i)) == 0)
					available.add(i);
			if (available.size() == 0)
				continue;
			if (available.size() == 1) {
				int val = dp[st] + dist(available.get(0) + 1, 0) * 2;
				if (dp[(1 << n) - 1] > val) {
					dp[(1 << n) - 1] = val;
					dpFrom[(1 << n) - 1][0] = available.get(0);
					dpFrom[(1 << n) - 1][1] = -1;
				}
				continue;
			}
			for (int i = 0; i < available.size(); i++)
				for (int j = i + 1; j < available.size(); j++) {
					int val = dp[st] + dist(available.get(i) + 1, 0)
							+ dist(available.get(j) + 1, 0)
							+ dist(available.get(i) + 1, available.get(j) + 1);
					if (dp[st | (1 << available.get(i))
							| (1 << available.get(j))] > val) {
						dp[st | (1 << available.get(i))
								| (1 << available.get(j))] = val;
						dpFrom[st | (1 << available.get(i))
								| (1 << available.get(j))][0] = available
								.get(i);
						dpFrom[st | (1 << available.get(i))
								| (1 << available.get(j))][1] = available
								.get(j);
					}
				}
			for (int i = 0; i < available.size(); i++) {
				int val = dp[st] + dist(available.get(i) + 1, 0) * 2;
				if (dp[st | (1 << available.get(i))] > val) {
					dp[st | (1 << available.get(i))] = val;
					dpFrom[st | (1 << available.get(i))][0] = available.get(i);
					dpFrom[st | (1 << available.get(i))][0] = -1;
				}
			}
		}
		out.println(dp[(1 << n) - 1]);
		int nowSt = (1 << n) - 1;
		ArrayList<Integer> ans = new ArrayList<Integer>();
		ans.add(0);
		while (nowSt != 0) {
			int n1 = dpFrom[nowSt][0];
			int n2 = dpFrom[nowSt][1];
			if (n1 != -1)
				ans.add(n1 + 1);
			if (n2 != -1)
				ans.add(n2 + 1);
			if (n1 != -1)
				nowSt -= (1 << n1);
			if (n2 != -1)
				nowSt -= (1 << n2);
			ans.add(0);
		}
		for (int i = ans.size() - 1; i >= 0; i--)
			out.print(ans.get(i) + " ");
	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}
	}

	public static void main(String[] args) {
		new CF8C().runIO();
	}
}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class CF008C {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int x = s.nextInt();
        int y = s.nextInt();
        int n = s.nextInt();
        int[] xCoord = new int[n];
        int[] yCoord = new int[n];
        for(int i = 0;i<n;i++){
            xCoord[i] = s.nextInt();
            yCoord[i] = s.nextInt();
        }
        int[][] dp = new int[n][n];
        for(int i = 0;i<n;i++){
            Arrays.fill(dp[i],-1);
        }
        for(int i = 0;i<n;i++){
            dp[i][i] = 0;
            for(int j = 0;j<i;j++){
                dp[i][j] = calculateDistanceBetweenIandJ(xCoord,yCoord,i,j);
                dp[j][i] = dp[i][j];
            }
        }
        int[] distFromOrigin = new int[n];
        HashMap<Integer,Boolean> map = new HashMap<>();
        for(int i=0;i<n;i++){
            distFromOrigin[i] = (int) (Math.pow((xCoord[i] - x),2) + Math.pow(yCoord[i] - y,2));
            map.put(i,true);
        }
//        System.out.println(0);
        long sum = 0;
        String str = "0 ";

        while(!map.isEmpty()){
            int first = 0;
            int second = Integer.MIN_VALUE;
            if(map.size() == 1){
                first = new ArrayList<Integer>(map.keySet()).get(0) + 1;
                int min = distFromOrigin[first - 1] + distFromOrigin[first - 1];
                sum += min;
                map.remove(first - 1);
            }else {
                int min = Integer.MAX_VALUE;

                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < i; j++) {
                        if (map.containsKey(i) && map.containsKey(j) && distFromOrigin[i] + distFromOrigin[j] + dp[i][j] < min) {
                            min = distFromOrigin[i] + distFromOrigin[j] + dp[i][j];
                            first = i + 1;
                            second = j + 1;
                        }
                    }
                }
                sum += min;
                map.remove(first - 1);
                map.remove(second - 1);
            }
            if(second == Integer.MIN_VALUE){
                str = str + first + " ";
            }else{
                if(map.size() == 0) {
                    str = str + first + " " + second + " ";
                }else{
                    str = str + first + " " + second + " 0 ";
                }
            }
//            System.out.print(first + " " + second + " ");
        }
        System.out.println(sum);
        System.out.println(str + "0");

//        System.out.print(sum);
//        System.out.print(0);
    }

    private static int calculateDistanceBetweenIandJ(int[] xCoord, int[] yCoord, int i, int j) {
        int length = (int) (Math.pow((xCoord[i] - xCoord[j]),2) + Math.pow(yCoord[i] - yCoord[j], 2));
        return length;
    }
}

import java.awt.Point;
import java.util.Scanner;

public class LookingForOrder {
	int [][] pos;
	int [][] dp;
	boolean [][]visited;
	int [][][]nextstate;

	public LookingForOrder(int[][] pos, int[][] dp, boolean[][] visited, int[][][] nextstate) {
		super();
		this.pos = pos;
		this.dp = dp;
		this.visited = visited;
		this.nextstate = nextstate;
	}
	void print(int mask,int idx) {
		if(mask <= (1<<pos.length) - 1 ) {
			System.out.print(nextstate[mask][0][idx] + " ");
			print(nextstate[mask][1][idx],nextstate[mask][0][idx]);
		}
	}
	int distace(int x1,int x2,int y1,int y2) {
		return (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
	}
	int solve(int mask,int idx,int n) {
		if(mask == (1<<pos.length) - 1 ) {
			nextstate [mask][0][idx] = 0;
			nextstate[mask][1][idx] = 1<<pos.length;
			nextstate[mask][2][idx] = 1;

			return	distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) ;
		}
		if (visited [mask][idx]) {
			return dp[mask][idx];
		}
		visited [mask][idx] = true;
		if(idx == 0) {
			dp[mask][idx] = (int) 1e9;
			for (int i = 1; i < pos.length; i++) {
				if ((mask & (1<<i)) == 0) {
					int x = distace(pos[0][0], pos[i][0], pos[0][1], pos[i][1]) + solve((mask | (1<<i)), i, 1);
					if(dp[mask][idx] > x) {
						dp[mask][idx] = x;
						nextstate[mask][0][idx] = i;
						nextstate[mask][1][idx] = (mask | (1<<i));
						nextstate[mask][2][idx] = 1;
					}
				}
			}
			return dp[mask][idx];
		}
		if(n == 2) {
			nextstate[mask][0][idx] = 0;
			nextstate[mask][1][idx] = mask;
			nextstate[mask][2][idx] = 0;
			return dp[mask][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		}
		dp[mask][idx] = distace(pos[0][0], pos[idx][0], pos[0][1], pos[idx][1]) + solve(mask, 0, 0);
		nextstate[mask][0][idx] = 0;
		nextstate[mask][1][idx] = mask ;
		nextstate[mask][2][idx] = 0;
		for (int i = 1; i < pos.length; i++) {
			if ((mask & (1<<i)) == 0) {
				int x = distace(pos[idx][0], pos[i][0], pos[idx][1], pos[i][1]) + solve((mask | (1<<i)), i, 2);
				if(dp[mask][idx] > x) {
					dp[mask][idx] = x;
					nextstate[mask][0][idx] = i;
					nextstate[mask][1][idx] = (mask | (1<<i));
					nextstate[mask][2][idx] = 2;
				}

			}
		}
		return dp[mask][idx];
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int x = in.nextInt(),y = in.nextInt();
		int n = in.nextInt();
		int [][] pos = new int [n + 1][2];
		pos [0][0] = x;
		pos [0][1] = y;
		for (int i = 1; i < pos.length; i++) {
			pos [i][0] = in.nextInt();
			pos [i][1] = in.nextInt();
		}
		LookingForOrder z = new LookingForOrder(pos, new int [1<<(n + 1)][n+1], new boolean[1<<(n + 1)][n+1], new int[1<<(n + 1)][3][n+1]);
		System.out.println(z.solve(1, 0, 0));
		System.out.print(0+" ");
		z.print(1,0);
	}

}

import java.io.*;
import java.util.*;
//import java.lang.*;

public class Main {

	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		String input[] = kek.readLine().split(" ");
		int xH = Integer.parseInt(input[0]);
		int yH = Integer.parseInt(input[1]);
		int N = Integer.parseInt(kek.readLine());
		int xcoords[] = new int[N + 1];
		int ycoords[] = new int[N + 1];
		int dFromStart[] = new int[N + 1];
		int dFromEachOther[][] = new int[N + 1][N + 1];
		boolean taken[] = new boolean[N + 1];
		List<Integer> finalPath = new ArrayList<>();
		int minFromStart = 1;
		int max = 1;
		int objTrack = N;

		for(int i = 1; i <= N; i++){
			input = kek.readLine().split(" ");
			int x = Integer.parseInt(input[0]);
			int y = Integer.parseInt(input[1]);
			xcoords[i] = x;
			ycoords[i] = y;
			dFromStart[i] = getTime(xH, yH, x, y);
			minFromStart = dFromStart[minFromStart] > dFromStart[i] ? i : minFromStart;
			taken[i] = false;
		}

		for(int i = 1; i <= N; i++){
			int tempMax = 0;
			int x = xcoords[i];
			int y = ycoords[i];
			for(int j = 1; j <= N; j++){
				int x2 = xcoords[j];
				int y2 = ycoords[j];
				if(j != i){
					dFromEachOther[i][j] = getTime(x, y, x2, y2);
					tempMax = dFromEachOther[i][tempMax] < dFromEachOther[i][j] ? j : tempMax;
				} else {
					dFromEachOther[i][j] = 10000;
				}
			}
			max = tempMax > max ? tempMax : max;
		}

		int minTrack = max;
		int numOfObjs = 1;

		finalPath.add(0);
		finalPath.add(minFromStart);
		objTrack--;
		taken[minFromStart] = true;
		int res = dFromStart[minFromStart];

		for(int travel = 0; travel < N; travel++){
			if(objTrack > 0){
				if(travel > 0){
					minFromStart = minTrack;
				}
				for(int i = 1; i <= N; i++){
					if(taken[i] == false){
						minTrack = dFromEachOther[minFromStart][minTrack] > dFromEachOther[minFromStart][i] ? i : minTrack;
					}
				}
					res += dFromEachOther[minFromStart][minTrack];
					finalPath.add(minTrack);
					objTrack--;
					taken[minTrack] = true;
					numOfObjs += 1;
					if(numOfObjs >= 2){
						res += dFromStart[minTrack];
						numOfObjs = 1;
						finalPath.add(0);
						if(objTrack > 0){
							boolean first = true;
							for(int check = 1; check <= N; check++){
								if(taken[check] == false){
									if(first == true){
										minTrack = check;
										first = false;
									} else {
										minTrack = dFromStart[minTrack] > dFromStart[check] ? check : minTrack;
									}
								}
							}
							res += dFromStart[minTrack];
							finalPath.add(minTrack);
							taken[minTrack] = true;
						}
					}
			}
		}

		System.out.println(res);
		for(int i : finalPath){
			System.out.print(i + " ");
		}

	}

	static int getTime(int x1, int y1, int x2, int y2){
		int x = (x2 - x1);
		int fx = x * x;
		int y = (y2 - y1);
		int fy = y * y;
		int result = fx + fy;
		return result;
	}

	static void testPrint(List<Integer> l){
		for(int i : l){
			System.out.print(i + " ");
		}
	}
}

import java.io.*;
import java.util.*;

public class CF8C
{
	static final boolean _DEBUG = true;

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner(BufferedReader _br) {
			br = _br;
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					e.printStackTrace();
					return "";
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	static MyScanner   scan;
	static PrintWriter out;

	static int debugCount = 0;
	static void debug(String msg) {
		if (_DEBUG && debugCount < 200) {
			out.println(msg);
			out.flush();
			debugCount++;
		}
	}

	static final int INF = Integer.MAX_VALUE >> 1;

    public static void main (String args[]) throws IOException {
//    	scan = new MyScanner(new BufferedReader(new FileReader("test.in")));
    	scan = new MyScanner(new BufferedReader(new InputStreamReader(System.in)));
    	out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        CF8C inst = new CF8C();
        inst.execute();
        out.close();
    }

    int dp[];
    int p[];
    int x[];
    int y[];
    int[][] dist;
    int n;

    void backtrack() {
    	int last = (1 << n) - 1;
    	out.print(0);
    	while (last != 0) {
    		int t = p[last];
    		for (int i = 0; i < n; i++) {
    			if ((t & (1 << i)) != 0) {
    				out.print(" " + (i+1));
    				for (int j = i + 1; j < n; j++) {
    	    			if ((t & (1 << j)) != 0) {
    	    				out.print(" " + (j+1));
    	    				break;
    	    			}
    				}
    				break;
    			}
    		}
    		out.print(" 0");
    		last ^= t;
    	}
    	out.println();
    }

    void execute() throws IOException {
    	int rootx = scan.nextInt();
    	int rooty = scan.nextInt();
    	n = scan.nextInt();
        int x[] = new int[n+1];
        int y[] = new int[n+1];
        int[][] dist = new int[n+1][n+1];
        for(int i = 0; i < n; i++) {
    		x[i] = scan.nextInt();
    		y[i] = scan.nextInt();
    	}
    	x[n] = rootx;
    	y[n] = rooty;
    	for (int i = 0; i <= n; i++) {
    		for (int j = 0; j <= n; j++) {
    			int dx = x[i] - x[j];
    			int dy = y[i] - y[j];
    			dist[i][j] = dx * dx + dy * dy;
    		}
    	}
    	dp = new int[1<<n];
    	p = new int[1<<n];
    	Arrays.fill(dp, INF);
//    	Arrays.fill(p, -1);
    	dp[0] = 0;
    	p[0] = -1;

    	int last = (1 << n) - 1;
    	for(int i = 1; i <= last; i++) {
    		int first = 0;
    		for (; first < n; first++) {
    			if ((i & (1 << first)) != 0) break;
    		}
    		int temp = dp[i ^ (1 << first)] + dist[n][first] * 2;
    		if (temp < dp[i]) {
    			dp[i] = temp;
    			p[i] = 1 << first;
    		}
    		int second = first + 1;
    		for (; second < n; second++) {
    			if ((i & (1 << second)) != 0) break;
    		}
    		if (second != n) {
    			int s2 = (1 << first) | ( 1 << second);
    			temp = dp[i ^ s2] + dist[n][first] + dist[first][second] + dist[second][n];
    			if (temp < dp[i]) {
    				dp[i] = temp;
    				p[i] = s2;
    			}
    		}
    	}
    	out.println(dp[last]);
    	backtrack();
    }
}

import java.util.*;

public class C
{
   public static void main(String[] args)
   {
      new C(new Scanner(System.in));
   }

   vect[] vs;
   int N;
   int oo = 987654321;

   ArrayList<choice> cs;
   choice[][] cg;

   int MF;

   int[] memo;
   int[] next;

   int go(int m)
   {
      if (m == MF)
         return 0;
      if (memo[m] != -1)
         return memo[m];

      // Try a new place
      int res = oo;
      int nxt = -1;

      int i=0;
      for (i=0; i<N; i++)
      {
         if (((1<<i)&m) == 0)
            break;
      }

      for (int j=0; j<N; j++)
      {
         choice cc = cg[i][j];
         if ((m&cc.m) > 0)
            continue;

         int r2 = cc.cost+go(m|cc.m);
         if (r2 < res)
         {
            res = r2;
            nxt = i;
         }
      }

      memo[m] = res;
      next[m] = nxt;
      return res;
   }

   public C(Scanner in)
   {
      vect vt = new vect(in.nextInt(), in.nextInt());
      N = in.nextInt();
      vs = new vect[N+1];
      vs[N] = vt;
      for (int i=0; i<N; i++)
         vs[i] = new vect(in.nextInt(), in.nextInt());

      // Precompute all choices and masks
      cs = new ArrayList<choice>();
      cg = new choice[N][N];
      for (int i=0; i<N; i++)
      {
         choice cc = new choice(2*vs[i].dist(vt), 1<<i);
         cc.add(i);
         cs.add(cc);
         cg[i][i] = cc;
      }

      for (int i=0; i<N; i++)
      {
         for (int j=i+1; j<N; j++)
         {
            int dist = vs[i].dist(vt);
            dist += vs[i].dist(vs[j]);
            dist += vs[j].dist(vt);
            choice cc = new choice(dist, (1<<i)|(1<<j));
            cc.add(i); cc.add(j);
            cs.add(cc);
            cg[i][j] = cc;
            cg[j][i] = cc;
         }
      }

      MF = (1<<N)-1;
      next = new int[MF+1];
      memo = new int[MF+1];

      Arrays.fill(next, -1);
      Arrays.fill(memo, -1);

      int res = go(0);
      System.out.println(res);

      int m = 0;
      StringBuilder sb = new StringBuilder();
      while (m != -1)
      {
         //System.out.println(Integer.toBinaryString(m));
         sb.append(0);
         sb.append(' ');
         int i = next[m];
         if (i == -1)
            break;
         choice cc = cs.get(i);
         for (int j : cc.iv)
         {
            sb.append(f(j));
            sb.append(' ');
         }
         m = m|cc.m;
      }
      System.out.println(sb.toString().trim());
   }

   int f(int i)
   {
      if (i == N)
         return 0;
      return i+1;
   }
}

class choice
{
   int cost;
   int m;
   ArrayList<Integer> iv;

   public choice(int c, int mm)
   {
      cost = c;
      m = mm;
      iv = new ArrayList<Integer>(2);
   }

   void add(int i)
   {
      iv.add(i);
   }
}

class vect
{
   int x, y;

   public vect(int i, int j)
   {
      x=i; y=j;
   }

   int dist(vect rhs)
   {
      int xx = x-rhs.x;
      int yy = y-rhs.y;
      return xx*xx+yy*yy;
   }
}

import java.util.*;
import java.io.*;

public class Main{

    BufferedReader in;
    StringTokenizer str = null;
    PrintWriter out;

    private String next() throws Exception{
    	if (str == null || !str.hasMoreElements())
    	    str = new StringTokenizer(in.readLine());
    	return str.nextToken();
    }

    private int nextInt() throws Exception{
	   return Integer.parseInt(next());
    }

    int []x,y;
    int n;
    int []dp, prev;

    public void run() throws Exception{
    	in = new BufferedReader(new InputStreamReader(System.in));
    	out = new PrintWriter(System.out);

    	int xs = nextInt();
    	int ys = nextInt();
    	n = nextInt();
    	x = new int[n];
    	y = new int[n];
    	for(int i=0;i<n;i++){
    		x[i] = nextInt();
    		y[i] = nextInt();
    	}

    	int one[] = new int[n];
    	for(int i=0;i<n;i++){
    		one[i] = dist(xs, ys, x[i], y[i]);
    	}

    	int two[][] = new int[n][n];
    	for(int i=0;i<n;i++){
    		for(int j=i+1;j<n;j++){
    			two[i][j] = two[j][i] = dist(xs, ys, x[i], y[i]) + dist(x[i], y[i], x[j], y[j]) + dist(xs, ys, x[j], y[j]);
    		}
    	}

    	dp = new int[1<<n];
    	Arrays.fill(dp, Integer.MAX_VALUE/2);
    	dp[0] = 0;
    	prev = new int[1<<n];
    	Arrays.fill(prev, -1);

    	for(int mask=1;mask<(1<<n);mask++){
    		int i = 0;
    		while((mask & (1<<i)) == 0) i++;
    		dp[mask] = dp[mask ^ (1<<i)] + 2*one[i];
    		prev[mask] = i+1;
    		for(int j=i+1;j<n;j++){
    			if ((mask & (1<<j)) > 0) {
    				if (dp[mask] > dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j]) {
    					dp[mask] = dp[mask ^ (1<<i) ^ (1<<j)] + two[i][j];
    					prev[mask] = 100 * (i+1) + (j+1);
    				}
    			}
    		}
    	}

    	out.println(dp[(1<<n)-1]);
    	out.print(0 + " ");
    	int cur = (1<<n)-1;
    	int i = 0, j = 0;
    	while(cur > 0) {
    		i = prev[cur]/100;
    		j = prev[cur]%100;

    		if (i > 0) {
    			cur^=1<<(i-1);
    			out.print(i + " ");
    		}

    		if (j > 0) {
    			cur^=1<<(j-1);
    			out.print(j + " ");
    		}

    		if (i > 0 && j > 0) {
    			out.print(0 + " ");
    		}
    	}
    	if (i == 0 || j == 0) {
    		out.println(0);
    	}
		out.close();
    }

    private String bit2str(int mask, int n) {
    	String s = "";
    	for(int i=0;i<n;i++){
    		if ((mask & (1<<i)) > 0){
    			s+="1";
    		}else{
    			s+="0";
    		}
    	}
    	while(s.length() < n)
    		s+="0";

    	return new StringBuilder(s).reverse().toString();
    }

    private int dist(int x1, int y1, int x2, int y2) {
    	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    }

    public static void main(String args[]) throws Exception{
	   new Main().run();
    }
}

import java.util.Arrays;
import java.util.Scanner;

public class C
{

    public static void main(String[] args)
    {
        new C();
    }

    final int oo = (int)1e9;

    int Hx,Hy;

    int N;
    int[][] P;

    int[] memo;
    int[][] soln;

    int[] dist1;
    int[][] dist2;

    C()
    {
        Scanner in = new Scanner(System.in);
        Hx=in.nextInt();
        Hy=in.nextInt();

        N=in.nextInt();
        P=new int[N][2];
        for (int i=0; i<N; ++i)
        {
            P[i][0]=in.nextInt();
            P[i][1]=in.nextInt();
        }

        memo=new int[1<<N];
        Arrays.fill(memo, -1);
        soln=new int[2][1<<N];

        dist1=new int[N];
        Arrays.fill(dist1, -1);
        dist2=new int[N][N];
        for (int[] d : dist2) Arrays.fill(d, -1);

        int res=go((1<<N)-1);
        System.out.println(res);

        int set=(1<<N)-1;
        while (set>0)
        {
            System.out.print("0 ");
            System.out.print((soln[0][set]+1)+" ");
            if (soln[1][set]>-1) System.out.print((soln[1][set]+1)+" ");

            if (soln[1][set]>-1)
            {
                set-=((1<<soln[0][set])+(1<<soln[1][set]));
            }
            else
            {
                set-=(1<<soln[0][set]);
            }
        }
        System.out.println("0");
    }

    int go(int set)
    {
        if (set==0)
            return 0;
        if (memo[set]>-1)
            return memo[set];

        if (Integer.bitCount(set)==1)
        {
            int i=0;
            while (!on(set,i)) ++i;
            memo[set]=dist(i);
            soln[0][set]=i;
            soln[1][set]=-1;
            return memo[set];
        }

        int res=oo;
        int i=0;
        while (!on(set,i)) ++i;

        for (int j=i+1; j<N; ++j)
        {
            if (on(set,j))
            {
                int tmp=dist(i,j)+go(set-(1<<i)-(1<<j));
                if (tmp<res)
                {
                    res=tmp;
                    soln[0][set]=i;
                    soln[1][set]=j;
                }
            }
        }

        return memo[set]=res;
    }

    // H->i->H
    int dist(int i)
    {
        if (dist1[i]>-1) return dist1[i];

        int dx=P[i][0]-Hx;
        int dy=P[i][1]-Hy;
        return dist1[i]=2*(dx*dx+dy*dy);
    }

    // H->i->j->H
    int dist(int i, int j)
    {
        if (dist2[i][j]>-1) return dist2[i][j];

        int res=0,dx,dy;

        dx=P[i][0]-Hx;
        dy=P[i][1]-Hy;
        res+=dx*dx+dy*dy;

        dx=P[i][0]-P[j][0];
        dy=P[i][1]-P[j][1];
        res+=dx*dx+dy*dy;

        dx=P[j][0]-Hx;
        dy=P[j][1]-Hy;
        res+=dx*dx+dy*dy;

        return dist2[i][j]=res;
    }

    boolean on(int set, int loc)
    {
        return (set&(1<<loc))>0;
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            int bestC = best[set ^ (1 << i)] + single[i];
            int prevC = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            for (int j = i + 1, unoJ = 1 << (i + 1); j < n; ++j, unoJ <<= 1)
                if ((set & unoJ) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < best[set]) {
                        bestC = cur;
                        prevC = unoI | unoJ;
                    }
                }
            best[set] = bestC;
            prev[set] = prevC;
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	void work() {
		int x=in.nextInt(),y=in.nextInt();
		int n=in.nextInt();
		int[][] A=new int[n][2];
		for(int i=0;i<n;i++) {
			A[i]=new int[] {in.nextInt()-x,in.nextInt()-y};
		}
		int[][] dis=new int[n][n];
		for(int i=0;i<n;i++) {
			for(int j=i;j<n;j++) {
				if(i==j) {
					dis[i][i]=A[i][0]*A[i][0]+A[i][1]*A[i][1];
				}else {
					int dx=A[i][0]-A[j][0],dy=A[i][1]-A[j][1];
					dis[i][j]=dx*dx+dy*dy;
					dis[j][i]=dis[i][j];
				}
			}
		}
		int[] dp=new int[1<<n];
		int[][] route=new int[1<<n][2];
		for(int i=0;i<1<<n;i++) {
			route[i][0]=-1;
			route[i][1]=-1;
		}
		for(int i=1;i<1<<n;i++) {
			int b=0;
			for(;((1<<b)&i)==0;b++);
			dp[i]=dp[i-(1<<b)]+2*(dis[b][b]);
			route[i][0]=b;
			for(int j=b+1;j<n;j++) {
				if(((1<<j)&i)>0) {
					int nm=i-(1<<b)-(1<<j);
					int v=dp[nm]+dis[b][j]+dis[b][b]+dis[j][j];
					int p1=b,p2=-1;
					if(v<dp[i]) {
						dp[i]=v;
						p1=b;
						p2=j;
					}
					route[i][0]=p1;
					route[i][1]=p2;
				}
			}
		}
		out.println(dp[(1<<n)-1]);
		out.print(0+" ");
		int cur=(1<<n)-1;
		while(cur>0) {
			int s=1<<route[cur][0];
			out.print((route[cur][0]+1)+" ");
			if(route[cur][1]>=0) {
				out.print((route[cur][1]+1)+" ");
				s+=1<<route[cur][1];
			}
			out.print(0+" ");
			cur-=s;
		}
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 111118315581
 *
 * @author pttrung
 */
public class C {

    static Point hand;
    static int n;
    static Point[] data;
    static int[] next;
    static int []dp;

    public static void main(String[] args) {
        Scanner in = new Scanner();
        PrintWriter out = new PrintWriter(System.out);
        // System.out.println(1 << 24);
        hand = new Point(in.nextInt(), in.nextInt());
        n = in.nextInt();
        data = new Point[n];
        for (int i = 0; i < n; i++) {
            data[i] = new Point(in.nextInt(), in.nextInt());
        }
        next = new int[1 << n];
        dp = new int[1<<n];
        Arrays.fill(dp, -1);
        out.println(cal(0));
        int start = 0;

        do{
          int m = next[start];
          int val = m - start;
          out.print(0 + " ")  ;
          for(int i = 0; i < n; i++){
              if(((1 << i ) & val) != 0){
                  out.print((i + 1) + " ");
              }
          }
         // out.print(0 + " ")  ;
          start = m;
        }while(start != (1 <<n) - 1);
        out.println(0);
        out.close();
    }

    public static int cal(int mask) {
        if ((1 << n) - 1 == mask) {
            //  System.out.println(mask);
            return 0;
        }
        if(dp[mask] != -1){
            return dp[mask];
        }
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (((1 << i) & mask) == 0) {
                int dist = distance(hand, data[i]);
                for (int j = i + 1; j < n; j++) {
                    if (i != j && (((1 << i) & mask) == 0)) {
                        //System.out.println(i + " " + j);
                        int temp = dist + distance(hand, data[j]) + distance(data[i], data[j]) + cal(mask | (1 << i) | (1 << j));
                        if (temp < result) {
                            result = temp;
                            next[mask] = (mask | (1 << i) | (1 << j));
                        }

                    }
                }
                int temp = 2 * dist + cal(mask | (1 << i));
                if (temp < result) {
                    result = temp;
                    next[mask] = (mask | (1 << i));
                }
            }

        }
        dp[mask] = result;
        return result;
    }

    static int distance(Point a, Point b) {
        int total =  (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return total;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}

/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
*/
import java.util.*;
import java.io.*;

   public class x8C
   {
      public static void main(String args[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int Xs = Integer.parseInt(st.nextToken());
         int Ys = Integer.parseInt(st.nextToken());
         int N = Integer.parseInt(infile.readLine());
         int[] x = new int[N];
         int[] y = new int[N];
         for(int i=0; i < N; i++)
         {
            st = new StringTokenizer(infile.readLine());
            x[i] = Integer.parseInt(st.nextToken());
            y[i] = Integer.parseInt(st.nextToken());
         }
         //precompute
         int[] purse = new int[N];
         int[][] grid = new int[N][N];
         for(int i=0; i < N; i++)
            purse[i] = dist(Xs, Ys, x[i], y[i]);
         for(int a=0; a < N; a++)
            for(int b=a; b < N; b++)
            {
               grid[a][b] = dist(x[a], y[a], x[b], y[b]);
               grid[b][a] = grid[a][b];
            }
         //solve
         //always best to pick 2 items then return (vector shit)
         int[] parent = new int[1 << N];
         parent[0] = -1;
         int[] dp = new int[1 << N];
         Arrays.fill(dp, Integer.MAX_VALUE);
         dp[0] = 0;
         for(int mask=0; mask < dp.length-1; mask++)
         {
            int bc = Integer.bitCount(mask);
            int a = 100;
            for(int i=0; i < N; i++)
               if((mask & (1 << i)) == 0)
               {
                  int submask2 = mask|(1 << i);
                  int addon2 = purse[i] << 1;
                  if(dp[submask2] > dp[mask]+addon2)
                  {
                     dp[submask2] = dp[mask]+addon2;
                     parent[submask2] = mask;
                  }
                  a = Math.min(a, i);
               }
            //first item
            for(int i=0; i < N; i++)
            {
               int submask = mask|(1 << a);
               submask |= 1 << i;
               int addon = purse[a]+purse[i]+grid[a][i];
               if(dp[submask] > dp[mask]+addon)
               {
                  dp[submask] = dp[mask]+addon;
                  parent[submask] = mask;
               }
            }
         }
         StringBuilder sb = new StringBuilder();
         sb.append(dp[dp.length-1]+"\n");
         //process dp path
         Stack<Integer> stack = new Stack<Integer>();
         int curr = dp.length-1;
         while(parent[curr] != -1)
         {
            stack.push(curr);
            curr = parent[curr];
         }
         stack.push(curr);
         ArrayList<Integer> path = new ArrayList<Integer>();
         int a = stack.pop();
         int lol = stack.size();
         for(int qw=0; qw < lol; qw++)
         {
            path.add(0);
            int b = stack.pop();
            int c = a^b;
            for(int i=0; i < N; i++)
               if((c & (1 << i)) > 0)
                  path.add(i+1);
            a = b;
         }
         path.add(0);
         for(int x1: path)
            sb.append(x1+" ");
         System.out.println(sb.toString());
      }
      public static int dist(int a, int b, int c, int d)
      {
         return (a-c)*(a-c)+(b-d)*(b-d);
      }
   }