#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

    // 所谓两两相同,人话就是滑动窗口内不能出现相同的元素
    // 难点:左指针如何快速移动到当前窗口内与右指针所指元素相同的元素下标处?
    // 解决方法:使用哈希表统计窗口内所有元素的出现次数,如果发现右指针元素次数大于1。
    // 那么就让左指针不断向右进一位,直到右指针元素的出现次数重新变成1(实在妙不可言)
    // 注意这一过程实时把左指针处的哈希值减1,更新一下
int main() {
    int n;
    cin >> n;
    
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    unordered_map<int, int> map; // 创建哈希表存储已出现的元素的出现次数
    int l = 0, max_len = 0, curr_len = 0;
    vector<pair<int, int>> result; // 存储最大长度的区间lr值

    for (int r = 0; r < n; r++) {
        map[a[r]] ++; 
        while (map[a[r]] > 1) { // 出现两次了,不满足两两相等
            map[a[l]]--; // 左指针右移时,它的元素的哈希值肯定也变小
            if (map[a[l]] == 0) {
                map.erase(a[l]); //键对应值为0,直接抹去,节省哈希表内存
            }
            l++;
        }
        curr_len = r - l + 1; // 得到当前窗口长度
        if (curr_len > max_len) {
            result.clear();
            result.emplace_back(l+1, r+1);
            // emplace比push在非平凡类型上效率更高
            max_len = curr_len; // 更新最大长度
        }
        else if (curr_len == max_len) {
            result.emplace_back(l+1, r+1);
        }
    }

    cout << result.size() << '\n';
    for (auto & i : result) {
        cout << i.first << " " << i.second << '\n';
    }
    return 0; // 蓝桥杯要求主函数return 0,我们要养成好习惯
}

// 学到的新语法技巧:
// 1、对于要一次性存入l,r,不仅可以创建结构体数组,更可以创建pair数据类型的数组
// (利用pair存2的特性,实际操作时记得补上 {} )
// 2、对于既要输出最大长度,又要输出最大长度的区间,区间这一块当存在更大的长度时,
// 我直接把数组清空,result.clear(),然后把更长的区间lr存进去,非常省事
// 3、哈希表也需要注意内存维护,当某个键的值为0,及时将其.erase(a[i]),节省内存