#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t;
  cin >> t;
  vector<int> cnt(t);
  int b = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++cnt[a];
    b = max(a, b);
  }
  if (cnt[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  int x = 0;
  while (cnt[x + 1] == (x + 1) * 4) {
    ++x;
  }
  for (int n = 1; n <= t; ++n) {
    if (t % n != 0) {
      continue;
    }
    int m = t / n;
    // b == n - 1 - x + m - 1 - y
    int y = n + m - b - x - 2;
    vector<int> v(t);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        ++v[abs(i - x) + abs(j - y)];
      }
    }
    if (v == cnt) {
      cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
      return 0;
    }
  }
  cout << -1 << "\n";
  return 0;
}

/* In-contest, Wrong answer on pretest 4.
int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (b[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  if (t == 1) {
    cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}
*/


#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t;
  cin >> t;
  vector<int> cnt(t);
  int b = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++cnt[a];
    b = max(a, b);
  }
  if (cnt[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  int x = b + 1;
  for (int i = 1; i <= b; ++i) {
    if (cnt[i] != 4 * i) {
      x = i - 1;
      break;
    }
  }
  for (int n = 1; n * n <= t; ++n) {
    if (t % n != 0) {
      continue;
    }
    int m = t / n;
    // b == n - 1 - x + m - 1 - y
    int y = n + m - b - x - 2;
    vector<int> v(t);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        ++v[abs(i - x) + abs(j - y)];
      }
    }
    if (v == cnt) {
      cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
      return 0;
    }
  }
  cout << -1 << "\n";
  return 0;
}

/* In-contest, Wrong answer on pretest 4.
int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (b[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  if (t == 1) {
    cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}
*/


#include <bits/stdc++.h>

using namespace std;

int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
#
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;

int t,mx;
array<int,1000000> co = array<int,1000000>();
int nex = 1;

array<int,1000000> gen(int R, int C, int x, int y) {
    array<int,1000000> z = array<int,1000000>();
    if (x < 1 || x > R || y < 1 || y > C) return z;
    FOR(i,1,R+1) FOR(j,1,C+1) z[abs(i-x)+abs(j-y)] ++;
    return z;
}

void test(int R, int C) {
    int x = nex, y = mx+1-(R-nex);
    if (co == gen(R,C,x,y)) {
        cout << R << " " << C << "\n";
        cout << x << " " << y << "\n";
        exit(0);
    }
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> t;
    F0R(i,t) {
        int a; cin >> a;
        co[a] ++;
        mx = max(mx,a);
    }
    if (co[0] != 1) {
        cout << -1;
        exit(0);
    }
    while (co[nex] == 4*nex) nex ++;

    for (int i = 1; i*i <= t; ++i) if (t % i == 0) {
        test(i,t/i);
        test(t/i,i);
    }
    cout << -1;
}

/*
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t;
  cin >> t;
  vector<int> cnt(t);
  int b = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++cnt[a];
    b = max(a, b);
  }
  if (cnt[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  int x = 0;
  while (cnt[x + 1] == (x + 1) * 4) {
    ++x;
  }
  for (int n = 1; n * n <= t; ++n) {
    if (t % n != 0) {
      continue;
    }
    int m = t / n;
    // b == n - 1 - x + m - 1 - y
    int y = n + m - b - x - 2;
    vector<int> v(t);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        ++v[abs(i - x) + abs(j - y)];
      }
    }
    if (v == cnt) {
      cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
      return 0;
    }
  }
  cout << -1 << "\n";
  return 0;
}
*/

/* In-contest, Wrong answer on pretest 4.
int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (b[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  if (t == 1) {
    cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}
*/


#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t;
  cin >> t;
  vector<int> cnt(t);
  int b = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++cnt[a];
    b = max(a, b);
  }
  if (cnt[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  int x = b;
  for (int i = 1; i <= b; ++i) {
    if (cnt[i] != 4 * i) {
      x = i - 1;
      break;
    }
  }
  for (int n = 1; n * n <= t; ++n) {
    if (t % n != 0) {
      continue;
    }
    int m = t / n;
    // b == n - 1 - x + m - 1 - y
    int y = n + m - b - x - 2;
    vector<int> v(t);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        ++v[abs(i - x) + abs(j - y)];
      }
    }
    if (v == cnt) {
      cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
      return 0;
    }
  }
  cout << -1 << "\n";
  return 0;
}

/* In-contest, Wrong answer on pretest 4.
int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (b[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  if (t == 1) {
    cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}
*/


#include <bits/stdc++.h>

using namespace std;

int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (t == 1) {
    if (b[0] == 1) {
      cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    } else {
      cout << -1 << "\n";
    }
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t;
  cin >> t;
  vector<int> cnt(t);
  int b = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++cnt[a];
    b = max(a, b);
  }
  if (cnt[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  int x = 0;
  while (cnt[x + 1] == (x + 1) * 4) {
    ++x;
  }
  for (int n = 1; n <= t; ++n) {
    if (t % n != 0) {
      continue;
    }
    int m = t / n;
    // b == n - 1 - x + m - 1 - y
    int y = n + m - b - x - 2;
    if (x >= n || y < 0 || y >= m) {
      continue;
    }
    vector<int> v(t);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        ++v[abs(i - x) + abs(j - y)];
      }
    }
    if (v == cnt) {
      cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
      return 0;
    }
  }
  cout << -1 << "\n";
  return 0;
}

/* In-contest, Wrong answer on pretest 4.
int t;
vector<int> b;
int n, m, x, y;

bool Verify() {
  vector<int> bb(t);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int md = abs(i - x) + abs(j - y);
      ++bb[md];
    }
  }
  for (int i = 0; i < (int)b.size(); ++i) {
    if (b[i] != bb[i]) {
      return false;
    }
  }
  return true;
}

bool Solve1() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = (d[0] + d[1] + 1) * 2;
    } else if (d.size() == 3) {
      exp = d[0] + d[1] + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() == 4) {
      break;
    }
  }
  if (d.size() < 4) {
    return false;
  }
  n = d[0] + d[1] + 1;
  m = d[2] + d[3] + 1;
  x = d[0];
  y = d[2];
  return Verify();
}

bool Solve2() {
  vector<int> d;
  for (int i = 1; i < (int)b.size(); ++i) {
    int exp;
    if (d.size() == 0) {
      exp = i * 4;
    } else if (d.size() == 1) {
      exp = i * 4 - (i - d[0]) * 2 + 1;
    } else if (d.size() == 2) {
      exp = d[0] + d[1] + i + 1;
    }
    if (b[i] == exp) {
      continue;
    }
    if (b[i] > exp) {
      return false;
    }
    while (b[i] < exp) {
      d.push_back(i - 1);
      --exp;
    }
    if (d.size() > 4) {
      return false;
    }
    if (d.size() >= 3) {
      x = d[0];
      y = d[1];
      n = d[0] + d[2] + 1;
      if (t % n == 0) {
        m = t / n;
        if (Verify()) {
          return true;
        }
      }
      m = d[1] + d[2] + 1;
      if (t % m == 0) {
        n = t / m;
        if (Verify()) {
          return true;
        }
      }
      return false;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> t;
  b.resize(t);
  int a_max = 0;
  for (int i = 0; i < t; ++i) {
    int a;
    cin >> a;
    ++b[a];
    a_max = max(a_max, a);
  }
  b.resize(a_max + 1);
  if (b[0] != 1) {
    cout << -1 << "\n";
    return 0;
  }
  if (t == 1) {
    cout << 1 << " " << 1 << "\n" << 1 << " " << 1 << "\n";
    return 0;
  }
  if (Solve1()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else if (Solve2()) {
    cout << n << " " << m << "\n" << x + 1 << " " << y + 1 << "\n";
  } else {
    cout << -1 << "\n";
  }
  return 0;
}
*/


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
*/

int t, a[1000015], cnt[1000015], cnt2[1000015];
bool check(int n, int m, int x, int y) {
    clr(cnt2, 0);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ++cnt2[abs(i - x) + abs(j - y)];
        }
    }
    for (int i = 0; i < t; ++i) {
        if (cnt[i] != cnt2[i]) return false;
    }
    return true;
}
int main() {
    scanf("%d", &t);
    int ma = 0;
    for (int i = 1; i <= t; ++i) scanf("%d", &a[i]), ++cnt[a[i]], ma = max(ma, a[i]);
    int d = 0;
    for (int i = 1; i < t; ++i) {
        if (cnt[i] != 4 * i) {
            d = i;
            break;
        }
    }
    if (1 == t) {
        if (cnt[0]) {
            printf("1 1\n1 1");
        } else {
            puts("-1");
        }
        return 0;
    }
    for (int n = 1; n <= t; ++n) {
        if (t % n) continue;
        int m = t / n;
        int i = n + m - d - ma;
        if (i < d || i > n - d + 1 || d > n - d + 1) continue;
        if (check(n, m, i, d)) {
            return !printf("%d %d\n%d %d", n, m, i, d);
        }
    }
    puts("-1");
    return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
*/

int t, a[1000015], cnt[1000015], cnt2[1000015];
bool check(int n, int m, int x, int y) {
    clr(cnt2, 0);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ++cnt2[abs(i - x) + abs(j - y)];
        }
    }
    for (int i = 0; i < t; ++i) {
        if (cnt[i] != cnt2[i]) return false;
    }
    return true;
}
int main() {
    scanf("%d", &t);
    int ma = 0;
    for (int i = 1; i <= t; ++i) scanf("%d", &a[i]), ++cnt[a[i]], ma = max(ma, a[i]);
    int d = 0;
    for (int i = 1; i < t; ++i) {
        if (cnt[i] != 4 * i) {
            d = i;
            break;
        }
    }
    if (1 != cnt[0]) {
        return !printf("-1");
    }
    if (1 == t) {
        if (cnt[0]) {
            printf("1 1\n1 1");
        } else {
            puts("-1");
        }
        return 0;
    }
    for (int n = 1; n <= t; ++n) {
        if (t % n) continue;
        int m = t / n;
        int i = n + m - d - ma;
        if (i < d || d > n - d + 1) continue;
        if (check(n, m, i, d)) {
            return !printf("%d %d\n%d %d", n, m, i, d);
        }
    }
    puts("-1");
    return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
*/

int t, a[1000015], cnt[1000015], cnt2[1000015];
bool check(int n, int m, int x, int y) {
    clr(cnt2, 0);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ++cnt2[abs(i - x) + abs(j - y)];
        }
    }
    for (int i = 0; i < t; ++i) {
        if (cnt[i] != cnt2[i]) return false;
    }
    return true;
}
int main() {
    scanf("%d", &t);
    int ma = 0;
    for (int i = 1; i <= t; ++i) scanf("%d", &a[i]), ++cnt[a[i]], ma = max(ma, a[i]);
    int d = 0;
    for (int i = 1; i < t; ++i) {
        if (cnt[i] != 4 * i) {
            d = i;
            break;
        }
    }
    for (int n = 1; n <= t; ++n) {
        if (t % n) continue;
        int m = t / n;
        int i = n + m - d - ma;
        if (i < d || d > n - d + 1) continue;
        if (check(n, m, i, d)) {
            return !printf("%d %d\n%d %d", n, m, i, d);
        }
    }
    puts("-1");
    return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
*/

int t, a[1000015], cnt[1000015], cnt2[1000015];
bool check(int n, int m, int x, int y) {
    clr(cnt2, 0);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ++cnt2[abs(i - x) + abs(j - y)];
        }
    }
    for (int i = 0; i < t; ++i) {
        if (cnt[i] != cnt2[i]) return false;
    }
    return true;
}
int main() {
    scanf("%d", &t);
    int ma = 0;
    for (int i = 1; i <= t; ++i) scanf("%d", &a[i]), ++cnt[a[i]], ma = max(ma, a[i]);
    int d = 0;
    for (int i = 1; i < t; ++i) {
        if (cnt[i] != 4 * i) {
            d = i;
            break;
        }
    }
    for (int n = 1; n <= t; ++n) {
        if (t % n) continue;
        int m = t / n;
        int i = n + m - d - ma;
        if (i < d || i > n - d + 1) continue;
        if (check(n, m, i, d)) {
            return !printf("%d %d\n%d %d", n, m, i, d);
        }
    }
    puts("-1");
    return 0;
}


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
*/

int t, a[1000015], cnt[1000015], cnt2[1000015];
bool check(int n, int m, int x, int y) {
    clr(cnt2, 0);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ++cnt2[abs(i - x) + abs(j - y)];
        }
    }
    for (int i = 0; i < t; ++i) {
        if (cnt[i] != cnt2[i]) return false;
    }
    return true;
}
int main() {
    scanf("%d", &t);
    int ma = 0;
    for (int i = 1; i <= t; ++i) scanf("%d", &a[i]), ++cnt[a[i]], ma = max(ma, a[i]);
    int d = 0;
    for (int i = 1; i < t; ++i) {
        if (cnt[i] != 4 * i) {
            d = i;
            break;
        }
    }
    if (1 == t) {
        if (cnt[0]) {
            printf("1 1\n1 1");
        } else {
            puts("-1");
        }
        return 0;
    }
    for (int n = 1; n <= t; ++n) {
        if (t % n) continue;
        int m = t / n;
        int i = n + m - d - ma;
        if (i < d || d > n - d + 1) continue;
        if (check(n, m, i, d)) {
            return !printf("%d %d\n%d %d", n, m, i, d);
        }
    }
    puts("-1");
    return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    for(int i=0;i<2;i++) {
      if(valid(mx-ds[i], ds[i], ds[1], ds[1-i])) {
          found = true;
          break;
      }
    }
  }

  if(!found) {
    int r = ds[1] + 1;
    while(cnt[r+1] == cnt[r]) r++;
    debug(r);
    for(int i=0;i<2;i++) {
      if(valid(mx-ds[i], ds[i], r, ds[1-i])) {
          found = true;
          break;
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  xtest(10,10,1,2);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 1) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    return 0;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  xtest(10,10,1,2);
  xtest(10,10,2,3);
  xtest(10,10,3,4);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 1) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] >= 2) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  while(cnt[nd] - cnt[nd-1] >= 0) {
      nd++;
  }
  ds[2] = nd - 1;

  debug(ds[0], ds[1], ds[2]);

  bool found = false;

  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      debug(i1,i2,ds[i1],ds[i2],w);
      if((t%w)==0) {
        int h = t/w;
        debug(i1,i2,ds[i1],ds[i2],w,h);
        int i3 = 6-i1-i2;
        if(valid(ds[i1], ds[i3], ds[i2], h - ds[i3])) {
          return 0;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  xtest(10,10,1,2);
  xtest(10,10,2,3);
  xtest(10,10,3,4);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 3) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(mx && z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  if(cnt[0]>1) {
    cout << -1 << endl;
    return 0;
  }

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] >= 2) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  while(nd<=mx && cnt[nd] - cnt[nd-1] >= 0) {
      nd++;
  }
  ds[2] = nd - 1;

  debug(ds[0], ds[1], ds[2]);

  // if(t==1000000) {
  //   printf("%d %d %d\n", ds[0], ds[1], ds[2]);
  // }

  bool found = false;

  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      debug(i1,i2,ds[i1],ds[i2],w);
      if((t%w)==0) {
        int h = t/w;
        int i3 = 3-i1-i2;
        debug(i1,i2,i3,ds[i1],ds[i2],w,h);
        if(valid(ds[i1], ds[i3], ds[i2], h - 1 - ds[i3])) {
          return 0;
        }
      }
    }
  }

  ds[2]--;
  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      debug(i1,i2,ds[i1],ds[i2],w);
      if((t%w)==0) {
        int h = t/w;
        int i3 = 3-i1-i2;
        debug(i1,i2,i3,ds[i1],ds[i2],w,h);
        if(valid(ds[i1], ds[i3], ds[i2], h - 1 - ds[i3])) {
          return 0;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] >= 2) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  while(cnt[nd] - cnt[nd-1] >= 0) {
      nd++;
  }
  ds[2] = nd - 1;

  bool found = false;

  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      if(t%w==0) {
        int h = t/w;
        int i3 = 6-i1-i2;
        if(valid(ds[i1], ds[i3], ds[i2], h - ds[i3])) {
          return 0;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 1) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int r = ds[1] + 1;
    while(cnt[r+1] == cnt[r]) r++;
    debug(r);
    for(int i=0;i<2;i++) {
      if(valid(mx-ds[i], ds[i], r, ds[1-i])) {
          found = true;
          break;
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1, left--;
    last += left;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int last = 0, left = 4;
  int nd = 1;
  for(int i=0;i<2;) {
    while(cnt[nd] == last + left) {
      nd++;
      last += left;
    }
    int missing = last + left - cnt[nd];
    debug(i, missing, nd);
    for(int j=0;j<missing && i < 2;j++)
      ds[i++] = nd-1, left--;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(mx && z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] >= 2) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  while(nd<=mx && cnt[nd] - cnt[nd-1] >= 0) {
      nd++;
  }
  ds[2] = nd - 1;

  debug(ds[0], ds[1], ds[2]);

  // if(t==1000000) {
  //   printf("%d %d %d\n", ds[0], ds[1], ds[2]);
  // }

  bool found = false;

  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      debug(i1,i2,ds[i1],ds[i2],w);
      if((t%w)==0) {
        int h = t/w;
        int i3 = 3-i1-i2;
        debug(i1,i2,i3,ds[i1],ds[i2],w,h);
        if(valid(ds[i1], ds[i3], ds[i2], h - 1 - ds[i3])) {
          return 0;
        }
      }
    }
  }

  ds[2]--;
  for(int i1=0;i1<3;i1++) {
    for(int i2=0;i2<3;i2++) {
      if(i1==i2) continue;
      int w = (ds[i1] + ds[i2] + 1);
      debug(i1,i2,ds[i1],ds[i2],w);
      if((t%w)==0) {
        int h = t/w;
        int i3 = 3-i1-i2;
        debug(i1,i2,i3,ds[i1],ds[i2],w,h);
        if(valid(ds[i1], ds[i3], ds[i2], h - 1 - ds[i3])) {
          return 0;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  xtest(10,10,1,2);
  xtest(10,10,2,3);
  xtest(10,10,3,4);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] >= 1) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  xtest(10,10,1,2);
  xtest(10,10,2,3);
  xtest(10,10,3,4);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == 4) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  if(missing<=0) exit(-1);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 3) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  if(t==1000000) printf("%d %d %d\n", ds[0], ds[1], missing);

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}


//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

#define prec setprecision

typedef long long ll;
typedef unsigned long long llu;
template<typename T> T gcd(T m, T n) {while(n) {T t=m%n; m=n;n=t;};return m;}
template<typename T> T exgcd(T a, T b, T& sa, T& ta) {T q, r, sb=0, tb=1, sc, tc; sa=1,ta=0; if(b) do q = a/b, r = a-q*b, a = b, b = r, sc = sa-q*sb, sa = sb, sb = sc, tc = ta-q*tb, ta = tb, tb = tc; while(b); return a; }
template<typename T> T mul_inv(T a, T b) { T t1 = a, t2 = b, t3; T v1 = 1, v2 = 0, v3; T x; while (t2 != 1) x = t1/t2, t3 = t1 - x*t2, v3 = v1 - x*v2, t1 = t2, t2 = t3, v1 = v2, v2 = v3; return (v2 + b) % b; }
template<typename T> T powmod(T a, T b, T MOD) {if (b < 0) return 0; T rv = 1; while (b) (b % 2) && (rv = (rv*a) % MOD), a = a*a%MOD, b /= 2; return rv;}
template<ll n> struct BitSize{enum{Size=BitSize<n/2>::Size+1};};
template<> struct BitSize<0>{enum{Size=1};};
template<> struct BitSize<1>{enum{Size=1};};
#define BITSIZE(n) (BitSize<n>::Size)
#define BITMAX(n) (BitSize<n>::Size - 1)

#ifndef ONLINE_JUDGE
#define DEBUG 1
#else
#define DEBUG 0
#endif

template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
	while(*sdbg != ',')cerr<<*sdbg++; cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef DEBUG
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif

const int maxt = 1e6 + 7;
int t;
int a[maxt];
int b[maxt];
int cnt[maxt];
int mx = 0;

bool valid(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  if(m*n != t) return false;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      if(z>mx) return false;
      b[z]++;
    }
  }
  for(int i=1;i<=mx;i++) if(cnt[i]!=b[i]) return false;
  cout << m << " " << n << endl << x << " " << y << endl;
  return true;
}

void xtest(int dl, int dt, int dr, int db) {
  int m = dl + dr + 1;
  int n = dt + db + 1;
  int x = dr + 1, y = db + 1;
  debug(m,n,x,y);
  memset(b, 0, sizeof(b));
  for(int j=1;j<=n;j++) {
    for(int i=1;i<=m;i++) {
      int z = abs(i-x)+abs(j-y);
      b[z]++;
    }
  }
  debug(b[1], b[2], b[3], b[4], b[5]);
}

int main(int argc, char *argv[]) {
  std::cin.sync_with_stdio(false);std::cin.tie(nullptr);
  debug(10,10,1,2);
  cin >> t;
  memset(cnt, 0, sizeof(cnt));
  for(int i=1;i<=t;i++) cin >> a[i], cnt[a[i]]++, mx = max(mx, a[i]);

  int ds[] = {0,0,0,0};
  int left = 4;
  int nd = 1;
  cnt[0] = 0;
  while(cnt[nd] - cnt[nd-1] == left) {
    nd++;
  }
  int missing = left - (cnt[nd] - cnt[nd-1]);
  ds[0] = nd - 1;
  if(missing == 1) {
    while(cnt[nd] - cnt[nd-1] == 1) {
      nd++;
    }
    ds[1] = nd - 1;
  } else {
    ds[1] = nd - 1;
  }

  debug(ds[0], ds[1]);

  bool found = false;

  for(int i=0;i<=mx;i++) {
    if(min(i, mx-i) >= ds[1]) {
      if(valid(i, mx-i, ds[0], ds[1])) {
        found = true;
        break;
      }
    }
  }

  if(!found) {
    int h = ds[0] + ds[1] + 1;
    if(t%h==0) {
      int w = t / h - 1;
      for(int i=0, ie = min(w,mx);i<=ie;i++) {
        if(valid(i, ds[1], w-i, ds[0])) {
          found = true;
          break;
        }
      }
    }
  }

  if(!found) cout << -1 << endl; //@sub

  return 0;
}