Problem:
Score : 400 points

Problem Statement

Given a string t, we will call it unbalanced if and only if the length of t is at least 2, and more than half of the letters in t are the same. For example, both voodoo and melee are unbalanced, while neither noon nor a is.

You are given a string s consisting of lowercase letters. Determine if there exists a (contiguous) substring of s that is unbalanced. If the answer is positive, show a position where such a substring occurs in s.

Constraints

2 ≦ |s| ≦ 10^5

s consists of lowercase letters.

Partial Score

200 points will be awarded for passing the test set satisfying 2 ≦ N ≦ 100.

Input

The input is given from Standard Input in the following format:

s

Output

If there exists no unbalanced substring of s, print -1 -1.

If there exists an unbalanced substring of s, let one such substring be s_a s_{a+1} ... s_{b} (1 ≦ a < b ≦ |s|), and print a b. If there exists more than one such substring, any of them will be accepted.

Sample Input 1

needed

Sample Output 1

2 5

The string s_2 s_3 s_4 s_5 = eede is unbalanced. There are also other unbalanced substrings. For example, the output 2 6 will also be accepted.

Sample Input 2

atcoder

Sample Output 2

-1 -1

The string atcoder contains no unbalanced substring.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        Solve();
        Console.Out.Flush();
    }
    static void Solve()
    {
        var S = sc.ReadStr();
        var N = S.Length;
        var sum = new int[N + 1, 26];
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < 26; j++)
            {
                sum[i + 1, j] = sum[i, j];
            }
            sum[i + 1, S[i] - 'a']++;
        }
        var t = new Treap<Tuple<long, int>>[26];
        for (int i = 0; i < 26; i++)
        {
            t[i] = new Treap<Tuple<long, int>>();
        }
        var A = new long[N + 1, 26];
        for (int i = 0; i < N + 1; i++)
        {
            for (int j = 0; j < 26; j++)
            {
                A[i, j] = 2 * sum[i, j] - i;
                t[j].Insert(Tuple.Create(A[i, j], i));
            }
        }

        for (int i = 0; i < N + 1; i++)
        {
            for (int j = 0; j < 26; j++)
            {
                if (i - 2 >= 0)
                {
                    var lb = t[j].LowerBouond(Tuple.Create(A[i, j], i));
                    var count = N - i - lb;
                    if (count >= 1 && A[i, j] >= 0)
                    {
                        var si = i - 2 + 1;
                        var sj = t[j][lb].Item2 + 1;
                        Console.WriteLine($"{si} {sj}");
                        return;
                    }
                }
                t[j].Erase(Tuple.Create(A[i, j], i));
            }
        }
        Console.WriteLine($"{-1} {-1}");
    }

    class Treap<T> : IEnumerable<T>
    {
        public int Length
        {
            get { return this.Root == null ? 0 : this.NodeCount(this.Root); }
        }
        public T this[int i]
        {
            get
            {
                if (this.Root.Count < i - 1) throw new IndexOutOfRangeException();
                return this.Root.Get(i);
            }
        }
        public Node Root;
        private IComparer<T> Cmp = Comparer<T>.Default;
        public Treap(IComparer<T> cmp = null)
        {
            if (cmp != null) this.Cmp = cmp;
        }
        public Node Merge(Node l, Node r)
        {
            if (l == null || r == null) return l == null ? r : l;

            if (l.Priority > r.Priority)
            {
                l.R = this.Merge(l.R, r);
                return this.Update(l);
            }
            else
            {
                r.L = this.Merge(l, r.L);
                return this.Update(r);
            }
        }
        public Tuple<Node, Node> Split(int k) { return this.Split(this.Root, k); }
        public Tuple<Node, Node> Split(Node t, int k)
        {
            if (t == null) return Tuple.Create<Node, Node>(null, null);
            if (k <= this.NodeCount(t.L))
            {
                var s = this.Split(t.L, k);
                t.L = s.Item2;
                return Tuple.Create(s.Item1, this.Update(t));
            }
            else
            {
                var s = this.Split(t.R, k - this.NodeCount(t.L) - 1);
                t.R = s.Item1;
                return Tuple.Create(this.Update(t), s.Item2);
            }
        }
        public Node Update(Node node)
        {
            node.Count = this.NodeCount(node.L) + this.NodeCount(node.R) + 1;
            return node;
        }
        public int NodeCount(Node node)
        {
            return node == null ? 0 : node.Count;
        }
        public int LowerBouond(T value) { return this.LowerBouond(this.Root, value); }
        public int LowerBouond(Node node, T value)
        {
            if (node == null) return 0;
            if (this.Cmp.Compare(value, node.Value) <= 0)
                return this.LowerBouond(node.L, value);
            else
                return this.NodeCount(node.L) + 1 + this.LowerBouond(node.R, value);
        }
        public int UpperBound(T value) { return this.UpperBound(this.Root, value); }
        public int UpperBound(Node node, T value)
        {
            if (node == null) return 0;
            if (this.Cmp.Compare(value, node.Value) >= 0)
                return this.NodeCount(node.L) + 1 + this.UpperBound(node.R, value);
            else
                return this.UpperBound(node.L, value);
        }
        public int ValueCount(T value)
        {
            return this.UpperBound(value) - this.LowerBouond(value);
        }
        public void Insert(T value)
        {
            var sub = this.Split(this.Root, this.LowerBouond(value));
            var newNode = new Node(value);
            var merged = this.Merge(sub.Item1, newNode);
            this.Root = this.Merge(merged, sub.Item2);
        }
        public void Erase(T value)
        {
            if (this.ValueCount(value) == 0) return;
            var sub = this.Split(this.Root, this.LowerBouond(value));
            this.Root = this.Merge(sub.Item1, this.Split(sub.Item2, 1).Item2);
        }
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < this.Length; i++)
            {
                yield return this.Root.Get(i);
            }
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            for (int i = 0; i < this.Length; i++)
            {
                yield return this.Root.Get(i);
            }
        }
        public class Node
        {
            private static Random Rand = new Random();
            public T Value { get; set; }
            public Node L { get; set; } = null;
            public Node R { get; set; } = null;
            public int Count { get; set; }
            public double Priority { get; set; }
            public Node(T value, double priority)
            {
                this.Value = value;
                this.Priority = priority;
                this.Count = 1;
            }
            public Node(T value) : this(value, Rand.NextDouble()) { }
            public T Get(int i)
            {
                var lcount = 0;
                if (this.L != null) lcount = this.L.Count;
                if (lcount == i) return this.Value;
                else if (lcount < i) return this.R.Get(i - lcount - 1);
                else return this.L.Get(i);
            }
        }
    }
    static Scanner sc = new Scanner();
}
class Scanner
{
    string[] S = new string[0];
    int Index = 0;
    char[] Separators = new char[] { ' ' };

    public string Next()
    {
        if (this.Index < this.S.Length) return this.S[this.Index++];
        var line = "";
        while (line == "") line = Console.ReadLine();
        this.S = line.Split(this.Separators, StringSplitOptions.RemoveEmptyEntries);
        if (this.S.Length == 0) return this.Next();
        this.Index = 0;
        return this.S[this.Index++];
    }
    public string ReadStr()
    {
        return this.Next();
    }
    public char ReadChar()
    {
        return this.Next()[0];
    }
    public int ReadInt()
    {
        return int.Parse(this.Next());
    }
    public uint ReadUInt()
    {
        return uint.Parse(this.Next());
    }
    public long ReadLong()
    {
        return long.Parse(this.Next());
    }
    public double ReadDouble()
    {
        return double.Parse(this.Next());
    }
    public Tuple<int, int> ReadTup(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<long, long> ReadTupLong(int add = 0)
    {
        return Tuple.Create(this.ReadLong() + add, this.ReadLong() + add);
    }
    public Tuple<int, int, int> ReadTup3(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<int, int, int, int> ReadTup4(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public int[] ReadIntArray(int n)
    {
        var array = new int[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadInt();
        }
        return array;
    }
    public long[] ReadLongArray(int n)
    {
        var array = new long[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadLong();
        }
        return array;
    }
    public double[] ReadDoubleArray(int n)
    {
        var array = new double[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadDouble();
        }
        return array;
    }
    public char[] ReadCharArray(int n)
    {
        var array = new char[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadChar();
        }
        return array;
    }
    public string[] ReadStrArray(int n)
    {
        var array = new string[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadStr();
        }
        return array;
    }
    public Tuple<long, long>[] ReadTupLongArray(int n, int add = 0)
    {
        var array = new Tuple<long, long>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTupLong(add);
        }
        return array;
    }
    public Tuple<int, int>[] ReadTupArray(int n, int add = 0)
    {
        var array = new Tuple<int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup(add);
        }
        return array;
    }
    public Tuple<int, int, int>[] ReadTup3Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup3(add);
        }
        return array;
    }
    public Tuple<int, int, int, int>[] ReadTup4Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup4(add);
        }
        return array;
    }
}