Problem:
Problem A: A White Wall

Background

とある都市に住むＡ氏の家の敷地は、真っ白な壁に囲まれている。壁に物足りなさを感じたＡ氏は、近所の子供たちを呼んで、壁を自由に塗ってもらうことにした。子供達にはそれぞれ壁の好きな区間を選んで色を塗ってもらう。 さて、壁はどのように塗られただろうか。

Problem

0〜N-1の区画で構成される以下のような円型の白い壁がある。

M人の子供たちがこの壁の開始位置aと開始位置からの長さLを指定し、反時計回りにaから(a+L) mod Nまで色を塗る(ただし、a mod Nとは、aをNで割ったときの余りを表す)。ここで、他の人が色を塗った区間と重ねて塗ることもでき、その場合は、色が塗られた1つの区間とみなす。色が塗られた区間を大きい順に出力せよ。また、その大きさの区間がいくつあるかも同時に出力せよ。

Input

入力は以下の形式で与えられる。

N M
a0 L0
a1 L1
...
aM−1 LM−1

1行目にそれぞれ壁の長さと壁に色を塗る人の数を表す2つの整数N,Mが空白区切りで与えられる。続くM行には、各人が色を塗る区間の開始位置aiと長さLiが与えられる。

Constrains

入力は以下の条件を満たす

2 ≤ N ≤ 100

1 ≤ M ≤ 50

0 ≤ ai < N

1 ≤ Li ≤ N

Output

色が塗られた区間の長さとその長さの総数を色が塗られた区間が大きい順に出力する。

Sample Input 1

5 3
0 1
2 1
3 1

Sample Output 1

2 1
1 1

Sample Input 2

4 2
0 2
1 2

Sample Output 2

3 1

Sample Input 3

10 3
2 1
4 1
9 2

Sample Output 3

2 1
1 2

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;

public static class P
{
    public static void Main()
    {
        var nm = Console.ReadLine().Split().Select(int.Parse).ToArray();
        var n = nm[0];
        var m = nm[1];
        bool[] paint = new bool[n];
        for (int i = 0; i < m; i++)
        {
            var al = Console.ReadLine().Split().Select(int.Parse).ToArray();
            for (int j = 0; j < al[1]; j++)
            {
                paint[(j + al[0]) % n] |= true;
            }
        }

        UnionFind uf = new UnionFind(n + 1);
        for (int i = 0; i < n; i++)
        {
            if (!paint[i])
                uf.TryUnite(i, n);
        }
        for (int i = 0; i < n - 1; i++)
        {
            if (paint[i] && paint[i + 1]) uf.TryUnite(i, i + 1);
        }
        if (paint[n - 1] && paint[0]) uf.TryUnite(n - 1, 0);

        Console.WriteLine(string.Join("\n", Enumerable.Range(0, n).GroupBy(x => uf.Find(x)).Where(x => x.Key != uf.Find(n)).GroupBy(x => x.Count()).OrderByDescending(x => x.Key).Select(x => $"{x.Key} {x.Count()}")));
    }
}


class UnionFind
{
    public int Size { get; private set; }
    public int GroupCount { get; private set; }
    public IEnumerable<int> AllRepresents => Parent.Where((x, y) => x == y);
    int[] Sizes;
    int[] Parent;
    public UnionFind(int count)
    {
        Size = count;
        GroupCount = count;
        Parent = new int[count];
        Sizes = new int[count];
        for (int i = 0; i < count; i++) Sizes[Parent[i] = i] = 1;
    }
    public bool TryUnite(int x, int y)
    {
        int xp = Find(x);
        int yp = Find(y);
        if (yp == xp) return false;
        if (Sizes[xp] < Sizes[yp]) { var tmp = xp; xp = yp; yp = tmp; }
        GroupCount--;
        Parent[yp] = xp;
        Sizes[xp] += Sizes[yp];
        return true;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int GetSize(int x) => Sizes[Find(x)];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int Find(int x)
    {
        while (x != Parent[x]) x = (Parent[x] = Parent[Parent[x]]);
        return x;
    }
}