/* HackerRank Template v0.26 by Sergey Esipenko */ import java.io.*; import java.util.*; import static java.lang.Math.*; import static java.util.Arrays.fill; import static java.util.Arrays.sort; public class Solution implements Runnable { /* START OF SOLUTION */ static final Random RANDOM = new Random(7777L); static final int MAX_R_SIZE = 14; static final int MAX_L_SIZE = 2; void solve() throws IOException { // while (test(10)); final int n = nextInt(); final int[] perm = nextIntArray(n); for (int i = 0; i < perm.length; i++) perm[i]--; out.println(solve(perm)); } static String solve(final int[] perm) { final int n = perm.length; final RSQ lRsq = new RSQ(n); final NavigableSet<Element> bestLeft = new TreeSet<Solution.Element>(); for (int i = 0; i < n; i++) { lRsq.set(perm[i], 1); final int inv = lRsq.sum(perm[i] + 1, n - 1); final Element el = new Element(i, inv); if (inv > 0) bestLeft.add(el); while (bestLeft.size() > MAX_L_SIZE) bestLeft.pollLast(); } final RSQ rRsq = new RSQ(n); final NavigableSet<Element> bestRight = new TreeSet<Solution.Element>(); for (int i = n - 1; i >= 0; i--) { rRsq.set(perm[i], 1); final int inv = rRsq.sum(0, perm[i] - 1); final Element el = new Element(i, inv); if (inv > 0) bestRight.add(el); while (bestRight.size() > MAX_R_SIZE) bestRight.pollLast(); } long bestInversions = Long.MAX_VALUE; int bestL = -1; int bestR = -1; // System.err.println(bestLeft); // System.err.println(bestRight); for (final Element lel : bestLeft) { for (final Element rel : bestRight) { swap(perm, lel.pos, rel.pos); final long inversions = inversions(perm); swap(perm, lel.pos, rel.pos); final int l = min(lel.pos, rel.pos); final int r = max(lel.pos, rel.pos); if (bestInversions > inversions || bestInversions == inversions && (bestL > l || bestL == l && bestR > r)) { bestInversions = inversions; bestL = l; bestR = r; } } } final String answer = bestL == -1 ? "Cool Array" : ((bestL + 1) + " " + (bestR + 1)); return answer; } static String solveNiave(final int[] a) { final long initialInversions = inversions(a); long minInversions = initialInversions; int u = -1, v = -1; for (int i = 0; i < a.length; i++) { for (int j = i + 1; j < a.length; j++) { swap(a, i, j); final long newInversions = inversions(a); swap(a, i, j); if (minInversions > newInversions) { minInversions = newInversions; u = i; v = j; } } } if (u == -1) { return "Cool Array"; } else { return (u + 1) + " " + (v + 1); } } static boolean test(final int n) { final int[] perm = new int [n]; for (int i = 0; i < n; i++) perm[i] = i; shuffle(perm); final String answer = solve(perm); final String answerNaive = solveNiave(perm); if (!answer.equals(answerNaive)) { System.err.println(n); for (int i = 0; i < n; i++) { if (i > 0) System.err.print(' '); System.err.print(perm[i] + 1); } System.err.println(); System.err.println(answer); System.err.println(answerNaive); return false; } return true; } static long inversions(final int[] a) { final RSQ rsq = new RSQ(a.length); long inversions = 0; for (int i = 0; i < a.length; i++) { inversions += rsq.sum(a[i] + 1, a.length - 1); rsq.set(a[i], 1); } return inversions; } static class Element implements Comparable<Element> { final int pos; final int inv; Element(int pos, int inv) { this.pos = pos; this.inv = inv; } @Override public int compareTo(Element el) { if (inv != el.inv) return -Integer.compare(inv, el.inv); return Integer.compare(pos, el.pos); } @Override public String toString() { return "[p=" + pos + ", i=" + inv + "]"; } } static class RSQ { int n; int[] val; RSQ(int sz) { val = new int[2 * (n = sz)]; } void set(int i, int v) { val[i += n] = v; for (i >>= 1; i > 0; i >>= 1) val[i] = val[i << 1] + val[(i << 1) + 1]; } int sum(int l, int r) { l += n; r += n; int ret = 0; while (l <= r) { if ((l & 1) == 1) ret += val[l]; if ((r & 1) == 0) ret += val[r]; l = (l + 1) >> 1; r = (r - 1) >> 1; } return ret; } } /* END OF SOLUTION */ /************************************************************************** * Entry point *************************************************************************/ static final Solution INSTANCE = new Solution(); static final boolean WRITE_LOG = true; static final long STACK_SIZE = 1L << 24; // < 0 for default stack size static long initTime; static boolean localRun = false; @SuppressWarnings("unused") public static void main(String[] args) throws IOException { try { initTime = System.currentTimeMillis(); try { localRun = "true".equals(System.getProperty("LOCAL_RUN_7777")); if (localRun && new File("input.txt").exists()) System.setIn(new FileInputStream("input.txt")); } catch (SecurityException e) { // Can't get property. It seems that solution is running in a secure // environment } if (STACK_SIZE < 0L) { INSTANCE.run(); } else { new Thread(null, INSTANCE, "Solver", 1L << 24).start(); } } catch (Throwable e) { e.printStackTrace(); System.exit(999); } } @Override public void run() { try { in = new BufferedReader(new InputStreamReader(System.in)); out = new PrintWriter(System.out); solve(); out.close(); in.close(); writeLog("Total time: " + (System.currentTimeMillis() - initTime) + " ms"); writeLog("Memory status: " + memoryStatus()); } catch (Throwable e) { e.printStackTrace(); System.exit(999); } } /************************************************************************** * Input *************************************************************************/ BufferedReader in; PrintWriter out; StringTokenizer st = new StringTokenizer(""); String nextToken() throws IOException { while (!st.hasMoreTokens()) st = new StringTokenizer(in.readLine()); return st.nextToken(); } int nextInt() throws IOException { return Integer.parseInt(nextToken()); } long nextLong() throws IOException { return Long.parseLong(nextToken()); } double nextDouble() throws IOException { return Double.parseDouble(nextToken()); } int[] nextIntArray(int size) throws IOException { int[] ret = new int [size]; for (int i = 0; i < size; i++) ret[i] = nextInt(); return ret; } long[] nextLongArray(int size) throws IOException { long[] ret = new long [size]; for (int i = 0; i < size; i++) ret[i] = nextLong(); return ret; } double[] nextDoubleArray(int size) throws IOException { double[] ret = new double [size]; for (int i = 0; i < size; i++) ret[i] = nextDouble(); return ret; } String nextLine() throws IOException { st = new StringTokenizer(""); return in.readLine(); } boolean isEof() throws IOException { while (!st.hasMoreTokens()) { String s = in.readLine(); if (s == null) return true; st = new StringTokenizer(s); } return false; } /************************************************************************** * Output *************************************************************************/ void printIf(final boolean condition, final String msgIfTrue, final String msgIfFalse) { out.println(condition ? msgIfTrue : msgIfFalse); } void printRepeat(String s, int count) { for (int i = 0; i < count; i++) out.print(s); } void printArray(int[] array) { if (array == null || array.length == 0) return; for (int i = 0; i < array.length; i++) { if (i > 0) out.print(' '); out.print(array[i]); } out.println(); } void printArray(long[] array) { if (array == null || array.length == 0) return; for (int i = 0; i < array.length; i++) { if (i > 0) out.print(' '); out.print(array[i]); } out.println(); } void printArray(double[] array) { if (array == null || array.length == 0) return; for (int i = 0; i < array.length; i++) { if (i > 0) out.print(' '); out.print(array[i]); } out.println(); } void printArray(double[] array, String spec) { if (array == null || array.length == 0) return; for (int i = 0; i < array.length; i++) { if (i > 0) out.print(' '); out.printf(Locale.US, spec, array[i]); } out.println(); } void printArray(Object[] array) { if (array == null || array.length == 0) return; boolean blank = false; for (Object x : array) { if (blank) out.print(' '); else blank = true; out.print(x); } out.println(); } @SuppressWarnings("rawtypes") void printCollection(Collection collection) { if (collection == null || collection.isEmpty()) return; boolean blank = false; for (Object x : collection) { if (blank) out.print(' '); else blank = true; out.print(x); } out.println(); } /************************************************************************** * Utility *************************************************************************/ static String memoryStatus() { return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() >> 20) + "/" + (Runtime.getRuntime().totalMemory() >> 20) + " MB"; } static void checkMemory() { System.err.println(memoryStatus()); } static long getRunningTime() { return System.currentTimeMillis() - initTime; } static void chk(boolean f) { if (!f) throw new RuntimeException("Assert failed"); } static void chk(boolean f, String format, Object ... args) { if (!f) throw new RuntimeException(String.format(format, args)); } static void writeLog(String format, Object... args) { if (localRun && WRITE_LOG) System.err.println(String.format(Locale.US, format, args)); } static void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } static void swap(long[] a, int i, int j) { long tmp = a[i]; a[i] = a[j]; a[j] = tmp; } static void swap(double[] a, int i, int j) { double tmp = a[i]; a[i] = a[j]; a[j] = tmp; } static void swap(Object[] a, int i, int j) { Object tmp = a[i]; a[i] = a[j]; a[j] = tmp; } static void shuffle(int[] a, int from, int to) { for (int i = from; i <= to; i++) swap(a, i, from + RANDOM.nextInt(i - from + 1)); } static void shuffle(long[] a, int from, int to) { for (int i = from; i <= to; i++) swap(a, i, from + RANDOM.nextInt(i - from + 1)); } static void shuffle(double[] a, int from, int to) { for (int i = from; i <= to; i++) swap(a, i, from + RANDOM.nextInt(i - from + 1)); } static void shuffle(Object[] a, int from, int to) { for (int i = from; i <= to; i++) swap(a, i, from + RANDOM.nextInt(i - from + 1)); } static void shuffle(int[] a) { if (a == null) return; shuffle(a, 0, a.length - 1); } static void shuffle(long[] a) { if (a == null) return; shuffle(a, 0, a.length - 1); } static void shuffle(double[] a) { if (a == null) return; shuffle(a, 0, a.length - 1); } static void shuffle(Object[] a) { if (a == null) return; shuffle(a, 0, a.length - 1); } static long[] getPartialSums(int[] a) { final long[] sums = new long [a.length + 1]; for (int i = 0; i < a.length; i++) sums[i + 1] = sums[i] + a[i]; return sums; } static long[] getPartialSums(long[] a) { final long[] sums = new long [a.length + 1]; for (int i = 0; i < a.length; i++) sums[i + 1] = sums[i] + a[i]; return sums; } static int[] getOrderedSet(int[] a) { final int[] set = Arrays.copyOf(a, a.length); if (a.length == 0) return set; shuffle(set); sort(set); int k = 1; int prev = set[0]; for (int i = 1; i < a.length; i++) { if (prev != set[i]) { set[k++] = prev = set[i]; } } return Arrays.copyOf(set, k); } static long[] getOrderedSet(long[] a) { final long[] set = Arrays.copyOf(a, a.length); if (a.length == 0) return set; shuffle(set); sort(set); int k = 1; long prev = set[0]; for (int i = 1; i < a.length; i++) { if (prev != set[i]) { set[k++] = prev = set[i]; } } return Arrays.copyOf(set, k); } static int gcd(int x, int y) { x = abs(x); y = abs(y); while (x > 0 && y > 0) { if (x > y) { x %= y; } else { y %= x; } } return x + y; } static long gcd(long x, long y) { x = abs(x); y = abs(y); while (x > 0 && y > 0) { if (x > y) { x %= y; } else { y %= x; } } return x + y; } }