We will use a file-sharing system to share a very large file which consists of `m` small **chunks** with IDs from `1` to `m`.

When users join the system, the system should assign **a unique** ID to them. The unique ID should be used **once** for each user, but when a user leaves the system, the ID can be **reused** again.

Users can request a certain chunk of the file, the system should return a list of IDs of all the users who own this chunk. If the user receives a non-empty list of IDs, they receive the requested chunk successfully.

  
Implement the `FileSharing` class:

*   `FileSharing(int m)` Initializes the object with a file of `m` chunks.
*   `int join(int[] ownedChunks)`: A new user joined the system owning some chunks of the file, the system should assign an id to the user which is the **smallest positive integer** not taken by any other user. Return the assigned id.
*   `void leave(int userID)`: The user with `userID` will leave the system, you cannot take file chunks from them anymore.
*   `int[] request(int userID, int chunkID)`: The user `userID` requested the file chunk with `chunkID`. Return a list of the IDs of all users that own this chunk sorted in ascending order.

**Example:**

**Input:**
\[ "FileSharing ", "join ", "join ", "join ", "request ", "request ", "leave ", "request ", "leave ", "join "\]
\[\[4\],\[\[1,2\]\],\[\[2,3\]\],\[\[4\]\],\[1,3\],\[2,2\],\[1\],\[2,1\],\[2\],\[\[\]\]\]
**Output:**
\[null,1,2,3,\[2\],\[1,2\],null,\[\],null,1\]
**Explanation:**
FileSharing fileSharing = new FileSharing(4); // We use the system to share a file of 4 chunks.

fileSharing.join(\[1, 2\]);    // A user who has chunks \[1,2\] joined the system, assign id = 1 to them and return 1.

fileSharing.join(\[2, 3\]);    // A user who has chunks \[2,3\] joined the system, assign id = 2 to them and return 2.

fileSharing.join(\[4\]);       // A user who has chunk \[4\] joined the system, assign id = 3 to them and return 3.

fileSharing.request(1, 3);   // The user with id = 1 requested the third file chunk, as only the user with id = 2 has the file, return \[2\] . Notice that user 1 now has chunks \[1,2,3\].

fileSharing.request(2, 2);   // The user with id = 2 requested the second file chunk, users with ids \[1,2\] have this chunk, thus we return \[1,2\].

fileSharing.leave(1);        // The user with id = 1 left the system, all the file chunks with them are no longer available for other users.

fileSharing.request(2, 1);   // The user with id = 2 requested the first file chunk, no one in the system has this chunk, we return empty list \[\].

fileSharing.leave(2);        // The user with id = 2 left the system.

fileSharing.join(\[\]);        // A user who doesn't have any chunks joined the system, assign id = 1 to them and return 1. Notice that ids 1 and 2 are free and we can reuse them.

**Constraints:**

*   `1 <= m <= 105`
*   `0 <= ownedChunks.length <= min(100, m)`
*   `1 <= ownedChunks[i] <= m`
*   Values of `ownedChunks` are unique.
*   `1 <= chunkID <= m`
*   `userID` is guaranteed to be a user in the system if you **assign** the IDs **correctly**.
*   At most `104` calls will be made to `join`, `leave` and `request`.
*   Each call to `leave` will have a matching call for `join`.


파일 공유 시스템을 사용하여 '1'에서 'm'까지의 ID를 가진 'm'개의 작은 **청크**로 구성된 매우 큰 파일을 공유할 것입니다.

사용자가 시스템에 가입하면 시스템은 사용자에게 **고유한** ID를 할당해야 합니다. 고유 ID는 각 사용자에 대해 **한 번만** 사용해야 하지만, 사용자가 시스템을 떠날 경우 해당 ID를 다시 **재사용**할 수 있습니다.

사용자가 파일의 특정 청크를 요청할 수 있으며, 시스템은 이 청크를 소유한 모든 사용자의 ID 목록을 반환해야 합니다. 사용자가 비어 있지 않은 ID 목록을 받으면 요청된 청크를 성공적으로 받은 것입니다.

  
FileSharing` 클래스를 구현합니다:

* `FileSharing(int m)` `m` 청크의 파일로 객체를 초기화합니다.
* `int join(int[] ownedChunks)`: 새로운 사용자가 파일의 일부 청크를 소유하고 시스템에 가입하면, 시스템은 다른 사용자가 가져가지 않은 **가장 작은 양의 정수**인 아이디를 해당 사용자에게 할당해야 합니다. 할당된 아이디를 반환합니다.
* `void leave(int userID)`: userID`를 가진 사용자가 시스템을 떠나면 더 이상 파일 청크를 가져올 수 없습니다.
* `int[] request(int userID, int chunkID)`: userID` 사용자가 `chunkID`로 파일 청크를 요청했습니다. 이 청크를 소유한 모든 사용자의 ID 목록을 오름차순으로 정렬하여 반환합니다.

**예시:**

**입력:**
\["FileSharing ","join ","join ","join ","요청 ","요청 ","leave ","요청 ","leave ","join"\]
\[\[4\],\[\[1,2\]\],\[\[2,3\]\],\[\[4\]\],\[1,3\],\[2,2\],\[1\],\[2,1\],\[2\],\[\[\]\]\]
**출력:**
\[null,1,2,3,\[2\],\[1,2\],null,\[\],null,1\]
**설명:**
FileSharing fileSharing = new FileSharing(4); // 시스템을 사용하여 4개의 청크로 구성된 파일을 공유합니다.

fileSharing.join(\[1, 2\]); // 청크 \[1,2\]를 가진 사용자가 시스템에 가입하면, 이 사용자에게 id = 1을 할당하고 1을 반환합니다.

fileSharing.join(\[2, 3\]); // 청크 \[2,3\]을 가진 사용자가 시스템에 가입하면, 이들에게 id = 2를 할당하고 2를 반환합니다.

fileSharing.join(\[4\]); // 청크 \[4\]를 가진 사용자가 시스템에 가입하면, 이들에게 id = 3을 할당하고 3을 반환합니다.

fileSharing.request(1, 3); // id = 1을 가진 사용자가 세 번째 파일 청크를 요청했습니다, id = 2를 가진 사용자만 파일을 가지고 있으므로 \[2\] 를 반환합니다. 이제 사용자 1이 \[1,2,3\] 청크를 가지고 있음을 알 수 있습니다.

fileSharing.request(2, 2); // id = 2인 사용자가 두 번째 파일 청크를 요청했고, id가 \[1,2\]인 사용자가 이 청크를 가지고 있으므로 \[1,2\]를 반환합니다.

fileSharing.leave(1); // id가 1인 사용자가 시스템을 떠났고, 이 사용자가 가진 모든 파일 청크는 더 이상 다른 사용자가 사용할 수 없습니다.

fileSharing.request(2, 1); // id = 2인 사용자가 첫 번째 파일 청크를 요청했고, 시스템 내 아무도 이 청크를 가지고 있지 않으므로 빈 목록 \[\]을 반환합니다.

fileSharing.leave(2); // id = 2인 사용자가 시스템을 떠났습니다.

fileSharing.join(\[\]); // 청크가 없는 사용자가 시스템에 가입하면, 이 사용자에게 id = 1을 할당하고 1을 반환합니다. id 1과 2는 무료이므로 재사용할 수 있습니다.

**제약 조건:**

* `1 <= m <= 105`
* `0 <= 소유된 청크 길이 <= min(100, m)`
* `1 <= 소유된 청크[i] <= m`
* 소유된 청크`의 값은 고유합니다.
* `1 <= chunkID <= m`
* ID를 **올바르게 **할당**하면 `userID`는 시스템에서 사용자로 보장됩니다.
* 최대 `104`번의 호출이 `가입`, `탈퇴`, `요청`으로 이루어집니다.
* 'leave'에 대한 각 호출에는 'join'에 대한 일치하는 호출이 있습니다.

