#include <bits/stdc++.h>
using namespace std;
bool comp(long long a, long long b) { return a < b; }
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long power(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n % 2 != 0) {
      res *= a;
      n -= 1;
      res %= 1000000007;
    } else {
      a *= a;
      n /= 2;
      a %= 1000000007;
    }
  }
  return res;
}
bool isPrime(long long n) {
  if (n <= 1) return false;
  if (n <= 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  for (long long i = 5; i * i <= n; i = i + 6) {
    if (n % i == 0 || n % (i + 2) == 0) {
      return false;
    }
  }
  return true;
}
void primeFactors(long long n) {
  while (n % 2 == 0) {
    cout << 2 << " ";
    n = n / 2;
  }
  for (long long i = 3; i <= sqrt(n); i = i + 2) {
    while (n % i == 0) {
      cout << i << " ";
      n = n / i;
    }
  }
  if (n > 2) {
    cout << n << " ";
  }
}
void printDivisors(long long n) {
  for (long long i = 1; i <= sqrt(n); i++) {
    if (n % i == 0) {
      if (n / i == i)
        printf("%d ", i);
      else
        printf("%d %d ", i, n / i);
    }
  }
}
void BellmanFord(long long graph[][3], long long V, long long E,
                 long long src) {
  long long dis[V];
  for (long long i = 0; i < V; i++) dis[i] = INT_MAX;
  dis[src] = 0;
  for (long long i = 0; i < V - 1; i++) {
    for (long long j = 0; j < E; j++) {
      if (dis[graph[j][0]] + graph[j][2] < dis[graph[j][1]])
        dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2];
    }
  }
  bool flag = true;
  for (long long i = 0; i < E; i++) {
    long long x = graph[i][0], y = graph[i][1], weight = graph[i][2];
    if (dis[x] != INT_MAX && dis[x] + weight < dis[y]) {
      flag = false;
      break;
    }
  }
}
void topoSort(long long n, long long m, vector<vector<bool>> &e,
              vector<bool> &visited, long long x) {
  visited[x] = true;
  for (long long i = n - 1; i >= 0; i--) {
    if (e[x][i] and !visited[i]) {
      topoSort(n, m, e, visited, i);
    }
  }
  return;
}
void convertGraphToTree(long long x, vector<vector<long long>> &v,
                        vector<bool> &visited,
                        vector<vector<long long>> &newedges) {
  visited[x] = true;
  for (long long i = 0; i < v[x].size(); i++) {
    if (!visited[v[x][i]]) {
      newedges[x].push_back(v[x][i]);
      convertGraphToTree(v[x][i], v, visited, newedges);
    }
  }
  return;
}
long long subtreeCount(long long x, vector<vector<long long>> &v,
                       vector<bool> &visited, vector<long long> &count) {
  visited[x] = true;
  long long ans = 1;
  for (long long i = 0; i < v[x].size(); i++) {
    if (!visited[v[x][i]]) {
      ans += subtreeCount(v[x][i], v, visited, count);
    }
  }
  count[x] = ans;
  return ans;
}
void create_sparse_table(long long n, vector<long long> &v) {
  long long k = (long long)log2(n * 1.0);
  vector<vector<long long>> st(n + 1, vector<long long>(k + 1, 0));
  for (long long i = 0; i < n; i++) st[i][0] = v[i];
  for (long long j = 1; j <= k; j++) {
    for (long long i = 0; i + (1 << j) <= n; i++)
      st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
  }
  return;
}
vector<long long> fact(200001, 1);
void preNCR() {
  for (long long i = 2; i < 200001; i++) {
    fact[i] = (fact[i - 1] * i) % 1000000007;
  }
  return;
}
long long ncr(long long n, long long r) {
  if (r > n) {
    return 0;
  }
  long long res = fact[n];
  res *= power(fact[r], 1000000007 - 2);
  res %= 1000000007;
  res *= power(fact[n - r], 1000000007 - 2);
  res %= 1000000007;
  return res;
}
void yes() { cout << "YES" << '\n'; }
void no() { cout << "NO" << '\n'; }
void helper(long long n, vector<pair<long long, long long>> &city,
            vector<long long> &k, vector<long long> &c) {
  vector<bool> stn(n, false);
  vector<bool> visited(n, false);
  vector<pair<long long, long long>> edges;
  priority_queue<pair<long long, pair<long long, long long>>,
                 vector<pair<long long, pair<long long, long long>>>,
                 greater<pair<long long, pair<long long, long long>>>>
      pq;
  long long index = -1, temp_cost = INT_MAX;
  for (long long i = 0; i < n; i++) {
    if (c[i] < temp_cost) {
      index = i;
      temp_cost = c[i];
    }
  }
  pq.push({temp_cost, {index, -1}});
  stn[index] = true;
  long long ans = 0;
  while (!pq.empty()) {
    long long x = pq.top().first, y = pq.top().second.first,
              z = pq.top().second.second;
    pq.pop();
    if (visited[y]) continue;
    visited[y] = true;
    ans += x;
    if (z == -1)
      stn[y] = true;
    else
      edges.push_back({y, z});
    for (long long i = 0; i < n; i++) {
      if (!visited[i]) {
        long long cost = (k[y] + k[i]) * (abs(city[y].first - city[i].first) +
                                          abs(city[y].second - city[i].second));
        if (cost < c[i]) {
          pq.push({cost, {i, y}});
        } else {
          pq.push({c[i], {i, -1}});
        }
      }
    }
  }
  long long stn_c = 0;
  for (long long i = 0; i < n; i++) {
    if (stn[i]) stn_c += 1;
  }
  cout << ans << '\n';
  cout << stn_c << '\n';
  for (long long i = 0; i < n; i++) {
    if (stn[i]) cout << i + 1 << " ";
  }
  cout << '\n';
  cout << edges.size() << '\n';
  for (long long i = 0; i < edges.size(); i++) {
    cout << edges[i].first + 1 << " " << edges[i].second + 1 << '\n';
  }
  return;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long n;
  cin >> n;
  vector<pair<long long, long long>> city(n, pair<long long, long long>());
  vector<long long> k(n, 0);
  vector<long long> c(n, 0);
  for (long long i = 0; i < n; i++) {
    cin >> city[i].first >> city[i].second;
  }
  for (long long i = 0; i < n; i++) cin >> c[i];
  for (long long i = 0; i < n; i++) cin >> k[i];
  helper(n, city, k, c);
  return 0;
}
