The concept "by removing all commits older than the 5th commit ago" is not really coherent. However, let us presume the simplest possible case, that what you mean is: you have a main branch main, and you want the repo to consist only of commits main~5 thru main, and none of these is a merge commit.
That in itself is not really coherent either, because by removing any earlier commits, we will be changing history — and a commit's history can never be changed. So what we really want are new commits that look like commits main~5 thru main, and they should be, in effect, the only commits in the history of main.
Very well. You will be working in the local repo (which we will presume matches the remote repo, because, as you have said, you cloned it, or because you fetched it and updated your local main). As an illustration I will presume the history initially looks something like this:
* 1cebb20 (HEAD -> main) h
* 44285d5 g
* ab95e96 f
* 7896607 e
* 8d0a11a d
* 214a6c5 c
* dd7cb4c b
* 769dfff a
There may be commits before a but never mind that. The point then is that we want, in effect, the first commit with any content in the history to be just like c (because it is 5 before h; it is main~5).
That part of the task is the hardest. We need a commit that is not c (because we are going to change parentage) but whose contents look like those of c. This commit will need a parent that is itself parentless — what Git calls an "orphan". To effect this, you would first say:
% git switch --orphan temp
% git commit --allow-empty -mnewroot
% git cat-file commit main~5
tree 04a59185a0c5f4047e4fd3fa87b0c84e671b00ee
parent ...
author ...
committer ...
Okay, we have made an empty parentless commit, pointed to by temp. And Git has told us how to get at the content of the commit 5 before main. We want to take that content and pour it into a new commit whose parent is the temp branch we have just created. We do this by using the tree SHA that we were just given, like this:
% git commit-tree -p temp -m 'c' 04a59185a0c5f4047e4fd3fa87b0c84e671b00ee
b1fa80953a368fa6cc7f58b2018be19d2adf2b69
(Naturally, your numbers here will be different.)
Okay, so we have made a new commit that looks like c and has the empty parentless (orphan) temp commit as its parent. Git has also told us the SHA of this new commit — the new c. The rest is easy: we simply rebase the remainder of main onto that commit:
% git rebase --onto b1fa80953a main~5 main
Done! The history now looks like this:
* 3581893 (HEAD -> main) h
* 95227d0 g
* df95fd3 f
* f2f1edf e
* a910be2 d
* b1fa809 c
* 8f41473 (temp) newroot
We can now delete temp, as its job is done.
% git branch -D temp
And then of course, as you rightly suggest, you would need to push with force in order to update an existing remote repo; but it would be much simpler and more efficient at this point just to delete the remote repo and make a new one (and GitHub will then give you instructions for associating your local repo with this new repo and pushing main).
N). The answer is only a little more involved than the case ofN=1.